Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

typescript-eslint-parser

Package Overview
Dependencies
Maintainers
2
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typescript-eslint-parser - npm Package Compare versions

Comparing version 0.1.0-alpha-1 to 0.1.0

CHANGELOG.md

461

lib/ast-converter.js
/**
* @fileoverview Converts TypeScript AST into ESTree format.
* @author Nicholas C. Zakas
* @copyright 2015 Fred K. Schott. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @copyright jQuery Foundation and other contributors, https://jquery.org/
* MIT License
*/

@@ -34,3 +15,4 @@

var ts = require("typescript"),
assign = require("object-assign");
assign = require("object-assign"),
unescape = require("lodash.unescape");

@@ -41,4 +23,3 @@ //------------------------------------------------------------------------------

var SyntaxKind = ts.SyntaxKind,
TokenClass = ts.TokenClass;
var SyntaxKind = ts.SyntaxKind;

@@ -120,2 +101,7 @@ var ASSIGNMENT_OPERATORS = [

/**
* Returns true if the given TSNode is a valid ESTree class member
* @param {TSNode} node TypeScript AST node
* @returns {boolean} is valid ESTree class member
*/
function isESTreeClassMember(node) {

@@ -125,2 +111,7 @@ return node.kind !== SyntaxKind.PropertyDeclaration && node.kind !== SyntaxKind.SemicolonClassElement;

/**
* Returns true if the given TSToken is a comma
* @param {TSToken} token the TypeScript token
* @returns {boolean} is comma
*/
function isComma(token) {

@@ -130,2 +121,7 @@ return token.kind === SyntaxKind.CommaToken;

/**
* Returns true if the given TSToken is the assignment operator
* @param {TSToken} operator the operator token
* @returns {boolean} is assignment
*/
function isAssignmentOperator(operator) {

@@ -135,2 +131,7 @@ return ASSIGNMENT_OPERATORS.indexOf(operator.kind) > -1;

/**
* Returns true if the given TSToken is a logical operator
* @param {TSToken} operator the operator token
* @returns {boolean} is a logical operator
*/
function isLogicalOperator(operator) {

@@ -140,2 +141,7 @@ return LOGICAL_OPERATORS.indexOf(operator.kind) > -1;

/**
* Returns the binary expression type of the given TSToken
* @param {TSToken} operator the operator token
* @returns {string} the binary expression type
*/
function getBinaryExpressionType(operator) {

@@ -151,2 +157,10 @@ if (isAssignmentOperator(operator)) {

/**
* Returns line and column data for the given start and end positions,
* for the given AST
* @param {Object} start start data
* @param {Object} end end data
* @param {Object} ast the AST object
* @returns {Object} the loc data
*/
function getLocFor(start, end, ast) {

@@ -168,2 +182,9 @@ var startLoc = ast.getLineAndCharacterOfPosition(start),

/**
* Returns line and column data for the given ESTreeNode or ESTreeToken,
* for the given AST
* @param {ESTreeToken|ESTreeNode} nodeOrToken the ESTreeNode or ESTreeToken
* @param {Object} ast the AST object
* @returns {Object} the loc data
*/
function getLoc(nodeOrToken, ast) {

@@ -187,2 +208,9 @@ return getLocFor(nodeOrToken.getStart(), nodeOrToken.end, ast);

/**
* Fixes the exports of the given TSNode
* @param {TSNode} node the TSNode
* @param {Object} result result
* @param {Object} ast the AST
* @returns {TSNode} the TSNode with fixed exports
*/
function fixExports(node, result, ast) {

@@ -219,2 +247,7 @@ // check for exports

/**
* Extends and formats a given error object
* @param {Object} error the error object
* @returns {Object} converted error object
*/
function convertError(error) {

@@ -232,5 +265,9 @@

/**
* Returns the type of a given ESTreeToken
* @param {ESTreeToken} token the ESTreeToken
* @returns {string} the token type
*/
function getTokenType(token) {
// Need two checks for keywords since some are also identifiers

@@ -245,14 +282,20 @@ if (token.originalKeywordKind) {

case SyntaxKind.SetKeyword:
case SyntaxKind.TypeKeyword:
case SyntaxKind.ModuleKeyword:
return "Identifier";
default:
return "Keyword"
return "Keyword";
}
}
if (token.kind >= 68 && token.kind <= 112) {
if (token.kind >= SyntaxKind.FirstKeyword && token.kind <= SyntaxKind.LastFutureReservedWord) {
if (token.kind === SyntaxKind.FalseKeyword || token.kind === SyntaxKind.TrueKeyword) {
return "Boolean";
}
return "Keyword";
}
if (token.kind >= 15 && token.kind <= 66) {
if (token.kind >= SyntaxKind.FirstPunctuation && token.kind <= SyntaxKind.LastBinaryOperator) {
return "Punctuator";

@@ -269,3 +312,12 @@ }

case SyntaxKind.JsxText:
return "JSXText";
case SyntaxKind.StringLiteral:
// A TypeScript-StringLiteral token with a TypeScript-JsxAttribute or TypeScript-JsxElement parent,
// must actually be an ESTree-JSXText token
if (token.parent && (token.parent.kind === SyntaxKind.JsxAttribute || token.parent.kind === SyntaxKind.JsxElement)) {
return "JSXText";
}
return "String";

@@ -281,6 +333,21 @@

// falls through
default:
}
// Some JSX tokens have to be determined based on their parent
if (token.parent) {
if (token.kind === SyntaxKind.Identifier && token.parent.kind === SyntaxKind.FirstNode) {
return "JSXIdentifier";
}
if (token.parent.kind >= SyntaxKind.JsxElement && token.parent.kind <= SyntaxKind.JsxAttribute) {
if (token.kind === SyntaxKind.FirstNode) {
return "JSXMemberExpression";
}
if (token.kind === SyntaxKind.Identifier) {
return "JSXIdentifier";
}
}
}

@@ -290,2 +357,8 @@ return "Identifier";

/**
* Extends and formats a given ESTreeToken, for a given AST
* @param {ESTreeToken} token the ESTreeToken
* @param {Object} ast the AST object
* @returns {ESTreeToken} the converted ESTreeToken
*/
function convertToken(token, ast) {

@@ -295,3 +368,3 @@

value = ast.text.slice(start, token.end),
newToken = {
newToken = {
type: getTokenType(token),

@@ -313,2 +386,7 @@ value: value,

/**
* Converts all tokens for the given AST
* @param {Object} ast the AST object
* @returns {ESTreeToken[]} the converted ESTreeTokens
*/
function convertTokens(ast) {

@@ -324,3 +402,2 @@ var token = ast.getFirstToken(),

}
token = ts.findNextToken(token, ast);

@@ -342,2 +419,8 @@ }

/**
* Converts a TypeScript node into an ESTree node
* @param {TSNode} node the TSNode
* @param {TSNode} parent the parent TSNode
* @returns {ESTreeNode} the converted ESTreeNode
*/
function convert(node, parent) {

@@ -356,2 +439,7 @@

/**
* Copies the result object into an ESTree node with just a type property.
* This is used only for leaf nodes that have no other properties.
* @returns {void}
*/
function simplyCopy() {

@@ -363,2 +451,7 @@ assign(result, {

/**
* Converts a TypeScript node into an ESTree node.
* @param {TSNode} child the child TSNode
* @returns {ESTreeNode} the converted ESTree node
*/
function convertChild(child) {

@@ -368,2 +461,91 @@ return convert(child, node);

/**
* Converts a child into a type annotation. This creates an intermediary
* TypeAnnotation node to match what Flow does.
* @param {TSNode} child The TypeScript AST node to convert.
* @returns {ESTreeNode} The type annotation node.
*/
function convertTypeAnnotation(child) {
var annotation = convertChild(child);
return {
type: "TypeAnnotation",
loc: annotation.loc,
range: annotation.range,
typeAnnotation: annotation
};
}
/**
* Converts a child into a class implements node. This creates an intermediary
* ClassImplements node to match what Flow does.
* @param {TSNode} child The TypeScript AST node to convert.
* @returns {ESTreeNode} The type annotation node.
*/
function convertClassImplements(child) {
var id = convertChild(child.expression);
return {
type: "ClassImplements",
loc: id.loc,
range: id.range,
id: id
};
}
/**
* For nodes that are copied directly from the TypeScript AST into
* ESTree mostly as-is. The only difference is the addition of a type
* property instead of a kind property. Recursively copies all children.
* @returns {void}
*/
function deeplyCopy() {
result.type = "TS" + SyntaxKind[node.kind];
Object.keys(node).filter(function(key) {
return !(/^(?:kind|parent|pos|end)$/.test(key));
}).forEach(function(key) {
if (key === "type") {
result.typeAnnotation = convertTypeAnnotation(node.type);
} else {
if (Array.isArray(node[key])) {
result[key] = node[key].map(convertChild);
} else if (node[key] && typeof node[key] === "object") {
result[key] = convertChild(node[key]);
} else {
result[key] = node[key];
}
}
});
}
/**
* Converts a TypeScript JSX node.tagName into an ESTree node.name
* @param {Object} tagName the tagName object from a JSX TSNode
* @param {Object} ast the AST object
* @returns {Object} the converted ESTree name object
*/
function convertTypeScriptJSXTagNameToESTreeName(tagName) {
var tagNameToken = convertToken(tagName, ast);
if (tagNameToken.type === "JSXMemberExpression") {
var isNestedMemberExpression = (node.tagName.left.kind === SyntaxKind.FirstNode);
// Convert TSNode left and right objects into ESTreeNode object
// and property objects
tagNameToken.object = convertChild(node.tagName.left);
tagNameToken.property = convertChild(node.tagName.right);
// Assign the appropriate types
tagNameToken.object.type = (isNestedMemberExpression) ? "JSXMemberExpression" : "JSXIdentifier";
tagNameToken.property.type = "JSXIdentifier";
} else {
tagNameToken.name = tagNameToken.value;
}
delete tagNameToken.value;
return tagNameToken;
}
switch (node.kind) {

@@ -374,3 +556,3 @@ case SyntaxKind.SourceFile:

body: [],
sourceType: node.externalModuleIndicator ? "module": "script"
sourceType: node.externalModuleIndicator ? "module" : "script"
});

@@ -543,2 +725,6 @@

if (node.type) {
result.returnType = convertTypeAnnotation(node.type);
}
// check for exports

@@ -555,2 +741,6 @@ result = fixExports(node, result, ast);

});
if (node.type) {
result.id.typeAnnotation = convertTypeAnnotation(node.type);
}
break;

@@ -560,6 +750,14 @@

var varStatementKind;
if (node.declarationList.flags) {
varStatementKind = (node.declarationList.flags === ts.NodeFlags.Let) ? "let" : "const";
} else {
varStatementKind = "var";
}
assign(result, {
type: "VariableDeclaration",
declarations: node.declarationList.declarations.map(convertChild),
kind: (node.declarationList.flags ? (node.declarationList.flags === ts.NodeFlags.Let ? "let" : "const") : "var")
kind: varStatementKind
});

@@ -573,6 +771,15 @@

case SyntaxKind.VariableDeclarationList:
var varDeclarationListKind;
if (node.flags) {
varDeclarationListKind = (node.flags === ts.NodeFlags.Let) ? "let" : "const";
} else {
varDeclarationListKind = "var";
}
assign(result, {
type: "VariableDeclaration",
declarations: node.declarations.map(convertChild),
kind: (node.flags ? (node.flags === ts.NodeFlags.Let ? "let" : "const") : "var")
kind: varDeclarationListKind
});

@@ -715,2 +922,6 @@ break;

if (node.type) {
method.returnType = convertTypeAnnotation(node.type);
}
if (parent.kind === SyntaxKind.ObjectLiteralExpression) {

@@ -751,3 +962,3 @@ assign(result, {

var constructorIsStatic = Boolean(node.flags & ts.NodeFlags.Static),
var constructorIsStatic = Boolean(node.flags & ts.NodeFlags.Static),
firstConstructorToken = constructorIsStatic ? ts.findNextToken(node.getFirstToken(), ast) : node.getFirstToken(),

@@ -832,2 +1043,6 @@ constructorOffset = 11,

});
if (node.type) {
result.returnType = convertTypeAnnotation(node.type);
}
break;

@@ -841,9 +1056,2 @@

case SyntaxKind.SpreadElementExpression:
assign(result, {
type: "SpreadElement",
argument: convertChild(node.expression)
});
break;
case SyntaxKind.ArrayBindingPattern:

@@ -915,2 +1123,7 @@ assign(result, {

});
if (node.type) {
result.returnType = convertTypeAnnotation(node.type);
}
break;

@@ -1015,4 +1228,12 @@

case SyntaxKind.ClassExpression:
var lastClassToken = node.heritageClauses ? node.heritageClauses[node.heritageClauses.length - 1] : node.name;
if (!lastClassToken) { // no name
var heritageClauses = node.heritageClauses || [];
var lastClassToken = heritageClauses.length ? heritageClauses[heritageClauses.length - 1] : node.name;
/**
* We need check for modifiers, and use the last one, as there
* could be multiple before the open brace
*/
if (node.modifiers && node.modifiers.length) {
var lastModifier = node.modifiers[node.modifiers.length - 1];
lastClassToken = ts.findNextToken(lastModifier, ast);
} else if (!lastClassToken) { // no name
lastClassToken = node.getFirstToken();

@@ -1022,3 +1243,12 @@ }

var openBrace = ts.findNextToken(lastClassToken, ast);
var hasExtends = (heritageClauses.length && node.heritageClauses[0].token === SyntaxKind.ExtendsKeyword),
superClass,
hasImplements = false;
if (hasExtends) {
superClass = heritageClauses.shift();
}
hasImplements = heritageClauses.length > 0;
assign(result, {

@@ -1035,3 +1265,4 @@ type: SyntaxKind[node.kind],

},
superClass: (node.heritageClauses ? convertChild(node.heritageClauses[0].types[0].expression) : null),
superClass: (superClass ? convertChild(superClass.types[0].expression) : null),
implements: hasImplements ? heritageClauses[0].types.map(convertClassImplements) : []
});

@@ -1266,3 +1497,3 @@

type: "Literal",
value: node.text,
value: unescape(node.text),
raw: ast.text.slice(result.range[0], result.range[1])

@@ -1295,3 +1526,4 @@ });

type: "Literal",
value: "true"
value: true,
raw: "true"
});

@@ -1303,3 +1535,4 @@ break;

type: "Literal",
value: "false"
value: false,
raw: "false"
});

@@ -1311,3 +1544,4 @@ break;

type: "Literal",
value: "null"
value: null,
raw: "null"
});

@@ -1321,2 +1555,121 @@ break;

// JSX
case SyntaxKind.JsxElement:
assign(result, {
type: "JSXElement",
openingElement: convertChild(node.openingElement),
closingElement: convertChild(node.closingElement),
children: node.children.map(convertChild)
});
break;
case SyntaxKind.JsxSelfClosingElement:
// Convert SyntaxKind.JsxSelfClosingElement to SyntaxKind.JsxOpeningElement,
// TypeScript does not seem to have the idea of openingElement when tag is self-closing
node.kind = SyntaxKind.JsxOpeningElement;
assign(result, {
type: "JSXElement",
openingElement: convertChild(node),
closingElement: null,
children: []
});
break;
case SyntaxKind.JsxOpeningElement:
var openingTagName = convertTypeScriptJSXTagNameToESTreeName(node.tagName);
assign(result, {
type: "JSXOpeningElement",
selfClosing: !(node.parent && node.parent.closingElement),
name: openingTagName,
attributes: node.attributes.map(convertChild)
});
break;
case SyntaxKind.JsxClosingElement:
var closingTagName = convertTypeScriptJSXTagNameToESTreeName(node.tagName);
assign(result, {
type: "JSXClosingElement",
name: closingTagName
});
break;
case SyntaxKind.JsxExpression:
var eloc = ast.getLineAndCharacterOfPosition(result.range[0] + 1);
var expression = (node.expression) ? convertChild(node.expression) : {
type: "JSXEmptyExpression",
loc: {
start: {
line: eloc.line + 1,
column: eloc.character
},
end: {
line: result.loc.end.line,
column: result.loc.end.column - 1
}
},
range: [result.range[0] + 1, result.range[1] - 1]
};
assign(result, {
type: "JSXExpressionContainer",
expression: expression
});
break;
case SyntaxKind.JsxAttribute:
var attributeName = convertToken(node.name, ast);
attributeName.name = attributeName.value;
delete attributeName.value;
assign(result, {
type: "JSXAttribute",
name: attributeName,
value: convertChild(node.initializer)
});
break;
case SyntaxKind.JsxText:
assign(result, {
type: "Literal",
value: ast.text.slice(node.pos, node.end),
raw: ast.text.slice(node.pos, node.end)
});
result.loc.start.column = node.pos;
result.range[0] = node.pos;
break;
case SyntaxKind.JsxSpreadAttribute:
assign(result, {
type: "JSXSpreadAttribute",
argument: convertChild(node.expression)
});
break;
case SyntaxKind.FirstNode:
var jsxMemberExpressionObject = convertChild(node.left);
jsxMemberExpressionObject.type = "JSXIdentifier";
delete jsxMemberExpressionObject.value;
var jsxMemberExpressionProperty = convertChild(node.right);
jsxMemberExpressionProperty.type = "JSXIdentifier";
delete jsxMemberExpressionObject.value;
assign(result, {
type: "JSXMemberExpression",
object: jsxMemberExpressionObject,
property: jsxMemberExpressionProperty
});
break;
// TypeScript specific

@@ -1328,4 +1681,3 @@

default:
console.log(node.kind);
result = null;
deeplyCopy();
}

@@ -1336,4 +1688,2 @@

var estree = convert(ast);

@@ -1345,4 +1695,9 @@

/**
* Add the comment nodes to the AST (that were parsed separately in parser.js)
* TODO: Track the progress of https://github.com/eslint/eslint/issues/6724
* regarding ESLint itself becoming responsible for attributing comment nodes
*/
if (extra.comment || extra.attachComment) {
estree.comments = [];
estree.comments = extra.comments || [];
}

@@ -1349,0 +1704,0 @@

24

lib/ast-node-types.js
/**
* @fileoverview The AST node types produced by the parser.
* @author Nicholas C. Zakas
* @copyright 2014 Nicholas C. Zakas. All rights reserved.
* @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @copyright jQuery Foundation and other contributors, https://jquery.org/
* MIT License
*/

@@ -27,0 +7,0 @@

@@ -5,24 +5,4 @@ /**

* @author Nicholas C. Zakas
* @copyright 2015 Fred K. Schott. All rights reserved.
* @copyright 2014 Nicholas C. Zakas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @copyright jQuery Foundation and other contributors, https://jquery.org/
* MIT License
*/

@@ -29,0 +9,0 @@

/**
* @fileoverview Translates tokens between Acorn format and Esprima format.
* @author Nicholas C. Zakas
* @copyright 2015 Nicholas C. Zakas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @copyright jQuery Foundation and other contributors, https://jquery.org/
* MIT License
*/

@@ -26,0 +7,0 @@ /* eslint no-underscore-dangle: 0 */

@@ -5,5 +5,5 @@ {

"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
"homepage": "https://github.com/eslint/espree",
"homepage": "https://github.com/eslint/typescript-eslint-parser",
"main": "parser.js",
"version": "0.1.0-alpha-1",
"version": "0.1.0",
"files": [

@@ -16,20 +16,13 @@ "lib",

},
"repository": {
"type": "git",
"url": "https://github.com/eslint/typescript-eslint-parser.git"
},
"repository": "eslint/typescript-eslint-parser",
"bugs": {
"url": "https://github.com/eslint/typescript-eslint-parser/issues"
},
"licenses": [
{
"type": "BSD",
"url": "http://github.com/nzakas/espree/raw/master/LICENSE"
}
],
"license": "BSD-2-Clause",
"devDependencies": {
"chai": "^1.10.0",
"dateformat": "^1.0.11",
"eslint": "^1.8.0",
"eslint-config-eslint": "^1.0.1",
"eslint": "^2.2.0",
"eslint-config-eslint": "^3.0.0",
"eslint-release": "^0.9.2",
"istanbul": "~0.2.6",

@@ -55,10 +48,15 @@ "leche": "^1.0.1",

"lint": "node Makefile.js lint",
"patch": "node Makefile.js patch",
"minor": "node Makefile.js minor",
"major": "node Makefile.js major"
"release": "eslint-release",
"ci-release": "eslint-ci-release",
"gh-release": "eslint-gh-release",
"alpharelease": "eslint-prerelease alpha",
"betarelease": "eslint-prerelease beta"
},
"dependencies": {
"object-assign": "^4.0.1",
"typescript": "^1.6.2"
"lodash.unescape": "4.0.0",
"object-assign": "^4.0.1"
},
"peerDependencies": {
"typescript": "^1.7.3"
}
}
/**
* @fileoverview Parser that converts TypeScript into ESTree format.
* Copyright 2015 Nicholas C. Zakas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @author Nicholas C. Zakas
* @copyright jQuery Foundation and other contributors, https://jquery.org/
* MIT License
*/
/*eslint no-undefined:0, no-use-before-define: 0*/
/* eslint no-undefined:0, no-use-before-define: 0 */

@@ -30,11 +12,10 @@ "use strict";

var astNodeTypes = require("./lib/ast-node-types"),
commentAttachment = require("./lib/comment-attachment"),
TokenTranslator = require("./lib/token-translator"),
acornJSX = require("acorn-jsx/inject"),
ts = require("typescript");
var lookahead,
extra,
lastToken;
var extra;
/**
* Resets the extra config object
* @returns {void}
*/
function resetExtra() {

@@ -54,4 +35,57 @@ extra = {

/**
* Converts a TypeScript comment to an Esprima comment.
* @param {boolean} block True if it's a block comment, false if not.
* @param {string} text The text of the comment.
* @param {int} start The index at which the comment starts.
* @param {int} end The index at which the comment ends.
* @param {Location} startLoc The location at which the comment starts.
* @param {Location} endLoc The location at which the comment ends.
* @returns {Object} The comment object.
* @private
*/
function convertTypeScriptCommentToEsprimaComment(block, text, start, end, startLoc, endLoc) {
var comment = {
type: block ? "Block" : "Line",
value: text
};
if (typeof start === "number") {
comment.range = [start, end];
}
if (typeof startLoc === "object") {
comment.loc = {
start: startLoc,
end: endLoc
};
}
return comment;
}
/**
* Returns line and column data for the given start and end positions,
* for the given AST
* @param {Object} start start data
* @param {Object} end end data
* @param {Object} ast the AST object
* @returns {Object} the loc data
*/
function getLocFor(start, end, ast) {
var startLoc = ast.getLineAndCharacterOfPosition(start),
endLoc = ast.getLineAndCharacterOfPosition(end);
return {
start: {
line: startLoc.line + 1,
column: startLoc.character
},
end: {
line: endLoc.line + 1,
column: endLoc.character
}
};
}
//------------------------------------------------------------------------------

@@ -61,11 +95,12 @@ // Parser

/**
* Parses the given source code to produce a valid AST
* @param {mixed} code TypeScript code
* @param {object} options configuration object for the parser
* @returns {object} the AST
*/
function parse(code, options) {
var program,
toString = String,
translator,
acornOptions = {
ecmaVersion: 5
};
toString = String;

@@ -77,3 +112,2 @@ if (typeof code !== "string" && !(code instanceof String)) {

resetExtra();
commentAttachment.reset();

@@ -91,3 +125,2 @@ if (typeof options !== "undefined") {

extra.tokens = [];
// translator = new TokenTranslator(tt, code);
}

@@ -104,7 +137,13 @@ if (typeof options.comment === "boolean" && options.comment) {

extra.comments = [];
commentAttachment.reset();
}
var FILENAME = "eslint.ts";
if (options.ecmaFeatures && typeof options.ecmaFeatures === "object") {
// pass through jsx option
extra.ecmaFeatures.jsx = options.ecmaFeatures.jsx;
}
// Even if jsx option is set in typescript compiler, filename still has to
// contain .tsx file extension
var FILENAME = (extra.ecmaFeatures.jsx) ? "eslint.tsx" : "eslint.ts";
var compilerHost = {

@@ -142,3 +181,3 @@ fileExists: function() {

var program = ts.createProgram([FILENAME], {
program = ts.createProgram([FILENAME], {
noResolve: true,

@@ -152,10 +191,32 @@ target: ts.ScriptTarget.Latest,

if (extra.attachComment || extra.comment) {
acornOptions.onComment = function() {
var comment = convertAcornCommentToEsprimaComment.apply(this, arguments);
extra.comments.push(comment);
/**
* Create a TypeScript Scanner, with skipTrivia set to false so that
* we can parse the comments
*/
var triviaScanner = ts.createScanner(ast.languageVersion, false, 0, code);
if (extra.attachComment) {
commentAttachment.addComment(comment);
var kind = triviaScanner.scan();
while (kind !== ts.SyntaxKind.EndOfFileToken) {
if (kind !== ts.SyntaxKind.SingleLineCommentTrivia && kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
kind = triviaScanner.scan();
continue;
}
};
var isBlock = (kind === ts.SyntaxKind.MultiLineCommentTrivia);
var range = {
pos: triviaScanner.getTokenPos(),
end: triviaScanner.getTextPos(),
kind: triviaScanner.getToken()
};
var comment = code.substring(range.pos, range.end);
var text = comment.replace("//", "").replace("/*", "").replace("*/", "");
var loc = getLocFor(range.pos, range.end, ast);
var esprimaComment = convertTypeScriptCommentToEsprimaComment(isBlock, text, range.pos, range.end, loc.start, loc.end);
extra.comments.push(esprimaComment);
kind = triviaScanner.scan();
}
}

@@ -166,2 +227,3 @@

var convert = require("./lib/ast-converter");
return convert(ast, extra);

@@ -180,3 +242,3 @@ }

/* istanbul ignore next */
exports.Syntax = (function () {
exports.Syntax = (function() {
var name, types = {};

@@ -183,0 +245,0 @@

# TypeScript ESLint Parser (Experimental)
An parser that converts TypeScript into an [ESTree](https://github.com/estree/estree)-compatible form so it can be used in ESLint.
A parser that converts TypeScript into an [ESTree](https://github.com/estree/estree)-compatible form so it can be used in ESLint. The goal is to allow TypeScript files to be parsed by ESLint (though not necessarily pass all ESLint rules).

@@ -25,2 +25,11 @@ **Important:** This parser is still in the very early stages and is considered experimental. There are likely a lot of bugs. You should not rely on this in a production environment yet.

## Reporting Bugs
**Do not** file bugs about ESLint rule failures. This is expected because ESLint doesn't know anything about TypeScript syntax. It's likely that many ESLint rules will have failures as a result. Longer-term, it's likely we'll need to create a custom set of ESLint rules that are TypeScript-specific.
Bugs should be filed for:
1. TypeScript syntax that fails to parse.
1. TypeScript syntax that produces an unexpected AST.
## Contributing

@@ -30,4 +39,2 @@

TypeScript ESLint Parser is licensed under a permissive BSD 2-clause license.
## Build Commands

@@ -38,10 +45,5 @@

## Development Plan
## License
* **Phase 1:** Full ES6 support, stripping out all TypeScript-specific syntax.
* **Phase 2:** Add support for attaching comments.
* **Phase 3:** Add JSX support.
* **Phase 4:** Add support for top-level TypeScript syntax.
* **Phase 5:** Add support for types.
TypeScript ESLint Parser is licensed under a permissive BSD 2-clause license.
The high-level goal is to have output that matches Espree v3.x.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc