1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | "use strict";
|
10 |
|
11 | const astNodeTypes = require("./lib/ast-node-types"),
|
12 | ts = require("typescript"),
|
13 | convert = require("./lib/ast-converter"),
|
14 | semver = require("semver");
|
15 |
|
16 | const SUPPORTED_TYPESCRIPT_VERSIONS = require("./package.json").devDependencies.typescript;
|
17 | const ACTIVE_TYPESCRIPT_VERSION = ts.version;
|
18 | const isRunningSupportedTypeScriptVersion = semver.satisfies(ACTIVE_TYPESCRIPT_VERSION, SUPPORTED_TYPESCRIPT_VERSIONS);
|
19 |
|
20 | let extra;
|
21 | let warnedAboutTSVersion = false;
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 | function resetExtra() {
|
28 | extra = {
|
29 | tokens: null,
|
30 | range: false,
|
31 | loc: false,
|
32 | comment: false,
|
33 | comments: [],
|
34 | tolerant: false,
|
35 | errors: [],
|
36 | strict: false,
|
37 | ecmaFeatures: {},
|
38 | useJSXTextNode: false,
|
39 | log: console.log
|
40 | };
|
41 | }
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | function generateAST(code, options, additionalParsingContext) {
|
55 | additionalParsingContext = additionalParsingContext || {};
|
56 |
|
57 | const toString = String;
|
58 |
|
59 | if (typeof code !== "string" && !(code instanceof String)) {
|
60 | code = toString(code);
|
61 | }
|
62 |
|
63 | resetExtra();
|
64 |
|
65 | if (typeof options !== "undefined") {
|
66 | extra.range = (typeof options.range === "boolean") && options.range;
|
67 | extra.loc = (typeof options.loc === "boolean") && options.loc;
|
68 |
|
69 | if (extra.loc && options.source !== null && options.source !== undefined) {
|
70 | extra.source = toString(options.source);
|
71 | }
|
72 |
|
73 | if (typeof options.tokens === "boolean" && options.tokens) {
|
74 | extra.tokens = [];
|
75 | }
|
76 | if (typeof options.comment === "boolean" && options.comment) {
|
77 | extra.comment = true;
|
78 | extra.comments = [];
|
79 | }
|
80 | if (typeof options.tolerant === "boolean" && options.tolerant) {
|
81 | extra.errors = [];
|
82 | }
|
83 |
|
84 | if (options.ecmaFeatures && typeof options.ecmaFeatures === "object") {
|
85 |
|
86 | extra.ecmaFeatures.jsx = options.ecmaFeatures.jsx;
|
87 | }
|
88 |
|
89 | |
90 |
|
91 |
|
92 |
|
93 | if (options.errorOnUnknownASTType) {
|
94 | extra.errorOnUnknownASTType = true;
|
95 | }
|
96 |
|
97 | if (typeof options.useJSXTextNode === "boolean" && options.useJSXTextNode) {
|
98 | extra.useJSXTextNode = true;
|
99 | }
|
100 |
|
101 | |
102 |
|
103 |
|
104 | if (typeof options.loggerFn === "function") {
|
105 | extra.log = options.loggerFn;
|
106 | } else if (options.loggerFn === false) {
|
107 | extra.log = Function.prototype;
|
108 | }
|
109 |
|
110 | |
111 |
|
112 |
|
113 |
|
114 | if (additionalParsingContext.isParseForESLint) {
|
115 | extra.parseForESLint = true;
|
116 | }
|
117 | }
|
118 |
|
119 | if (!isRunningSupportedTypeScriptVersion && !warnedAboutTSVersion) {
|
120 | const border = "=============";
|
121 | const versionWarning = [
|
122 | border,
|
123 | "WARNING: You are currently running a version of TypeScript which is not officially supported by typescript-eslint-parser.",
|
124 | "You may find that it works just fine, or you may not.",
|
125 | `SUPPORTED TYPESCRIPT VERSIONS: ${SUPPORTED_TYPESCRIPT_VERSIONS}`,
|
126 | `YOUR TYPESCRIPT VERSION: ${ACTIVE_TYPESCRIPT_VERSION}`,
|
127 | "Please only submit bug reports when using the officially supported version.",
|
128 | border
|
129 | ];
|
130 | extra.log(versionWarning.join("\n\n"));
|
131 | warnedAboutTSVersion = true;
|
132 | }
|
133 |
|
134 |
|
135 |
|
136 | const FILENAME = (extra.ecmaFeatures.jsx) ? "eslint.tsx" : "eslint.ts";
|
137 |
|
138 | const compilerHost = {
|
139 | fileExists() {
|
140 | return true;
|
141 | },
|
142 | getCanonicalFileName() {
|
143 | return FILENAME;
|
144 | },
|
145 | getCurrentDirectory() {
|
146 | return "";
|
147 | },
|
148 | getDefaultLibFileName() {
|
149 | return "lib.d.ts";
|
150 | },
|
151 |
|
152 |
|
153 | getNewLine() {
|
154 | return "\n";
|
155 | },
|
156 | getSourceFile(filename) {
|
157 | return ts.createSourceFile(filename, code, ts.ScriptTarget.Latest, true);
|
158 | },
|
159 | readFile() {
|
160 | return null;
|
161 | },
|
162 | useCaseSensitiveFileNames() {
|
163 | return true;
|
164 | },
|
165 | writeFile() {
|
166 | return null;
|
167 | }
|
168 | };
|
169 |
|
170 | const program = ts.createProgram([FILENAME], {
|
171 | noResolve: true,
|
172 | target: ts.ScriptTarget.Latest,
|
173 | jsx: extra.ecmaFeatures.jsx ? "preserve" : undefined
|
174 | }, compilerHost);
|
175 |
|
176 | const ast = program.getSourceFile(FILENAME);
|
177 |
|
178 | extra.code = code;
|
179 | return convert(ast, extra);
|
180 | }
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 | exports.version = require("./package.json").version;
|
187 |
|
188 | exports.parse = function parse(code, options) {
|
189 | return generateAST(code, options, { isParseForESLint: false });
|
190 | };
|
191 |
|
192 | exports.parseForESLint = function parseForESLint(code, options) {
|
193 | const ast = generateAST(code, options, { isParseForESLint: true });
|
194 | return { ast };
|
195 | };
|
196 |
|
197 |
|
198 |
|
199 | exports.Syntax = (function() {
|
200 | let name,
|
201 | types = {};
|
202 |
|
203 | if (typeof Object.create === "function") {
|
204 | types = Object.create(null);
|
205 | }
|
206 |
|
207 | for (name in astNodeTypes) {
|
208 | if (astNodeTypes.hasOwnProperty(name)) {
|
209 | types[name] = astNodeTypes[name];
|
210 | }
|
211 | }
|
212 |
|
213 | if (typeof Object.freeze === "function") {
|
214 | Object.freeze(types);
|
215 | }
|
216 |
|
217 | return types;
|
218 | }());
|