diff --git a/packages/typescript-eslint-parser/parser.js b/packages/typescript-eslint-parser/parser.js index dec3cd6e5039..995c1ebe4006 100644 --- a/packages/typescript-eslint-parser/parser.js +++ b/packages/typescript-eslint-parser/parser.js @@ -8,7 +8,7 @@ "use strict"; -const parse = require("typescript-estree").parse; +const parse = require("typescript-estree").parseAndGenerateServices; const astNodeTypes = require("typescript-estree").AST_NODE_TYPES; const traverser = require("eslint/lib/util/traverser"); const analyzeScope = require("./analyze-scope"); @@ -40,7 +40,7 @@ exports.parseForESLint = function parseForESLint(code, options) { options.sourceType = "script"; } - const ast = parse(code, options); + const { ast, services } = parse(code, options); ast.sourceType = options.sourceType; traverser.traverse(ast, { @@ -58,7 +58,7 @@ exports.parseForESLint = function parseForESLint(code, options) { }); const scopeManager = analyzeScope(ast, options); - return { ast, scopeManager, visitorKeys }; + return { ast, services, scopeManager, visitorKeys }; }; exports.parse = function(code, options) { diff --git a/packages/typescript-eslint-parser/tests/fixtures/services/isolated-file.src.ts b/packages/typescript-eslint-parser/tests/fixtures/services/isolated-file.src.ts new file mode 100644 index 000000000000..0f03f0973061 --- /dev/null +++ b/packages/typescript-eslint-parser/tests/fixtures/services/isolated-file.src.ts @@ -0,0 +1 @@ +const x = [3, 4, 5]; diff --git a/packages/typescript-eslint-parser/tests/fixtures/services/tsconfig.json b/packages/typescript-eslint-parser/tests/fixtures/services/tsconfig.json new file mode 100644 index 000000000000..914d17298c56 --- /dev/null +++ b/packages/typescript-eslint-parser/tests/fixtures/services/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "strict": true, + "esModuleInterop": true + } +} diff --git a/packages/typescript-eslint-parser/tests/lib/__snapshots__/services.js.snap b/packages/typescript-eslint-parser/tests/lib/__snapshots__/services.js.snap new file mode 100644 index 000000000000..d7af97b5b5dc --- /dev/null +++ b/packages/typescript-eslint-parser/tests/lib/__snapshots__/services.js.snap @@ -0,0 +1,356 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`services fixtures/isolated-file.src 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "name": "x", + "range": Array [ + 6, + 7, + ], + "type": "Identifier", + }, + "init": Object { + "elements": Array [ + Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 12, + ], + "raw": "3", + "type": "Literal", + "value": 3, + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "range": Array [ + 14, + 15, + ], + "raw": "4", + "type": "Literal", + "value": 4, + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 18, + ], + "raw": "5", + "type": "Literal", + "value": 5, + }, + ], + "loc": Object { + "end": Object { + "column": 19, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 19, + ], + "type": "ArrayExpression", + }, + "loc": Object { + "end": Object { + "column": 19, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "range": Array [ + 6, + 19, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "const", + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 20, + ], + "type": "VariableDeclaration", + }, + ], + "comments": Array [], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 21, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 5, + ], + "type": "Keyword", + "value": "const", + }, + Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "range": Array [ + 6, + 7, + ], + "type": "Identifier", + "value": "x", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "range": Array [ + 8, + 9, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 11, + ], + "type": "Punctuator", + "value": "[", + }, + Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 12, + ], + "type": "Numeric", + "value": "3", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 13, + ], + "type": "Punctuator", + "value": ",", + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "range": Array [ + 14, + 15, + ], + "type": "Numeric", + "value": "4", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 1, + }, + "start": Object { + "column": 15, + "line": 1, + }, + }, + "range": Array [ + 15, + 16, + ], + "type": "Punctuator", + "value": ",", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 18, + ], + "type": "Numeric", + "value": "5", + }, + Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 1, + }, + "start": Object { + "column": 18, + "line": 1, + }, + }, + "range": Array [ + 18, + 19, + ], + "type": "Punctuator", + "value": "]", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 20, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; diff --git a/packages/typescript-eslint-parser/tests/lib/services.js b/packages/typescript-eslint-parser/tests/lib/services.js new file mode 100644 index 000000000000..2c0e8b37bde0 --- /dev/null +++ b/packages/typescript-eslint-parser/tests/lib/services.js @@ -0,0 +1,53 @@ +/** + * @fileoverview Tests for TypeScript-specific constructs + * @author Benjamin Lichtman + * @copyright jQuery Foundation and other contributors, https://jquery.org/ + * MIT License + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const path = require("path"), + fs = require("fs"), + glob = require('glob'), + testUtils = require("../../tools/test-utils"); + +//------------------------------------------------------------------------------ +// Setup +//------------------------------------------------------------------------------ + +const FIXTURES_DIR = "./tests/fixtures/services"; +const testFiles = glob.sync(`${FIXTURES_DIR}/**/*.src.ts`); + +/** +* @param {string} filename Full path to file being tested +* @returns {Object} Config object +*/ +function createConfig(filename) { + return { + filePath: filename, + generateServices: true, + project: "./tsconfig.json", + tsconfigRootDir: path.resolve(FIXTURES_DIR) + }; +} + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +describe("services", () => { + testFiles.forEach(filename => { + const code = fs.readFileSync(filename, 'utf8'); + const config = createConfig(filename); + test(testUtils.formatSnapshotName(filename, FIXTURES_DIR, '.ts'), testUtils.createSnapshotTestBlock(code, config)); + test(`${testUtils.formatSnapshotName(filename, FIXTURES_DIR, '.ts')} services`, () => { + testUtils.testServices(code, config); + }); + }); + +}); diff --git a/packages/typescript-eslint-parser/tools/test-utils.js b/packages/typescript-eslint-parser/tools/test-utils.js index 11d6fd38008e..2f84b0938aa3 100644 --- a/packages/typescript-eslint-parser/tools/test-utils.js +++ b/packages/typescript-eslint-parser/tools/test-utils.js @@ -20,6 +20,16 @@ const parser = require("../parser"); // Private //-------------------------------------------------------------------------------- +const defaultConfig = { + loc: true, + range: true, + raw: true, + tokens: true, + comment: true, + errorOnUnknownASTType: true, + sourceType: "module" +}; + /** * Returns a raw copy of the given AST * @param {Object} ast the AST object @@ -42,15 +52,6 @@ function getRaw(ast) { * @returns {Function} callback for Jest test() block */ function createSnapshotTestBlock(code, config = {}) { - const defaultConfig = { - loc: true, - range: true, - raw: true, - tokens: true, - comment: true, - errorOnUnknownASTType: true, - sourceType: "module" - }; config = Object.assign({}, defaultConfig, config); /** @@ -79,6 +80,21 @@ function createSnapshotTestBlock(code, config = {}) { } +/** + * @param {string} code The code being parsed + * @param {Object} config The configuration object for the parser + * @returns {void} + */ +function testServices(code, config = {}) { + config = Object.assign({}, defaultConfig, config); + + const services = parser.parseForESLint(code, config).services; + expect(services).toBeDefined(); + expect(services.program).toBeDefined(); + expect(services.esTreeNodeToTSNodeMap).toBeDefined(); + expect(services.tsNodeToESTreeNodeMap).toBeDefined(); +} + function formatSnapshotName(filename, fixturesDir, fileExtension = '.js') { return `fixtures/${filename.replace(fixturesDir + '/', '').replace(fileExtension, '')}`; } @@ -86,5 +102,6 @@ function formatSnapshotName(filename, fixturesDir, fileExtension = '.js') { module.exports = { getRaw, createSnapshotTestBlock, + testServices, formatSnapshotName };
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: