diff --git a/.gitignore b/.gitignore
index c027f5873c87a..05f981a0acefd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,5 @@
node_modules/
built/*
-tests/cases/*.js
-tests/cases/*/*.js
-tests/cases/*/*/*.js
-tests/cases/*/*/*/*.js
-tests/cases/*/*/*/*/*.js
-tests/cases/*.js.map
-tests/cases/*/*.js.map
-tests/cases/*/*/*.js.map
-tests/cases/*/*/*/*.js.map
-tests/cases/*/*/*/*/*.js.map
tests/cases/rwc/*
tests/cases/test262/*
tests/cases/perf/*
diff --git a/AUTHORS.md b/AUTHORS.md
index 0ade4c3122171..486a15bf47f6d 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -8,6 +8,7 @@ TypeScript is authored by:
* Basarat Ali Syed
* Ben Duffield
* Bill Ticehurst
+* Brett Mayen
* Bryan Forbes
* Caitlin Potter
* Chris Bubernak
@@ -17,11 +18,14 @@ TypeScript is authored by:
* Dan Quirk
* Daniel Rosenwasser
* David Li
-* Dick van den Brink
-* Dirk Bumer
+* Denis Nedelyaev
+* Dick van den Brink
+* Dirk Bäumer
+* Eyas Sharaiha
* Frank Wallis
* Gabriel Isenberg
* Gilad Peleg
+* Graeme Wicksted
* Guillaume Salles
* Harald Niesche
* Ingvar Stepanyan
@@ -31,30 +35,39 @@ TypeScript is authored by:
* Jason Ramsay
* Jed Mao
* Johannes Rieken
+* John Vilk
* Jonathan Bond-Caron
* Jonathan Park
* Jonathan Turner
* Josh Kalderimis
+* Julian Williams
* Kagami Sascha Rosylight
* Keith Mashinter
+* Ken Howard
* Kenji Imamula
* Lorant Pinter
+* Martin Všetička
* Masahiro Wakame
* Max Deepfield
* Micah Zoltu
* Mohamed Hegazy
+* Nathan Shively-Sanders
* Oleg Mihailik
* Oleksandr Chekhovskyi
* Paul van Brenk
* Pedro Maltez
* Philip Bulley
* piloopin
+* @progre
+* Punya Biswal
* Ron Buckton
* Ryan Cavanaugh
+* Ryohei Ikegami
+* Sébastien Arod
* Sheetal Nandi
* Shengping Zhong
* Shyyko Serhiy
-* Simon Hrlimann
+* Simon Hürlimann
* Solal Pirelli
* Stan Thomas
* Steve Lucco
@@ -63,8 +76,10 @@ TypeScript is authored by:
* togru
* Tomas Grubliauskas
* TruongSinh Tran-Nguyen
+* Viliv Vane
* Vladimir Matveev
* Wesley Wigham
+* York Yao
* Yui Tanglertsampan
* Zev Spitz
-* Zhengbo Li
\ No newline at end of file
+* Zhengbo Li
diff --git a/Jakefile.js b/Jakefile.js
index 5dfbcc26d74cb..6243ce8ff97ea 100644
--- a/Jakefile.js
+++ b/Jakefile.js
@@ -40,6 +40,7 @@ var compilerSources = [
"utilities.ts",
"binder.ts",
"checker.ts",
+ "sourcemap.ts",
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
@@ -59,6 +60,7 @@ var servicesSources = [
"utilities.ts",
"binder.ts",
"checker.ts",
+ "sourcemap.ts",
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
@@ -106,6 +108,16 @@ var serverCoreSources = [
return path.join(serverDirectory, f);
});
+var scriptSources = [
+ "tslint/booleanTriviaRule.ts",
+ "tslint/nextLineRule.ts",
+ "tslint/noNullRule.ts",
+ "tslint/preferConstRule.ts",
+ "tslint/typeOperatorSpacingRule.ts"
+].map(function (f) {
+ return path.join(scriptsDirectory, f);
+});
+
var serverSources = serverCoreSources.concat(servicesSources);
var languageServiceLibrarySources = [
@@ -365,7 +377,6 @@ file(builtGeneratedDiagnosticMessagesJSON,[generatedDiagnosticMessagesJSON], fun
desc("Generates a diagnostic file in TypeScript based on an input JSON file");
task("generate-diagnostics", [diagnosticInfoMapTs]);
-
// Publish nightly
var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts");
@@ -466,7 +477,7 @@ compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].conca
var nodeDefinitionsFileContents = definitionFileContents + "\r\nexport = ts;";
fs.writeFileSync(nodeDefinitionsFile, nodeDefinitionsFileContents);
- // Node package definition file to be distributed without the package. Created by replacing
+ // Node package definition file to be distributed without the package. Created by replacing
// 'ts' namespace with '"typescript"' as a module.
var nodeStandaloneDefinitionsFileContents = definitionFileContents.replace(/declare (namespace|module) ts/g, 'declare module "typescript"');
fs.writeFileSync(nodeStandaloneDefinitionsFile, nodeStandaloneDefinitionsFileContents);
@@ -875,7 +886,7 @@ var tslintRulesOutFiles = tslintRules.map(function(p) {
desc("Compiles tslint rules to js");
task("build-rules", tslintRulesOutFiles);
tslintRulesFiles.forEach(function(ruleFile, i) {
- compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
+ compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
});
function getLinterOptions() {
@@ -909,7 +920,8 @@ function lintFileAsync(options, path, cb) {
var lintTargets = compilerSources
.concat(harnessCoreSources)
- .concat(serverCoreSources);
+ .concat(serverCoreSources)
+ .concat(scriptSources);
desc("Runs tslint on the compiler sources");
task("lint", ["build-rules"], function() {
@@ -937,7 +949,7 @@ function lintWatchFile(filename) {
if (event !== "change") {
return;
}
-
+
if (!lintSemaphores[filename]) {
lintSemaphores[filename] = true;
lintFileAsync(getLinterOptions(), filename, function(err, result) {
diff --git a/README.md b/README.md
index e27e7a99fa7b1..13e1f3e4786c6 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
[](https://travis-ci.org/Microsoft/TypeScript)
-[](http://badge.fury.io/js/typescript)
-[](https://npmjs.org/package/typescript)
+[](https://www.npmjs.com/package/typescript)
+[](https://www.npmjs.com/package/typescript)
# TypeScript
diff --git a/lib/tsc.js b/lib/tsc.js
index bbbcedf0f47a9..87a413af7294e 100644
--- a/lib/tsc.js
+++ b/lib/tsc.js
@@ -665,7 +665,7 @@ var ts;
}
ts.fileExtensionIs = fileExtensionIs;
ts.supportedExtensions = [".ts", ".tsx", ".d.ts"];
- ts.moduleFileExtensions = ts.supportedExtensions;
+ ts.supportedJsExtensions = ts.supportedExtensions.concat(".js", ".jsx");
function isSupportedSourceFileName(fileName) {
if (!fileName) {
return false;
@@ -716,17 +716,16 @@ var ts;
}
function Signature(checker) {
}
+ function Node(kind, pos, end) {
+ this.kind = kind;
+ this.pos = pos;
+ this.end = end;
+ this.flags = 0;
+ this.parent = undefined;
+ }
ts.objectAllocator = {
- getNodeConstructor: function (kind) {
- function Node(pos, end) {
- this.pos = pos;
- this.end = end;
- this.flags = 0;
- this.parent = undefined;
- }
- Node.prototype = { kind: kind };
- return Node;
- },
+ getNodeConstructor: function () { return Node; },
+ getSourceFileConstructor: function () { return Node; },
getSymbolConstructor: function () { return Symbol; },
getTypeConstructor: function () { return Type; },
getSignatureConstructor: function () { return Signature; }
@@ -1003,7 +1002,16 @@ var ts;
if (writeByteOrderMark) {
data = "\uFEFF" + data;
}
- _fs.writeFileSync(fileName, data, "utf8");
+ var fd;
+ try {
+ fd = _fs.openSync(fileName, "w");
+ _fs.writeSync(fd, data, undefined, "utf8");
+ }
+ finally {
+ if (fd !== undefined) {
+ _fs.closeSync(fd);
+ }
+ }
}
function getCanonicalPath(path) {
return useCaseSensitiveFileNames ? path.toLowerCase() : path;
@@ -1688,6 +1696,7 @@ var ts;
Disallow_inconsistently_cased_references_to_the_same_file: { code: 6078, category: ts.DiagnosticCategory.Message, key: "Disallow_inconsistently_cased_references_to_the_same_file_6078", message: "Disallow inconsistently-cased references to the same file." },
Specify_JSX_code_generation_Colon_preserve_or_react: { code: 6080, category: ts.DiagnosticCategory.Message, key: "Specify_JSX_code_generation_Colon_preserve_or_react_6080", message: "Specify JSX code generation: 'preserve' or 'react'" },
Argument_for_jsx_must_be_preserve_or_react: { code: 6081, category: ts.DiagnosticCategory.Message, key: "Argument_for_jsx_must_be_preserve_or_react_6081", message: "Argument for '--jsx' must be 'preserve' or 'react'." },
+ Only_amd_and_system_modules_are_supported_alongside_0: { code: 6082, category: ts.DiagnosticCategory.Error, key: "Only_amd_and_system_modules_are_supported_alongside_0_6082", message: "Only 'amd' and 'system' modules are supported alongside --{0}." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." },
@@ -2148,7 +2157,7 @@ var ts;
function getCommentRanges(text, pos, trailing) {
var result;
var collecting = trailing || pos === 0;
- while (true) {
+ while (pos < text.length) {
var ch = text.charCodeAt(pos);
switch (ch) {
case 13:
@@ -2217,6 +2226,7 @@ var ts;
}
return result;
}
+ return result;
}
function getLeadingCommentRanges(text, pos) {
return getCommentRanges(text, pos, false);
@@ -2312,7 +2322,7 @@ var ts;
error(ts.Diagnostics.Digit_expected);
}
}
- return +(text.substring(start, end));
+ return "" + +(text.substring(start, end));
}
function scanOctalDigits() {
var start = pos;
@@ -2704,7 +2714,7 @@ var ts;
return pos++, token = 36;
case 46:
if (isDigit(text.charCodeAt(pos + 1))) {
- tokenValue = "" + scanNumber();
+ tokenValue = scanNumber();
return token = 8;
}
if (text.charCodeAt(pos + 1) === 46 && text.charCodeAt(pos + 2) === 46) {
@@ -2801,7 +2811,7 @@ var ts;
case 55:
case 56:
case 57:
- tokenValue = "" + scanNumber();
+ tokenValue = scanNumber();
return token = 8;
case 58:
return pos++, token = 54;
@@ -3094,3102 +3104,2150 @@ var ts;
})(ts || (ts = {}));
var ts;
(function (ts) {
- ts.bindTime = 0;
- function or(state1, state2) {
- return (state1 | state2) & 2
- ? 2
- : (state1 & state2) & 8
- ? 8
- : 4;
- }
- function getModuleInstanceState(node) {
- if (node.kind === 215 || node.kind === 216) {
- return 0;
+ function getDeclarationOfKind(symbol, kind) {
+ var declarations = symbol.declarations;
+ if (declarations) {
+ for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
+ var declaration = declarations_1[_i];
+ if (declaration.kind === kind) {
+ return declaration;
+ }
+ }
}
- else if (ts.isConstEnumDeclaration(node)) {
- return 2;
+ return undefined;
+ }
+ ts.getDeclarationOfKind = getDeclarationOfKind;
+ var stringWriters = [];
+ function getSingleLineStringWriter() {
+ if (stringWriters.length === 0) {
+ var str = "";
+ var writeText = function (text) { return str += text; };
+ return {
+ string: function () { return str; },
+ writeKeyword: writeText,
+ writeOperator: writeText,
+ writePunctuation: writeText,
+ writeSpace: writeText,
+ writeStringLiteral: writeText,
+ writeParameter: writeText,
+ writeSymbol: writeText,
+ writeLine: function () { return str += " "; },
+ increaseIndent: function () { },
+ decreaseIndent: function () { },
+ clear: function () { return str = ""; },
+ trackSymbol: function () { },
+ reportInaccessibleThisError: function () { }
+ };
}
- else if ((node.kind === 222 || node.kind === 221) && !(node.flags & 2)) {
- return 0;
+ return stringWriters.pop();
+ }
+ ts.getSingleLineStringWriter = getSingleLineStringWriter;
+ function releaseStringWriter(writer) {
+ writer.clear();
+ stringWriters.push(writer);
+ }
+ ts.releaseStringWriter = releaseStringWriter;
+ function getFullWidth(node) {
+ return node.end - node.pos;
+ }
+ ts.getFullWidth = getFullWidth;
+ function arrayIsEqualTo(array1, array2, equaler) {
+ if (!array1 || !array2) {
+ return array1 === array2;
}
- else if (node.kind === 219) {
- var state = 0;
- ts.forEachChild(node, function (n) {
- switch (getModuleInstanceState(n)) {
- case 0:
- return false;
- case 2:
- state = 2;
- return false;
- case 1:
- state = 1;
- return true;
- }
- });
- return state;
+ if (array1.length !== array2.length) {
+ return false;
}
- else if (node.kind === 218) {
- return getModuleInstanceState(node.body);
+ for (var i = 0; i < array1.length; ++i) {
+ var equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
+ if (!equals) {
+ return false;
+ }
}
- else {
- return 1;
+ return true;
+ }
+ ts.arrayIsEqualTo = arrayIsEqualTo;
+ function hasResolvedModule(sourceFile, moduleNameText) {
+ return sourceFile.resolvedModules && ts.hasProperty(sourceFile.resolvedModules, moduleNameText);
+ }
+ ts.hasResolvedModule = hasResolvedModule;
+ function getResolvedModule(sourceFile, moduleNameText) {
+ return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
+ }
+ ts.getResolvedModule = getResolvedModule;
+ function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
+ if (!sourceFile.resolvedModules) {
+ sourceFile.resolvedModules = {};
}
+ sourceFile.resolvedModules[moduleNameText] = resolvedModule;
}
- ts.getModuleInstanceState = getModuleInstanceState;
- var binder = createBinder();
- function bindSourceFile(file, options) {
- var start = new Date().getTime();
- binder(file, options);
- ts.bindTime += new Date().getTime() - start;
+ ts.setResolvedModule = setResolvedModule;
+ function containsParseError(node) {
+ aggregateChildData(node);
+ return (node.parserContextFlags & 64) !== 0;
}
- ts.bindSourceFile = bindSourceFile;
- function createBinder() {
- var file;
- var options;
- var parent;
- var container;
- var blockScopeContainer;
- var lastContainer;
- var seenThisKeyword;
- var hasExplicitReturn;
- var currentReachabilityState;
- var labelStack;
- var labelIndexMap;
- var implicitLabels;
- var inStrictMode;
- var symbolCount = 0;
- var Symbol;
- var classifiableNames;
- function bindSourceFile(f, opts) {
- file = f;
- options = opts;
- inStrictMode = !!file.externalModuleIndicator;
- classifiableNames = {};
- Symbol = ts.objectAllocator.getSymbolConstructor();
- if (!file.locals) {
- bind(file);
- file.symbolCount = symbolCount;
- file.classifiableNames = classifiableNames;
+ ts.containsParseError = containsParseError;
+ function aggregateChildData(node) {
+ if (!(node.parserContextFlags & 128)) {
+ var thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & 16) !== 0) ||
+ ts.forEachChild(node, containsParseError);
+ if (thisNodeOrAnySubNodesHasError) {
+ node.parserContextFlags |= 64;
}
- parent = undefined;
- container = undefined;
- blockScopeContainer = undefined;
- lastContainer = undefined;
- seenThisKeyword = false;
- hasExplicitReturn = false;
- labelStack = undefined;
- labelIndexMap = undefined;
- implicitLabels = undefined;
+ node.parserContextFlags |= 128;
}
- return bindSourceFile;
- function createSymbol(flags, name) {
- symbolCount++;
- return new Symbol(flags, name);
+ }
+ function getSourceFileOfNode(node) {
+ while (node && node.kind !== 248) {
+ node = node.parent;
}
- function addDeclarationToSymbol(symbol, node, symbolFlags) {
- symbol.flags |= symbolFlags;
- node.symbol = symbol;
- if (!symbol.declarations) {
- symbol.declarations = [];
- }
- symbol.declarations.push(node);
- if (symbolFlags & 1952 && !symbol.exports) {
- symbol.exports = {};
- }
- if (symbolFlags & 6240 && !symbol.members) {
- symbol.members = {};
- }
- if (symbolFlags & 107455 && !symbol.valueDeclaration) {
- symbol.valueDeclaration = node;
- }
+ return node;
+ }
+ ts.getSourceFileOfNode = getSourceFileOfNode;
+ function getStartPositionOfLine(line, sourceFile) {
+ ts.Debug.assert(line >= 0);
+ return ts.getLineStarts(sourceFile)[line];
+ }
+ ts.getStartPositionOfLine = getStartPositionOfLine;
+ function nodePosToString(node) {
+ var file = getSourceFileOfNode(node);
+ var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
+ return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
+ }
+ ts.nodePosToString = nodePosToString;
+ function getStartPosOfNode(node) {
+ return node.pos;
+ }
+ ts.getStartPosOfNode = getStartPosOfNode;
+ function nodeIsMissing(node) {
+ if (!node) {
+ return true;
}
- function getDeclarationName(node) {
- if (node.name) {
- if (node.kind === 218 && node.name.kind === 9) {
- return "\"" + node.name.text + "\"";
- }
- if (node.name.kind === 136) {
- var nameExpression = node.name.expression;
- ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
- return ts.getPropertyNameForKnownSymbolName(nameExpression.name.text);
- }
- return node.name.text;
- }
- switch (node.kind) {
- case 144:
- return "__constructor";
- case 152:
- case 147:
- return "__call";
- case 153:
- case 148:
- return "__new";
- case 149:
- return "__index";
- case 228:
- return "__export";
- case 227:
- return node.isExportEquals ? "export=" : "default";
- case 213:
- case 214:
- return node.flags & 512 ? "default" : undefined;
- }
+ return node.pos === node.end && node.pos >= 0 && node.kind !== 1;
+ }
+ ts.nodeIsMissing = nodeIsMissing;
+ function nodeIsPresent(node) {
+ return !nodeIsMissing(node);
+ }
+ ts.nodeIsPresent = nodeIsPresent;
+ function getTokenPosOfNode(node, sourceFile) {
+ if (nodeIsMissing(node)) {
+ return node.pos;
}
- function getDisplayName(node) {
- return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node);
- }
- function declareSymbol(symbolTable, parent, node, includes, excludes) {
- ts.Debug.assert(!ts.hasDynamicName(node));
- var isDefaultExport = node.flags & 512;
- var name = isDefaultExport && parent ? "default" : getDeclarationName(node);
- var symbol;
- if (name !== undefined) {
- symbol = ts.hasProperty(symbolTable, name)
- ? symbolTable[name]
- : (symbolTable[name] = createSymbol(0, name));
- if (name && (includes & 788448)) {
- classifiableNames[name] = name;
- }
- if (symbol.flags & excludes) {
- if (node.name) {
- node.name.parent = node;
- }
- var message = symbol.flags & 2
- ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
- : ts.Diagnostics.Duplicate_identifier_0;
- ts.forEach(symbol.declarations, function (declaration) {
- if (declaration.flags & 512) {
- message = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
- }
- });
- ts.forEach(symbol.declarations, function (declaration) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
- });
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
- symbol = createSymbol(0, name);
- }
- }
- else {
- symbol = createSymbol(0, "__missing");
- }
- addDeclarationToSymbol(symbol, node, includes);
- symbol.parent = parent;
- return symbol;
+ return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
+ }
+ ts.getTokenPosOfNode = getTokenPosOfNode;
+ function getNonDecoratorTokenPosOfNode(node, sourceFile) {
+ if (nodeIsMissing(node) || !node.decorators) {
+ return getTokenPosOfNode(node, sourceFile);
}
- function declareModuleMember(node, symbolFlags, symbolExcludes) {
- var hasExportModifier = ts.getCombinedNodeFlags(node) & 2;
- if (symbolFlags & 8388608) {
- if (node.kind === 230 || (node.kind === 221 && hasExportModifier)) {
- return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- }
- else {
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- }
- else {
- if (hasExportModifier || container.flags & 131072) {
- var exportKind = (symbolFlags & 107455 ? 1048576 : 0) |
- (symbolFlags & 793056 ? 2097152 : 0) |
- (symbolFlags & 1536 ? 4194304 : 0);
- var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
- local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- node.localSymbol = local;
- return local;
- }
- else {
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- }
+ return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
+ }
+ ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
+ function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
+ if (includeTrivia === void 0) { includeTrivia = false; }
+ if (nodeIsMissing(node)) {
+ return "";
}
- function bindChildren(node) {
- var saveParent = parent;
- var saveContainer = container;
- var savedBlockScopeContainer = blockScopeContainer;
- parent = node;
- var containerFlags = getContainerFlags(node);
- if (containerFlags & 1) {
- container = blockScopeContainer = node;
- if (containerFlags & 4) {
- container.locals = {};
- }
- addToContainerChain(container);
- }
- else if (containerFlags & 2) {
- blockScopeContainer = node;
- blockScopeContainer.locals = undefined;
- }
- var savedReachabilityState;
- var savedLabelStack;
- var savedLabels;
- var savedImplicitLabels;
- var savedHasExplicitReturn;
- var kind = node.kind;
- var flags = node.flags;
- flags &= ~1572864;
- if (kind === 215) {
- seenThisKeyword = false;
- }
- var saveState = kind === 248 || kind === 219 || ts.isFunctionLikeKind(kind);
- if (saveState) {
- savedReachabilityState = currentReachabilityState;
- savedLabelStack = labelStack;
- savedLabels = labelIndexMap;
- savedImplicitLabels = implicitLabels;
- savedHasExplicitReturn = hasExplicitReturn;
- currentReachabilityState = 2;
- hasExplicitReturn = false;
- labelStack = labelIndexMap = implicitLabels = undefined;
- }
- bindReachableStatement(node);
- if (currentReachabilityState === 2 && ts.isFunctionLikeKind(kind) && ts.nodeIsPresent(node.body)) {
- flags |= 524288;
- if (hasExplicitReturn) {
- flags |= 1048576;
- }
- }
- if (kind === 215) {
- flags = seenThisKeyword ? flags | 262144 : flags & ~262144;
- }
- node.flags = flags;
- if (saveState) {
- hasExplicitReturn = savedHasExplicitReturn;
- currentReachabilityState = savedReachabilityState;
- labelStack = savedLabelStack;
- labelIndexMap = savedLabels;
- implicitLabels = savedImplicitLabels;
- }
- container = saveContainer;
- parent = saveParent;
- blockScopeContainer = savedBlockScopeContainer;
+ var text = sourceFile.text;
+ return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end);
+ }
+ ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
+ function getTextOfNodeFromSourceText(sourceText, node) {
+ if (nodeIsMissing(node)) {
+ return "";
}
- function bindReachableStatement(node) {
- if (checkUnreachable(node)) {
- ts.forEachChild(node, bind);
- return;
+ return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
+ }
+ ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
+ function getTextOfNode(node, includeTrivia) {
+ if (includeTrivia === void 0) { includeTrivia = false; }
+ return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
+ }
+ ts.getTextOfNode = getTextOfNode;
+ function escapeIdentifier(identifier) {
+ return identifier.length >= 2 && identifier.charCodeAt(0) === 95 && identifier.charCodeAt(1) === 95 ? "_" + identifier : identifier;
+ }
+ ts.escapeIdentifier = escapeIdentifier;
+ function unescapeIdentifier(identifier) {
+ return identifier.length >= 3 && identifier.charCodeAt(0) === 95 && identifier.charCodeAt(1) === 95 && identifier.charCodeAt(2) === 95 ? identifier.substr(1) : identifier;
+ }
+ ts.unescapeIdentifier = unescapeIdentifier;
+ function makeIdentifierFromModuleName(moduleName) {
+ return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
+ }
+ ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
+ function isBlockOrCatchScoped(declaration) {
+ return (getCombinedNodeFlags(declaration) & 24576) !== 0 ||
+ isCatchClauseVariableDeclaration(declaration);
+ }
+ ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
+ function getEnclosingBlockScopeContainer(node) {
+ var current = node.parent;
+ while (current) {
+ if (isFunctionLike(current)) {
+ return current;
}
- switch (node.kind) {
- case 198:
- bindWhileStatement(node);
- break;
- case 197:
- bindDoStatement(node);
- break;
+ switch (current.kind) {
+ case 248:
+ case 220:
+ case 244:
+ case 218:
case 199:
- bindForStatement(node);
- break;
case 200:
case 201:
- bindForInOrForOfStatement(node);
- break;
- case 196:
- bindIfStatement(node);
- break;
- case 204:
- case 208:
- bindReturnOrThrow(node);
- break;
- case 203:
- case 202:
- bindBreakOrContinueStatement(node);
- break;
- case 209:
- bindTryStatement(node);
- break;
- case 206:
- bindSwitchStatement(node);
- break;
- case 220:
- bindCaseBlock(node);
- break;
- case 207:
- bindLabeledStatement(node);
- break;
- default:
- ts.forEachChild(node, bind);
- break;
+ return current;
+ case 192:
+ if (!isFunctionLike(current.parent)) {
+ return current;
+ }
}
+ current = current.parent;
}
- function bindWhileStatement(n) {
- var preWhileState = n.expression.kind === 84 ? 4 : currentReachabilityState;
- var postWhileState = n.expression.kind === 99 ? 4 : currentReachabilityState;
- bind(n.expression);
- currentReachabilityState = preWhileState;
- var postWhileLabel = pushImplicitLabel();
- bind(n.statement);
- popImplicitLabel(postWhileLabel, postWhileState);
- }
- function bindDoStatement(n) {
- var preDoState = currentReachabilityState;
- var postDoLabel = pushImplicitLabel();
- bind(n.statement);
- var postDoState = n.expression.kind === 99 ? 4 : preDoState;
- popImplicitLabel(postDoLabel, postDoState);
- bind(n.expression);
- }
- function bindForStatement(n) {
- var preForState = currentReachabilityState;
- var postForLabel = pushImplicitLabel();
- bind(n.initializer);
- bind(n.condition);
- bind(n.incrementor);
- bind(n.statement);
- var isInfiniteLoop = (!n.condition || n.condition.kind === 99);
- var postForState = isInfiniteLoop ? 4 : preForState;
- popImplicitLabel(postForLabel, postForState);
- }
- function bindForInOrForOfStatement(n) {
- var preStatementState = currentReachabilityState;
- var postStatementLabel = pushImplicitLabel();
- bind(n.initializer);
- bind(n.expression);
- bind(n.statement);
- popImplicitLabel(postStatementLabel, preStatementState);
- }
- function bindIfStatement(n) {
- var ifTrueState = n.expression.kind === 84 ? 4 : currentReachabilityState;
- var ifFalseState = n.expression.kind === 99 ? 4 : currentReachabilityState;
- currentReachabilityState = ifTrueState;
- bind(n.expression);
- bind(n.thenStatement);
- if (n.elseStatement) {
- var preElseState = currentReachabilityState;
- currentReachabilityState = ifFalseState;
- bind(n.elseStatement);
- currentReachabilityState = or(currentReachabilityState, preElseState);
- }
- else {
- currentReachabilityState = or(currentReachabilityState, ifFalseState);
- }
- }
- function bindReturnOrThrow(n) {
- bind(n.expression);
- if (n.kind === 204) {
- hasExplicitReturn = true;
- }
- currentReachabilityState = 4;
- }
- function bindBreakOrContinueStatement(n) {
- bind(n.label);
- var isValidJump = jumpToLabel(n.label, n.kind === 203 ? currentReachabilityState : 4);
- if (isValidJump) {
- currentReachabilityState = 4;
- }
+ }
+ ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
+ function isCatchClauseVariableDeclaration(declaration) {
+ return declaration &&
+ declaration.kind === 211 &&
+ declaration.parent &&
+ declaration.parent.kind === 244;
+ }
+ ts.isCatchClauseVariableDeclaration = isCatchClauseVariableDeclaration;
+ function declarationNameToString(name) {
+ return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
+ }
+ ts.declarationNameToString = declarationNameToString;
+ function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
+ var sourceFile = getSourceFileOfNode(node);
+ var span = getErrorSpanForNode(sourceFile, node);
+ return ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
+ }
+ ts.createDiagnosticForNode = createDiagnosticForNode;
+ function createDiagnosticForNodeFromMessageChain(node, messageChain) {
+ var sourceFile = getSourceFileOfNode(node);
+ var span = getErrorSpanForNode(sourceFile, node);
+ return {
+ file: sourceFile,
+ start: span.start,
+ length: span.length,
+ code: messageChain.code,
+ category: messageChain.category,
+ messageText: messageChain.next ? messageChain : messageChain.messageText
+ };
+ }
+ ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain;
+ function getSpanOfTokenAtPosition(sourceFile, pos) {
+ var scanner = ts.createScanner(sourceFile.languageVersion, true, sourceFile.languageVariant, sourceFile.text, undefined, pos);
+ scanner.scan();
+ var start = scanner.getTokenPos();
+ return ts.createTextSpanFromBounds(start, scanner.getTextPos());
+ }
+ ts.getSpanOfTokenAtPosition = getSpanOfTokenAtPosition;
+ function getErrorSpanForNode(sourceFile, node) {
+ var errorNode = node;
+ switch (node.kind) {
+ case 248:
+ var pos_1 = ts.skipTrivia(sourceFile.text, 0, false);
+ if (pos_1 === sourceFile.text.length) {
+ return ts.createTextSpan(0, 0);
+ }
+ return getSpanOfTokenAtPosition(sourceFile, pos_1);
+ case 211:
+ case 163:
+ case 214:
+ case 186:
+ case 215:
+ case 218:
+ case 217:
+ case 247:
+ case 213:
+ case 173:
+ errorNode = node.name;
+ break;
}
- function bindTryStatement(n) {
- var preTryState = currentReachabilityState;
- bind(n.tryBlock);
- var postTryState = currentReachabilityState;
- currentReachabilityState = preTryState;
- bind(n.catchClause);
- var postCatchState = currentReachabilityState;
- currentReachabilityState = preTryState;
- bind(n.finallyBlock);
- currentReachabilityState = or(postTryState, postCatchState);
+ if (errorNode === undefined) {
+ return getSpanOfTokenAtPosition(sourceFile, node.pos);
}
- function bindSwitchStatement(n) {
- var preSwitchState = currentReachabilityState;
- var postSwitchLabel = pushImplicitLabel();
- bind(n.expression);
- bind(n.caseBlock);
- var hasDefault = ts.forEach(n.caseBlock.clauses, function (c) { return c.kind === 242; });
- var postSwitchState = hasDefault && currentReachabilityState !== 2 ? 4 : preSwitchState;
- popImplicitLabel(postSwitchLabel, postSwitchState);
+ var pos = nodeIsMissing(errorNode)
+ ? errorNode.pos
+ : ts.skipTrivia(sourceFile.text, errorNode.pos);
+ return ts.createTextSpanFromBounds(pos, errorNode.end);
+ }
+ ts.getErrorSpanForNode = getErrorSpanForNode;
+ function isExternalModule(file) {
+ return file.externalModuleIndicator !== undefined;
+ }
+ ts.isExternalModule = isExternalModule;
+ function isExternalOrCommonJsModule(file) {
+ return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
+ }
+ ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
+ function isDeclarationFile(file) {
+ return (file.flags & 4096) !== 0;
+ }
+ ts.isDeclarationFile = isDeclarationFile;
+ function isConstEnumDeclaration(node) {
+ return node.kind === 217 && isConst(node);
+ }
+ ts.isConstEnumDeclaration = isConstEnumDeclaration;
+ function walkUpBindingElementsAndPatterns(node) {
+ while (node && (node.kind === 163 || isBindingPattern(node))) {
+ node = node.parent;
}
- function bindCaseBlock(n) {
- var startState = currentReachabilityState;
- for (var _i = 0, _a = n.clauses; _i < _a.length; _i++) {
- var clause = _a[_i];
- currentReachabilityState = startState;
- bind(clause);
- if (clause.statements.length && currentReachabilityState === 2 && options.noFallthroughCasesInSwitch) {
- errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
- }
- }
+ return node;
+ }
+ function getCombinedNodeFlags(node) {
+ node = walkUpBindingElementsAndPatterns(node);
+ var flags = node.flags;
+ if (node.kind === 211) {
+ node = node.parent;
}
- function bindLabeledStatement(n) {
- bind(n.label);
- var ok = pushNamedLabel(n.label);
- bind(n.statement);
- if (ok) {
- popNamedLabel(n.label, currentReachabilityState);
- }
+ if (node && node.kind === 212) {
+ flags |= node.flags;
+ node = node.parent;
}
- function getContainerFlags(node) {
- switch (node.kind) {
- case 186:
- case 214:
- case 215:
- case 217:
- case 155:
- case 165:
- return 1;
- case 147:
- case 148:
- case 149:
- case 143:
- case 142:
- case 213:
- case 144:
- case 145:
- case 146:
- case 152:
- case 153:
- case 173:
- case 174:
- case 218:
- case 248:
- case 216:
- return 5;
- case 244:
- case 199:
- case 200:
- case 201:
- case 220:
- return 2;
- case 192:
- return ts.isFunctionLike(node.parent) ? 0 : 2;
- }
- return 0;
+ if (node && node.kind === 193) {
+ flags |= node.flags;
}
- function addToContainerChain(next) {
- if (lastContainer) {
- lastContainer.nextContainer = next;
- }
- lastContainer = next;
+ return flags;
+ }
+ ts.getCombinedNodeFlags = getCombinedNodeFlags;
+ function isConst(node) {
+ return !!(getCombinedNodeFlags(node) & 16384);
+ }
+ ts.isConst = isConst;
+ function isLet(node) {
+ return !!(getCombinedNodeFlags(node) & 8192);
+ }
+ ts.isLet = isLet;
+ function isPrologueDirective(node) {
+ return node.kind === 195 && node.expression.kind === 9;
+ }
+ ts.isPrologueDirective = isPrologueDirective;
+ function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
+ return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
+ }
+ ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
+ function getLeadingCommentRangesOfNodeFromText(node, text) {
+ return ts.getLeadingCommentRanges(text, node.pos);
+ }
+ ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText;
+ function getJsDocComments(node, sourceFileOfNode) {
+ return getJsDocCommentsFromText(node, sourceFileOfNode.text);
+ }
+ ts.getJsDocComments = getJsDocComments;
+ function getJsDocCommentsFromText(node, text) {
+ var commentRanges = (node.kind === 138 || node.kind === 137) ?
+ ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
+ getLeadingCommentRangesOfNodeFromText(node, text);
+ return ts.filter(commentRanges, isJsDocComment);
+ function isJsDocComment(comment) {
+ return text.charCodeAt(comment.pos + 1) === 42 &&
+ text.charCodeAt(comment.pos + 2) === 42 &&
+ text.charCodeAt(comment.pos + 3) !== 47;
}
- function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
- declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes);
+ }
+ ts.getJsDocCommentsFromText = getJsDocCommentsFromText;
+ ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/;
+ ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/;
+ function isTypeNode(node) {
+ if (151 <= node.kind && node.kind <= 160) {
+ return true;
}
- function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) {
- switch (container.kind) {
- case 218:
- return declareModuleMember(node, symbolFlags, symbolExcludes);
- case 248:
- return declareSourceFileMember(node, symbolFlags, symbolExcludes);
- case 186:
- case 214:
- return declareClassMember(node, symbolFlags, symbolExcludes);
- case 217:
- return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- case 155:
- case 165:
- case 215:
- return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
- case 152:
- case 153:
- case 147:
- case 148:
- case 149:
- case 143:
- case 142:
- case 144:
- case 145:
- case 146:
- case 213:
- case 173:
- case 174:
- case 216:
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- }
- function declareClassMember(node, symbolFlags, symbolExcludes) {
- return node.flags & 64
- ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
- : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
- }
- function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
- return ts.isExternalModule(file)
- ? declareModuleMember(node, symbolFlags, symbolExcludes)
- : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- function hasExportDeclarations(node) {
- var body = node.kind === 248 ? node : node.body;
- if (body.kind === 248 || body.kind === 219) {
- for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
- var stat = _a[_i];
- if (stat.kind === 228 || stat.kind === 227) {
- return true;
- }
+ switch (node.kind) {
+ case 117:
+ case 128:
+ case 130:
+ case 120:
+ case 131:
+ return true;
+ case 103:
+ return node.parent.kind !== 177;
+ case 9:
+ return node.parent.kind === 138;
+ case 188:
+ return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
+ case 69:
+ if (node.parent.kind === 135 && node.parent.right === node) {
+ node = node.parent;
}
- }
- return false;
- }
- function setExportContextFlag(node) {
- if (ts.isInAmbientContext(node) && !hasExportDeclarations(node)) {
- node.flags |= 131072;
- }
- else {
- node.flags &= ~131072;
- }
- }
- function bindModuleDeclaration(node) {
- setExportContextFlag(node);
- if (node.name.kind === 9) {
- declareSymbolAndAddToSymbolTable(node, 512, 106639);
- }
- else {
- var state = getModuleInstanceState(node);
- if (state === 0) {
- declareSymbolAndAddToSymbolTable(node, 1024, 0);
+ else if (node.parent.kind === 166 && node.parent.name === node) {
+ node = node.parent;
}
- else {
- declareSymbolAndAddToSymbolTable(node, 512, 106639);
- if (node.symbol.flags & (16 | 32 | 256)) {
- node.symbol.constEnumOnlyModule = false;
- }
- else {
- var currentModuleIsConstEnumOnly = state === 2;
- if (node.symbol.constEnumOnlyModule === undefined) {
- node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
- }
- else {
- node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
- }
- }
+ ts.Debug.assert(node.kind === 69 || node.kind === 135 || node.kind === 166, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'.");
+ case 135:
+ case 166:
+ case 97:
+ var parent_1 = node.parent;
+ if (parent_1.kind === 154) {
+ return false;
}
- }
- }
- function bindFunctionOrConstructorType(node) {
- var symbol = createSymbol(131072, getDeclarationName(node));
- addDeclarationToSymbol(symbol, node, 131072);
- var typeLiteralSymbol = createSymbol(2048, "__type");
- addDeclarationToSymbol(typeLiteralSymbol, node, 2048);
- typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a);
- var _a;
- }
- function bindObjectLiteralExpression(node) {
- if (inStrictMode) {
- var seen = {};
- for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
- var prop = _a[_i];
- if (prop.name.kind !== 69) {
- continue;
- }
- var identifier = prop.name;
- var currentKind = prop.kind === 245 || prop.kind === 246 || prop.kind === 143
- ? 1
- : 2;
- var existingKind = seen[identifier.text];
- if (!existingKind) {
- seen[identifier.text] = currentKind;
- continue;
- }
- if (currentKind === 1 && existingKind === 1) {
- var span = ts.getErrorSpanForNode(file, identifier);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
- }
+ if (151 <= parent_1.kind && parent_1.kind <= 160) {
+ return true;
+ }
+ switch (parent_1.kind) {
+ case 188:
+ return !isExpressionWithTypeArgumentsInClassExtendsClause(parent_1);
+ case 137:
+ return node === parent_1.constraint;
+ case 141:
+ case 140:
+ case 138:
+ case 211:
+ return node === parent_1.type;
+ case 213:
+ case 173:
+ case 174:
+ case 144:
+ case 143:
+ case 142:
+ case 145:
+ case 146:
+ return node === parent_1.type;
+ case 147:
+ case 148:
+ case 149:
+ return node === parent_1.type;
+ case 171:
+ return node === parent_1.type;
+ case 168:
+ case 169:
+ return parent_1.typeArguments && ts.indexOf(parent_1.typeArguments, node) >= 0;
+ case 170:
+ return false;
}
- }
- return bindAnonymousDeclaration(node, 4096, "__object");
}
- function bindAnonymousDeclaration(node, symbolFlags, name) {
- var symbol = createSymbol(symbolFlags, name);
- addDeclarationToSymbol(symbol, node, symbolFlags);
+ return false;
+ }
+ ts.isTypeNode = isTypeNode;
+ function forEachReturnStatement(body, visitor) {
+ return traverse(body);
+ function traverse(node) {
+ switch (node.kind) {
+ case 204:
+ return visitor(node);
+ case 220:
+ case 192:
+ case 196:
+ case 197:
+ case 198:
+ case 199:
+ case 200:
+ case 201:
+ case 205:
+ case 206:
+ case 241:
+ case 242:
+ case 207:
+ case 209:
+ case 244:
+ return ts.forEachChild(node, traverse);
+ }
}
- function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
- switch (blockScopeContainer.kind) {
- case 218:
- declareModuleMember(node, symbolFlags, symbolExcludes);
- break;
- case 248:
- if (ts.isExternalModule(container)) {
- declareModuleMember(node, symbolFlags, symbolExcludes);
- break;
+ }
+ ts.forEachReturnStatement = forEachReturnStatement;
+ function forEachYieldExpression(body, visitor) {
+ return traverse(body);
+ function traverse(node) {
+ switch (node.kind) {
+ case 184:
+ visitor(node);
+ var operand = node.expression;
+ if (operand) {
+ traverse(operand);
}
+ case 217:
+ case 215:
+ case 218:
+ case 216:
+ case 214:
+ case 186:
+ return;
default:
- if (!blockScopeContainer.locals) {
- blockScopeContainer.locals = {};
- addToContainerChain(blockScopeContainer);
+ if (isFunctionLike(node)) {
+ var name_5 = node.name;
+ if (name_5 && name_5.kind === 136) {
+ traverse(name_5.expression);
+ return;
+ }
+ }
+ else if (!isTypeNode(node)) {
+ ts.forEachChild(node, traverse);
}
- declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
}
}
- function bindBlockScopedVariableDeclaration(node) {
- bindBlockScopedDeclaration(node, 2, 107455);
- }
- function checkStrictModeIdentifier(node) {
- if (inStrictMode &&
- node.originalKeywordKind >= 106 &&
- node.originalKeywordKind <= 114 &&
- !ts.isIdentifierName(node)) {
- if (!file.parseDiagnostics.length) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
- }
+ }
+ ts.forEachYieldExpression = forEachYieldExpression;
+ function isVariableLike(node) {
+ if (node) {
+ switch (node.kind) {
+ case 163:
+ case 247:
+ case 138:
+ case 245:
+ case 141:
+ case 140:
+ case 246:
+ case 211:
+ return true;
}
}
- function getStrictModeIdentifierMessage(node) {
- if (ts.getContainingClass(node)) {
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
- }
- if (file.externalModuleIndicator) {
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
- }
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
- }
- function checkStrictModeBinaryExpression(node) {
- if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
- checkStrictModeEvalOrArguments(node, node.left);
- }
- }
- function checkStrictModeCatchClause(node) {
- if (inStrictMode && node.variableDeclaration) {
- checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
- }
- }
- function checkStrictModeDeleteExpression(node) {
- if (inStrictMode && node.expression.kind === 69) {
- var span = ts.getErrorSpanForNode(file, node.expression);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
- }
+ return false;
+ }
+ ts.isVariableLike = isVariableLike;
+ function isAccessor(node) {
+ return node && (node.kind === 145 || node.kind === 146);
+ }
+ ts.isAccessor = isAccessor;
+ function isClassLike(node) {
+ return node && (node.kind === 214 || node.kind === 186);
+ }
+ ts.isClassLike = isClassLike;
+ function isFunctionLike(node) {
+ return node && isFunctionLikeKind(node.kind);
+ }
+ ts.isFunctionLike = isFunctionLike;
+ function isFunctionLikeKind(kind) {
+ switch (kind) {
+ case 144:
+ case 173:
+ case 213:
+ case 174:
+ case 143:
+ case 142:
+ case 145:
+ case 146:
+ case 147:
+ case 148:
+ case 149:
+ case 152:
+ case 153:
+ return true;
}
- function isEvalOrArgumentsIdentifier(node) {
- return node.kind === 69 &&
- (node.text === "eval" || node.text === "arguments");
+ }
+ ts.isFunctionLikeKind = isFunctionLikeKind;
+ function introducesArgumentsExoticObject(node) {
+ switch (node.kind) {
+ case 143:
+ case 142:
+ case 144:
+ case 145:
+ case 146:
+ case 213:
+ case 173:
+ return true;
}
- function checkStrictModeEvalOrArguments(contextNode, name) {
- if (name && name.kind === 69) {
- var identifier = name;
- if (isEvalOrArgumentsIdentifier(identifier)) {
- var span = ts.getErrorSpanForNode(file, name);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
- }
- }
+ return false;
+ }
+ ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject;
+ function isIterationStatement(node, lookInLabeledStatements) {
+ switch (node.kind) {
+ case 199:
+ case 200:
+ case 201:
+ case 197:
+ case 198:
+ return true;
+ case 207:
+ return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
}
- function getStrictModeEvalOrArgumentsMessage(node) {
- if (ts.getContainingClass(node)) {
- return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
- }
- if (file.externalModuleIndicator) {
- return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
+ return false;
+ }
+ ts.isIterationStatement = isIterationStatement;
+ function isFunctionBlock(node) {
+ return node && node.kind === 192 && isFunctionLike(node.parent);
+ }
+ ts.isFunctionBlock = isFunctionBlock;
+ function isObjectLiteralMethod(node) {
+ return node && node.kind === 143 && node.parent.kind === 165;
+ }
+ ts.isObjectLiteralMethod = isObjectLiteralMethod;
+ function getContainingFunction(node) {
+ while (true) {
+ node = node.parent;
+ if (!node || isFunctionLike(node)) {
+ return node;
}
- return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
}
- function checkStrictModeFunctionName(node) {
- if (inStrictMode) {
- checkStrictModeEvalOrArguments(node, node.name);
+ }
+ ts.getContainingFunction = getContainingFunction;
+ function getContainingClass(node) {
+ while (true) {
+ node = node.parent;
+ if (!node || isClassLike(node)) {
+ return node;
}
}
- function checkStrictModeNumericLiteral(node) {
- if (inStrictMode && node.flags & 32768) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
+ }
+ ts.getContainingClass = getContainingClass;
+ function getThisContainer(node, includeArrowFunctions) {
+ while (true) {
+ node = node.parent;
+ if (!node) {
+ return undefined;
}
- }
- function checkStrictModePostfixUnaryExpression(node) {
- if (inStrictMode) {
- checkStrictModeEvalOrArguments(node, node.operand);
+ switch (node.kind) {
+ case 136:
+ if (isClassLike(node.parent.parent)) {
+ return node;
+ }
+ node = node.parent;
+ break;
+ case 139:
+ if (node.parent.kind === 138 && isClassElement(node.parent.parent)) {
+ node = node.parent.parent;
+ }
+ else if (isClassElement(node.parent)) {
+ node = node.parent;
+ }
+ break;
+ case 174:
+ if (!includeArrowFunctions) {
+ continue;
+ }
+ case 213:
+ case 173:
+ case 218:
+ case 141:
+ case 140:
+ case 143:
+ case 142:
+ case 144:
+ case 145:
+ case 146:
+ case 147:
+ case 148:
+ case 149:
+ case 217:
+ case 248:
+ return node;
}
}
- function checkStrictModePrefixUnaryExpression(node) {
- if (inStrictMode) {
- if (node.operator === 41 || node.operator === 42) {
- checkStrictModeEvalOrArguments(node, node.operand);
- }
+ }
+ ts.getThisContainer = getThisContainer;
+ function getSuperContainer(node, includeFunctions) {
+ while (true) {
+ node = node.parent;
+ if (!node)
+ return node;
+ switch (node.kind) {
+ case 136:
+ if (isClassLike(node.parent.parent)) {
+ return node;
+ }
+ node = node.parent;
+ break;
+ case 139:
+ if (node.parent.kind === 138 && isClassElement(node.parent.parent)) {
+ node = node.parent.parent;
+ }
+ else if (isClassElement(node.parent)) {
+ node = node.parent;
+ }
+ break;
+ case 213:
+ case 173:
+ case 174:
+ if (!includeFunctions) {
+ continue;
+ }
+ case 141:
+ case 140:
+ case 143:
+ case 142:
+ case 144:
+ case 145:
+ case 146:
+ return node;
}
}
- function checkStrictModeWithStatement(node) {
- if (inStrictMode) {
- errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
+ }
+ ts.getSuperContainer = getSuperContainer;
+ function getEntityNameFromTypeNode(node) {
+ if (node) {
+ switch (node.kind) {
+ case 151:
+ return node.typeName;
+ case 188:
+ return node.expression;
+ case 69:
+ case 135:
+ return node;
}
}
- function errorOnFirstToken(node, message, arg0, arg1, arg2) {
- var span = ts.getSpanOfTokenAtPosition(file, node.pos);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
+ return undefined;
+ }
+ ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode;
+ function getInvokedExpression(node) {
+ if (node.kind === 170) {
+ return node.tag;
}
- function getDestructuringParameterName(node) {
- return "__" + ts.indexOf(node.parent.parameters, node);
+ return node.expression;
+ }
+ ts.getInvokedExpression = getInvokedExpression;
+ function nodeCanBeDecorated(node) {
+ switch (node.kind) {
+ case 214:
+ return true;
+ case 141:
+ return node.parent.kind === 214;
+ case 138:
+ return node.parent.body && node.parent.parent.kind === 214;
+ case 145:
+ case 146:
+ case 143:
+ return node.body && node.parent.kind === 214;
}
- function bind(node) {
- if (!node) {
- return;
- }
- node.parent = parent;
- var savedInStrictMode = inStrictMode;
- if (!savedInStrictMode) {
- updateStrictMode(node);
- }
- bindWorker(node);
- bindChildren(node);
- inStrictMode = savedInStrictMode;
+ return false;
+ }
+ ts.nodeCanBeDecorated = nodeCanBeDecorated;
+ function nodeIsDecorated(node) {
+ switch (node.kind) {
+ case 214:
+ if (node.decorators) {
+ return true;
+ }
+ return false;
+ case 141:
+ case 138:
+ if (node.decorators) {
+ return true;
+ }
+ return false;
+ case 145:
+ if (node.body && node.decorators) {
+ return true;
+ }
+ return false;
+ case 143:
+ case 146:
+ if (node.body && node.decorators) {
+ return true;
+ }
+ return false;
}
- function updateStrictMode(node) {
- switch (node.kind) {
- case 248:
- case 219:
- updateStrictModeStatementList(node.statements);
- return;
- case 192:
- if (ts.isFunctionLike(node.parent)) {
- updateStrictModeStatementList(node.statements);
- }
- return;
- case 214:
- case 186:
- inStrictMode = true;
- return;
- }
+ return false;
+ }
+ ts.nodeIsDecorated = nodeIsDecorated;
+ function childIsDecorated(node) {
+ switch (node.kind) {
+ case 214:
+ return ts.forEach(node.members, nodeOrChildIsDecorated);
+ case 143:
+ case 146:
+ return ts.forEach(node.parameters, nodeIsDecorated);
}
- function updateStrictModeStatementList(statements) {
- for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
- var statement = statements_1[_i];
- if (!ts.isPrologueDirective(statement)) {
- return;
+ return false;
+ }
+ ts.childIsDecorated = childIsDecorated;
+ function nodeOrChildIsDecorated(node) {
+ return nodeIsDecorated(node) || childIsDecorated(node);
+ }
+ ts.nodeOrChildIsDecorated = nodeOrChildIsDecorated;
+ function isPropertyAccessExpression(node) {
+ return node.kind === 166;
+ }
+ ts.isPropertyAccessExpression = isPropertyAccessExpression;
+ function isElementAccessExpression(node) {
+ return node.kind === 167;
+ }
+ ts.isElementAccessExpression = isElementAccessExpression;
+ function isExpression(node) {
+ switch (node.kind) {
+ case 95:
+ case 93:
+ case 99:
+ case 84:
+ case 10:
+ case 164:
+ case 165:
+ case 166:
+ case 167:
+ case 168:
+ case 169:
+ case 170:
+ case 189:
+ case 171:
+ case 172:
+ case 173:
+ case 186:
+ case 174:
+ case 177:
+ case 175:
+ case 176:
+ case 179:
+ case 180:
+ case 181:
+ case 182:
+ case 185:
+ case 183:
+ case 11:
+ case 187:
+ case 233:
+ case 234:
+ case 184:
+ case 178:
+ return true;
+ case 135:
+ while (node.parent.kind === 135) {
+ node = node.parent;
}
- if (isUseStrictPrologueDirective(statement)) {
- inStrictMode = true;
- return;
+ return node.parent.kind === 154;
+ case 69:
+ if (node.parent.kind === 154) {
+ return true;
+ }
+ case 8:
+ case 9:
+ case 97:
+ var parent_2 = node.parent;
+ switch (parent_2.kind) {
+ case 211:
+ case 138:
+ case 141:
+ case 140:
+ case 247:
+ case 245:
+ case 163:
+ return parent_2.initializer === node;
+ case 195:
+ case 196:
+ case 197:
+ case 198:
+ case 204:
+ case 205:
+ case 206:
+ case 241:
+ case 208:
+ case 206:
+ return parent_2.expression === node;
+ case 199:
+ var forStatement = parent_2;
+ return (forStatement.initializer === node && forStatement.initializer.kind !== 212) ||
+ forStatement.condition === node ||
+ forStatement.incrementor === node;
+ case 200:
+ case 201:
+ var forInStatement = parent_2;
+ return (forInStatement.initializer === node && forInStatement.initializer.kind !== 212) ||
+ forInStatement.expression === node;
+ case 171:
+ case 189:
+ return node === parent_2.expression;
+ case 190:
+ return node === parent_2.expression;
+ case 136:
+ return node === parent_2.expression;
+ case 139:
+ case 240:
+ case 239:
+ return true;
+ case 188:
+ return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2);
+ default:
+ if (isExpression(parent_2)) {
+ return true;
+ }
}
+ }
+ return false;
+ }
+ ts.isExpression = isExpression;
+ function isExternalModuleNameRelative(moduleName) {
+ return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\";
+ }
+ ts.isExternalModuleNameRelative = isExternalModuleNameRelative;
+ function isInstantiatedModule(node, preserveConstEnums) {
+ var moduleState = ts.getModuleInstanceState(node);
+ return moduleState === 1 ||
+ (preserveConstEnums && moduleState === 2);
+ }
+ ts.isInstantiatedModule = isInstantiatedModule;
+ function isExternalModuleImportEqualsDeclaration(node) {
+ return node.kind === 221 && node.moduleReference.kind === 232;
+ }
+ ts.isExternalModuleImportEqualsDeclaration = isExternalModuleImportEqualsDeclaration;
+ function getExternalModuleImportEqualsDeclarationExpression(node) {
+ ts.Debug.assert(isExternalModuleImportEqualsDeclaration(node));
+ return node.moduleReference.expression;
+ }
+ ts.getExternalModuleImportEqualsDeclarationExpression = getExternalModuleImportEqualsDeclarationExpression;
+ function isInternalModuleImportEqualsDeclaration(node) {
+ return node.kind === 221 && node.moduleReference.kind !== 232;
+ }
+ ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
+ function isSourceFileJavaScript(file) {
+ return isInJavaScriptFile(file);
+ }
+ ts.isSourceFileJavaScript = isSourceFileJavaScript;
+ function isInJavaScriptFile(node) {
+ return node && !!(node.parserContextFlags & 32);
+ }
+ ts.isInJavaScriptFile = isInJavaScriptFile;
+ function isRequireCall(expression) {
+ return expression.kind === 168 &&
+ expression.expression.kind === 69 &&
+ expression.expression.text === "require" &&
+ expression.arguments.length === 1 &&
+ expression.arguments[0].kind === 9;
+ }
+ ts.isRequireCall = isRequireCall;
+ function isExportsPropertyAssignment(expression) {
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === 181) &&
+ (expression.operatorToken.kind === 56) &&
+ (expression.left.kind === 166) &&
+ (expression.left.expression.kind === 69) &&
+ ((expression.left.expression).text === "exports");
+ }
+ ts.isExportsPropertyAssignment = isExportsPropertyAssignment;
+ function isModuleExportsAssignment(expression) {
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === 181) &&
+ (expression.operatorToken.kind === 56) &&
+ (expression.left.kind === 166) &&
+ (expression.left.expression.kind === 69) &&
+ ((expression.left.expression).text === "module") &&
+ (expression.left.name.text === "exports");
+ }
+ ts.isModuleExportsAssignment = isModuleExportsAssignment;
+ function getExternalModuleName(node) {
+ if (node.kind === 222) {
+ return node.moduleSpecifier;
+ }
+ if (node.kind === 221) {
+ var reference = node.moduleReference;
+ if (reference.kind === 232) {
+ return reference.expression;
}
}
- function isUseStrictPrologueDirective(node) {
- var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression);
- return nodeText === "\"use strict\"" || nodeText === "'use strict'";
+ if (node.kind === 228) {
+ return node.moduleSpecifier;
}
- function bindWorker(node) {
+ }
+ ts.getExternalModuleName = getExternalModuleName;
+ function hasQuestionToken(node) {
+ if (node) {
switch (node.kind) {
- case 69:
- return checkStrictModeIdentifier(node);
- case 181:
- return checkStrictModeBinaryExpression(node);
- case 244:
- return checkStrictModeCatchClause(node);
- case 175:
- return checkStrictModeDeleteExpression(node);
- case 8:
- return checkStrictModeNumericLiteral(node);
- case 180:
- return checkStrictModePostfixUnaryExpression(node);
- case 179:
- return checkStrictModePrefixUnaryExpression(node);
- case 205:
- return checkStrictModeWithStatement(node);
- case 97:
- seenThisKeyword = true;
- return;
- case 137:
- return declareSymbolAndAddToSymbolTable(node, 262144, 530912);
case 138:
- return bindParameter(node);
- case 211:
- case 163:
- return bindVariableDeclarationOrBindingElement(node);
+ case 143:
+ case 142:
+ case 246:
+ case 245:
case 141:
case 140:
- return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455);
- case 245:
- case 246:
- return bindPropertyOrMethodOrAccessor(node, 4, 107455);
- case 247:
- return bindPropertyOrMethodOrAccessor(node, 8, 107455);
- case 147:
- case 148:
- case 149:
- return declareSymbolAndAddToSymbolTable(node, 131072, 0);
- case 143:
- case 142:
- return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263);
- case 213:
- checkStrictModeFunctionName(node);
- return declareSymbolAndAddToSymbolTable(node, 16, 106927);
- case 144:
- return declareSymbolAndAddToSymbolTable(node, 16384, 0);
- case 145:
- return bindPropertyOrMethodOrAccessor(node, 32768, 41919);
- case 146:
- return bindPropertyOrMethodOrAccessor(node, 65536, 74687);
- case 152:
- case 153:
- return bindFunctionOrConstructorType(node);
- case 155:
- return bindAnonymousDeclaration(node, 2048, "__type");
- case 165:
- return bindObjectLiteralExpression(node);
- case 173:
- case 174:
- checkStrictModeFunctionName(node);
- var bindingName = node.name ? node.name.text : "__function";
- return bindAnonymousDeclaration(node, 16, bindingName);
- case 186:
- case 214:
- return bindClassLikeDeclaration(node);
- case 215:
- return bindBlockScopedDeclaration(node, 64, 792960);
- case 216:
- return bindBlockScopedDeclaration(node, 524288, 793056);
- case 217:
- return bindEnumDeclaration(node);
- case 218:
- return bindModuleDeclaration(node);
- case 221:
- case 224:
- case 226:
- case 230:
- return declareSymbolAndAddToSymbolTable(node, 8388608, 8388608);
- case 223:
- return bindImportClause(node);
- case 228:
- return bindExportDeclaration(node);
- case 227:
- return bindExportAssignment(node);
- case 248:
- return bindSourceFileIfExternalModule();
- }
- }
- function bindSourceFileIfExternalModule() {
- setExportContextFlag(file);
- if (ts.isExternalModule(file)) {
- bindAnonymousDeclaration(file, 512, "\"" + ts.removeFileExtension(file.fileName) + "\"");
- }
- }
- function bindExportAssignment(node) {
- if (!container.symbol || !container.symbol.exports) {
- bindAnonymousDeclaration(node, 8388608, getDeclarationName(node));
- }
- else if (node.expression.kind === 69) {
- declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608);
- }
- else {
- declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608);
+ return node.questionToken !== undefined;
}
}
- function bindExportDeclaration(node) {
- if (!container.symbol || !container.symbol.exports) {
- bindAnonymousDeclaration(node, 1073741824, getDeclarationName(node));
- }
- else if (!node.exportClause) {
- declareSymbol(container.symbol.exports, container.symbol, node, 1073741824, 0);
+ return false;
+ }
+ ts.hasQuestionToken = hasQuestionToken;
+ function isJSDocConstructSignature(node) {
+ return node.kind === 261 &&
+ node.parameters.length > 0 &&
+ node.parameters[0].type.kind === 263;
+ }
+ ts.isJSDocConstructSignature = isJSDocConstructSignature;
+ function getJSDocTag(node, kind) {
+ if (node && node.jsDocComment) {
+ for (var _i = 0, _a = node.jsDocComment.tags; _i < _a.length; _i++) {
+ var tag = _a[_i];
+ if (tag.kind === kind) {
+ return tag;
+ }
}
}
- function bindImportClause(node) {
- if (node.name) {
- declareSymbolAndAddToSymbolTable(node, 8388608, 8388608);
+ }
+ function getJSDocTypeTag(node) {
+ return getJSDocTag(node, 269);
+ }
+ ts.getJSDocTypeTag = getJSDocTypeTag;
+ function getJSDocReturnTag(node) {
+ return getJSDocTag(node, 268);
+ }
+ ts.getJSDocReturnTag = getJSDocReturnTag;
+ function getJSDocTemplateTag(node) {
+ return getJSDocTag(node, 270);
+ }
+ ts.getJSDocTemplateTag = getJSDocTemplateTag;
+ function getCorrespondingJSDocParameterTag(parameter) {
+ if (parameter.name && parameter.name.kind === 69) {
+ var parameterName = parameter.name.text;
+ var docComment = parameter.parent.jsDocComment;
+ if (docComment) {
+ return ts.forEach(docComment.tags, function (t) {
+ if (t.kind === 267) {
+ var parameterTag = t;
+ var name_6 = parameterTag.preParameterName || parameterTag.postParameterName;
+ if (name_6.text === parameterName) {
+ return t;
+ }
+ }
+ });
}
}
- function bindClassLikeDeclaration(node) {
- if (node.kind === 214) {
- bindBlockScopedDeclaration(node, 32, 899519);
- }
- else {
- var bindingName = node.name ? node.name.text : "__class";
- bindAnonymousDeclaration(node, 32, bindingName);
- if (node.name) {
- classifiableNames[node.name.text] = node.name.text;
+ }
+ ts.getCorrespondingJSDocParameterTag = getCorrespondingJSDocParameterTag;
+ function hasRestParameter(s) {
+ return isRestParameter(ts.lastOrUndefined(s.parameters));
+ }
+ ts.hasRestParameter = hasRestParameter;
+ function isRestParameter(node) {
+ if (node) {
+ if (node.parserContextFlags & 32) {
+ if (node.type && node.type.kind === 262) {
+ return true;
}
- }
- var symbol = node.symbol;
- var prototypeSymbol = createSymbol(4 | 134217728, "prototype");
- if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) {
- if (node.name) {
- node.name.parent = node;
+ var paramTag = getCorrespondingJSDocParameterTag(node);
+ if (paramTag && paramTag.typeExpression) {
+ return paramTag.typeExpression.type.kind === 262;
}
- file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
}
- symbol.exports[prototypeSymbol.name] = prototypeSymbol;
- prototypeSymbol.parent = symbol;
+ return node.dotDotDotToken !== undefined;
}
- function bindEnumDeclaration(node) {
- return ts.isConst(node)
- ? bindBlockScopedDeclaration(node, 128, 899967)
- : bindBlockScopedDeclaration(node, 256, 899327);
+ return false;
+ }
+ ts.isRestParameter = isRestParameter;
+ function isLiteralKind(kind) {
+ return 8 <= kind && kind <= 11;
+ }
+ ts.isLiteralKind = isLiteralKind;
+ function isTextualLiteralKind(kind) {
+ return kind === 9 || kind === 11;
+ }
+ ts.isTextualLiteralKind = isTextualLiteralKind;
+ function isTemplateLiteralKind(kind) {
+ return 11 <= kind && kind <= 14;
+ }
+ ts.isTemplateLiteralKind = isTemplateLiteralKind;
+ function isBindingPattern(node) {
+ return !!node && (node.kind === 162 || node.kind === 161);
+ }
+ ts.isBindingPattern = isBindingPattern;
+ function isNodeDescendentOf(node, ancestor) {
+ while (node) {
+ if (node === ancestor)
+ return true;
+ node = node.parent;
}
- function bindVariableDeclarationOrBindingElement(node) {
- if (inStrictMode) {
- checkStrictModeEvalOrArguments(node, node.name);
- }
- if (!ts.isBindingPattern(node.name)) {
- if (ts.isBlockOrCatchScoped(node)) {
- bindBlockScopedVariableDeclaration(node);
- }
- else if (ts.isParameterDeclaration(node)) {
- declareSymbolAndAddToSymbolTable(node, 1, 107455);
- }
- else {
- declareSymbolAndAddToSymbolTable(node, 1, 107454);
- }
+ return false;
+ }
+ ts.isNodeDescendentOf = isNodeDescendentOf;
+ function isInAmbientContext(node) {
+ while (node) {
+ if (node.flags & (4 | 4096)) {
+ return true;
}
+ node = node.parent;
}
- function bindParameter(node) {
- if (inStrictMode) {
- checkStrictModeEvalOrArguments(node, node.name);
- }
- if (ts.isBindingPattern(node.name)) {
- bindAnonymousDeclaration(node, 1, getDestructuringParameterName(node));
- }
- else {
- declareSymbolAndAddToSymbolTable(node, 1, 107455);
- }
- if (node.flags & 56 &&
- node.parent.kind === 144 &&
- ts.isClassLike(node.parent.parent)) {
- var classDeclaration = node.parent.parent;
- declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 107455);
- }
+ return false;
+ }
+ ts.isInAmbientContext = isInAmbientContext;
+ function isDeclaration(node) {
+ switch (node.kind) {
+ case 174:
+ case 163:
+ case 214:
+ case 186:
+ case 144:
+ case 217:
+ case 247:
+ case 230:
+ case 213:
+ case 173:
+ case 145:
+ case 223:
+ case 221:
+ case 226:
+ case 215:
+ case 143:
+ case 142:
+ case 218:
+ case 224:
+ case 138:
+ case 245:
+ case 141:
+ case 140:
+ case 146:
+ case 246:
+ case 216:
+ case 137:
+ case 211:
+ return true;
}
- function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
- return ts.hasDynamicName(node)
- ? bindAnonymousDeclaration(node, symbolFlags, "__computed")
- : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
- }
- function pushNamedLabel(name) {
- initializeReachabilityStateIfNecessary();
- if (ts.hasProperty(labelIndexMap, name.text)) {
+ return false;
+ }
+ ts.isDeclaration = isDeclaration;
+ function isStatement(n) {
+ switch (n.kind) {
+ case 203:
+ case 202:
+ case 210:
+ case 197:
+ case 195:
+ case 194:
+ case 200:
+ case 201:
+ case 199:
+ case 196:
+ case 207:
+ case 204:
+ case 206:
+ case 208:
+ case 209:
+ case 193:
+ case 198:
+ case 205:
+ case 227:
+ return true;
+ default:
return false;
- }
- labelIndexMap[name.text] = labelStack.push(1) - 1;
- return true;
}
- function pushImplicitLabel() {
- initializeReachabilityStateIfNecessary();
- var index = labelStack.push(1) - 1;
- implicitLabels.push(index);
- return index;
+ }
+ ts.isStatement = isStatement;
+ function isClassElement(n) {
+ switch (n.kind) {
+ case 144:
+ case 141:
+ case 143:
+ case 145:
+ case 146:
+ case 142:
+ case 149:
+ return true;
+ default:
+ return false;
}
- function popNamedLabel(label, outerState) {
- var index = labelIndexMap[label.text];
- ts.Debug.assert(index !== undefined);
- ts.Debug.assert(labelStack.length == index + 1);
- labelIndexMap[label.text] = undefined;
- setCurrentStateAtLabel(labelStack.pop(), outerState, label);
+ }
+ ts.isClassElement = isClassElement;
+ function isDeclarationName(name) {
+ if (name.kind !== 69 && name.kind !== 9 && name.kind !== 8) {
+ return false;
}
- function popImplicitLabel(implicitLabelIndex, outerState) {
- if (labelStack.length !== implicitLabelIndex + 1) {
- ts.Debug.assert(false, "Label stack: " + labelStack.length + ", index:" + implicitLabelIndex);
- }
- var i = implicitLabels.pop();
- if (implicitLabelIndex !== i) {
- ts.Debug.assert(false, "i: " + i + ", index: " + implicitLabelIndex);
+ var parent = name.parent;
+ if (parent.kind === 226 || parent.kind === 230) {
+ if (parent.propertyName) {
+ return true;
}
- setCurrentStateAtLabel(labelStack.pop(), outerState, undefined);
}
- function setCurrentStateAtLabel(innerMergedState, outerState, label) {
- if (innerMergedState === 1) {
- if (label && !options.allowUnusedLabels) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(label, ts.Diagnostics.Unused_label));
- }
- currentReachabilityState = outerState;
- }
- else {
- currentReachabilityState = or(innerMergedState, outerState);
- }
+ if (isDeclaration(parent)) {
+ return parent.name === name;
}
- function jumpToLabel(label, outerState) {
- initializeReachabilityStateIfNecessary();
- var index = label ? labelIndexMap[label.text] : ts.lastOrUndefined(implicitLabels);
- if (index === undefined) {
+ return false;
+ }
+ ts.isDeclarationName = isDeclarationName;
+ function isIdentifierName(node) {
+ var parent = node.parent;
+ switch (parent.kind) {
+ case 141:
+ case 140:
+ case 143:
+ case 142:
+ case 145:
+ case 146:
+ case 247:
+ case 245:
+ case 166:
+ return parent.name === node;
+ case 135:
+ if (parent.right === node) {
+ while (parent.kind === 135) {
+ parent = parent.parent;
+ }
+ return parent.kind === 154;
+ }
return false;
- }
- var stateAtLabel = labelStack[index];
- labelStack[index] = stateAtLabel === 1 ? outerState : or(stateAtLabel, outerState);
- return true;
+ case 163:
+ case 226:
+ return parent.propertyName === node;
+ case 230:
+ return true;
}
- function checkUnreachable(node) {
- switch (currentReachabilityState) {
- case 4:
- var reportError = ts.isStatement(node) ||
- node.kind === 214 ||
- (node.kind === 218 && shouldReportErrorOnModuleDeclaration(node)) ||
- (node.kind === 217 && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
- if (reportError) {
- currentReachabilityState = 8;
- var reportUnreachableCode = !options.allowUnreachableCode &&
- !ts.isInAmbientContext(node) &&
- (node.kind !== 193 ||
- ts.getCombinedNodeFlags(node.declarationList) & 24576 ||
- ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
- if (reportUnreachableCode) {
- errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
- }
- }
- case 8:
- return true;
- default:
- return false;
- }
- function shouldReportErrorOnModuleDeclaration(node) {
- var instanceState = getModuleInstanceState(node);
- return instanceState === 1 || (instanceState === 2 && options.preserveConstEnums);
+ return false;
+ }
+ ts.isIdentifierName = isIdentifierName;
+ function isAliasSymbolDeclaration(node) {
+ return node.kind === 221 ||
+ node.kind === 223 && !!node.name ||
+ node.kind === 224 ||
+ node.kind === 226 ||
+ node.kind === 230 ||
+ node.kind === 227 && node.expression.kind === 69;
+ }
+ ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration;
+ function getClassExtendsHeritageClauseElement(node) {
+ var heritageClause = getHeritageClause(node.heritageClauses, 83);
+ return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
+ }
+ ts.getClassExtendsHeritageClauseElement = getClassExtendsHeritageClauseElement;
+ function getClassImplementsHeritageClauseElements(node) {
+ var heritageClause = getHeritageClause(node.heritageClauses, 106);
+ return heritageClause ? heritageClause.types : undefined;
+ }
+ ts.getClassImplementsHeritageClauseElements = getClassImplementsHeritageClauseElements;
+ function getInterfaceBaseTypeNodes(node) {
+ var heritageClause = getHeritageClause(node.heritageClauses, 83);
+ return heritageClause ? heritageClause.types : undefined;
+ }
+ ts.getInterfaceBaseTypeNodes = getInterfaceBaseTypeNodes;
+ function getHeritageClause(clauses, kind) {
+ if (clauses) {
+ for (var _i = 0, clauses_1 = clauses; _i < clauses_1.length; _i++) {
+ var clause = clauses_1[_i];
+ if (clause.token === kind) {
+ return clause;
+ }
}
}
- function initializeReachabilityStateIfNecessary() {
- if (labelIndexMap) {
- return;
+ return undefined;
+ }
+ ts.getHeritageClause = getHeritageClause;
+ function tryResolveScriptReference(host, sourceFile, reference) {
+ if (!host.getCompilerOptions().noResolve) {
+ var referenceFileName = ts.isRootedDiskPath(reference.fileName) ? reference.fileName : ts.combinePaths(ts.getDirectoryPath(sourceFile.fileName), reference.fileName);
+ return host.getSourceFile(referenceFileName);
+ }
+ }
+ ts.tryResolveScriptReference = tryResolveScriptReference;
+ function getAncestor(node, kind) {
+ while (node) {
+ if (node.kind === kind) {
+ return node;
}
- currentReachabilityState = 2;
- labelIndexMap = {};
- labelStack = [];
- implicitLabels = [];
+ node = node.parent;
}
+ return undefined;
}
-})(ts || (ts = {}));
-var ts;
-(function (ts) {
- function getDeclarationOfKind(symbol, kind) {
- var declarations = symbol.declarations;
- if (declarations) {
- for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
- var declaration = declarations_1[_i];
- if (declaration.kind === kind) {
- return declaration;
+ ts.getAncestor = getAncestor;
+ function getFileReferenceFromReferencePath(comment, commentRange) {
+ var simpleReferenceRegEx = /^\/\/\/\s*/gim;
+ if (simpleReferenceRegEx.test(comment)) {
+ if (isNoDefaultLibRegEx.test(comment)) {
+ return {
+ isNoDefaultLib: true
+ };
+ }
+ else {
+ var matchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment);
+ if (matchResult) {
+ var start = commentRange.pos;
+ var end = commentRange.end;
+ return {
+ fileReference: {
+ pos: start,
+ end: end,
+ fileName: matchResult[3]
+ },
+ isNoDefaultLib: false
+ };
+ }
+ else {
+ return {
+ diagnosticMessage: ts.Diagnostics.Invalid_reference_directive_syntax,
+ isNoDefaultLib: false
+ };
}
}
}
return undefined;
}
- ts.getDeclarationOfKind = getDeclarationOfKind;
- var stringWriters = [];
- function getSingleLineStringWriter() {
- if (stringWriters.length === 0) {
- var str = "";
- var writeText = function (text) { return str += text; };
- return {
- string: function () { return str; },
- writeKeyword: writeText,
- writeOperator: writeText,
- writePunctuation: writeText,
- writeSpace: writeText,
- writeStringLiteral: writeText,
- writeParameter: writeText,
- writeSymbol: writeText,
- writeLine: function () { return str += " "; },
- increaseIndent: function () { },
- decreaseIndent: function () { },
- clear: function () { return str = ""; },
- trackSymbol: function () { },
- reportInaccessibleThisError: function () { }
- };
- }
- return stringWriters.pop();
- }
- ts.getSingleLineStringWriter = getSingleLineStringWriter;
- function releaseStringWriter(writer) {
- writer.clear();
- stringWriters.push(writer);
+ ts.getFileReferenceFromReferencePath = getFileReferenceFromReferencePath;
+ function isKeyword(token) {
+ return 70 <= token && token <= 134;
}
- ts.releaseStringWriter = releaseStringWriter;
- function getFullWidth(node) {
- return node.end - node.pos;
+ ts.isKeyword = isKeyword;
+ function isTrivia(token) {
+ return 2 <= token && token <= 7;
}
- ts.getFullWidth = getFullWidth;
- function arrayIsEqualTo(array1, array2, equaler) {
- if (!array1 || !array2) {
- return array1 === array2;
- }
- if (array1.length !== array2.length) {
- return false;
- }
- for (var i = 0; i < array1.length; ++i) {
- var equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
- if (!equals) {
- return false;
- }
- }
- return true;
+ ts.isTrivia = isTrivia;
+ function isAsyncFunctionLike(node) {
+ return isFunctionLike(node) && (node.flags & 256) !== 0 && !isAccessor(node);
}
- ts.arrayIsEqualTo = arrayIsEqualTo;
- function hasResolvedModule(sourceFile, moduleNameText) {
- return sourceFile.resolvedModules && ts.hasProperty(sourceFile.resolvedModules, moduleNameText);
+ ts.isAsyncFunctionLike = isAsyncFunctionLike;
+ function isStringOrNumericLiteral(kind) {
+ return kind === 9 || kind === 8;
}
- ts.hasResolvedModule = hasResolvedModule;
- function getResolvedModule(sourceFile, moduleNameText) {
- return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
+ ts.isStringOrNumericLiteral = isStringOrNumericLiteral;
+ function hasDynamicName(declaration) {
+ return declaration.name && isDynamicName(declaration.name);
}
- ts.getResolvedModule = getResolvedModule;
- function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
- if (!sourceFile.resolvedModules) {
- sourceFile.resolvedModules = {};
- }
- sourceFile.resolvedModules[moduleNameText] = resolvedModule;
+ ts.hasDynamicName = hasDynamicName;
+ function isDynamicName(name) {
+ return name.kind === 136 &&
+ !isStringOrNumericLiteral(name.expression.kind) &&
+ !isWellKnownSymbolSyntactically(name.expression);
}
- ts.setResolvedModule = setResolvedModule;
- function containsParseError(node) {
- aggregateChildData(node);
- return (node.parserContextFlags & 64) !== 0;
+ ts.isDynamicName = isDynamicName;
+ function isWellKnownSymbolSyntactically(node) {
+ return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
}
- ts.containsParseError = containsParseError;
- function aggregateChildData(node) {
- if (!(node.parserContextFlags & 128)) {
- var thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & 16) !== 0) ||
- ts.forEachChild(node, containsParseError);
- if (thisNodeOrAnySubNodesHasError) {
- node.parserContextFlags |= 64;
- }
- node.parserContextFlags |= 128;
+ ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically;
+ function getPropertyNameForPropertyNameNode(name) {
+ if (name.kind === 69 || name.kind === 9 || name.kind === 8) {
+ return name.text;
}
- }
- function getSourceFileOfNode(node) {
- while (node && node.kind !== 248) {
- node = node.parent;
+ if (name.kind === 136) {
+ var nameExpression = name.expression;
+ if (isWellKnownSymbolSyntactically(nameExpression)) {
+ var rightHandSideName = nameExpression.name.text;
+ return getPropertyNameForKnownSymbolName(rightHandSideName);
+ }
}
- return node;
- }
- ts.getSourceFileOfNode = getSourceFileOfNode;
- function getStartPositionOfLine(line, sourceFile) {
- ts.Debug.assert(line >= 0);
- return ts.getLineStarts(sourceFile)[line];
+ return undefined;
}
- ts.getStartPositionOfLine = getStartPositionOfLine;
- function nodePosToString(node) {
- var file = getSourceFileOfNode(node);
- var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
- return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
+ ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode;
+ function getPropertyNameForKnownSymbolName(symbolName) {
+ return "__@" + symbolName;
}
- ts.nodePosToString = nodePosToString;
- function getStartPosOfNode(node) {
- return node.pos;
+ ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName;
+ function isESSymbolIdentifier(node) {
+ return node.kind === 69 && node.text === "Symbol";
}
- ts.getStartPosOfNode = getStartPosOfNode;
- function nodeIsMissing(node) {
- if (!node) {
- return true;
+ ts.isESSymbolIdentifier = isESSymbolIdentifier;
+ function isModifier(token) {
+ switch (token) {
+ case 115:
+ case 118:
+ case 74:
+ case 122:
+ case 77:
+ case 82:
+ case 112:
+ case 110:
+ case 111:
+ case 113:
+ return true;
}
- return node.pos === node.end && node.pos >= 0 && node.kind !== 1;
+ return false;
}
- ts.nodeIsMissing = nodeIsMissing;
- function nodeIsPresent(node) {
- return !nodeIsMissing(node);
+ ts.isModifier = isModifier;
+ function isParameterDeclaration(node) {
+ var root = getRootDeclaration(node);
+ return root.kind === 138;
}
- ts.nodeIsPresent = nodeIsPresent;
- function getTokenPosOfNode(node, sourceFile) {
- if (nodeIsMissing(node)) {
- return node.pos;
+ ts.isParameterDeclaration = isParameterDeclaration;
+ function getRootDeclaration(node) {
+ while (node.kind === 163) {
+ node = node.parent.parent;
}
- return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
+ return node;
}
- ts.getTokenPosOfNode = getTokenPosOfNode;
- function getNonDecoratorTokenPosOfNode(node, sourceFile) {
- if (nodeIsMissing(node) || !node.decorators) {
- return getTokenPosOfNode(node, sourceFile);
- }
- return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
+ ts.getRootDeclaration = getRootDeclaration;
+ function nodeStartsNewLexicalEnvironment(n) {
+ return isFunctionLike(n) || n.kind === 218 || n.kind === 248;
}
- ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
- function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
- if (includeTrivia === void 0) { includeTrivia = false; }
- if (nodeIsMissing(node)) {
- return "";
+ ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
+ function cloneEntityName(node) {
+ if (node.kind === 69) {
+ var clone_1 = createSynthesizedNode(69);
+ clone_1.text = node.text;
+ return clone_1;
}
- var text = sourceFile.text;
- return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end);
- }
- ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
- function getTextOfNodeFromSourceText(sourceText, node) {
- if (nodeIsMissing(node)) {
- return "";
+ else {
+ var clone_2 = createSynthesizedNode(135);
+ clone_2.left = cloneEntityName(node.left);
+ clone_2.left.parent = clone_2;
+ clone_2.right = cloneEntityName(node.right);
+ clone_2.right.parent = clone_2;
+ return clone_2;
}
- return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
- }
- ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
- function getTextOfNode(node, includeTrivia) {
- if (includeTrivia === void 0) { includeTrivia = false; }
- return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
- }
- ts.getTextOfNode = getTextOfNode;
- function escapeIdentifier(identifier) {
- return identifier.length >= 2 && identifier.charCodeAt(0) === 95 && identifier.charCodeAt(1) === 95 ? "_" + identifier : identifier;
}
- ts.escapeIdentifier = escapeIdentifier;
- function unescapeIdentifier(identifier) {
- return identifier.length >= 3 && identifier.charCodeAt(0) === 95 && identifier.charCodeAt(1) === 95 && identifier.charCodeAt(2) === 95 ? identifier.substr(1) : identifier;
+ ts.cloneEntityName = cloneEntityName;
+ function nodeIsSynthesized(node) {
+ return node.pos === -1;
}
- ts.unescapeIdentifier = unescapeIdentifier;
- function makeIdentifierFromModuleName(moduleName) {
- return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
+ ts.nodeIsSynthesized = nodeIsSynthesized;
+ function createSynthesizedNode(kind, startsOnNewLine) {
+ var node = ts.createNode(kind, -1, -1);
+ node.startsOnNewLine = startsOnNewLine;
+ return node;
}
- ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
- function isBlockOrCatchScoped(declaration) {
- return (getCombinedNodeFlags(declaration) & 24576) !== 0 ||
- isCatchClauseVariableDeclaration(declaration);
+ ts.createSynthesizedNode = createSynthesizedNode;
+ function createSynthesizedNodeArray() {
+ var array = [];
+ array.pos = -1;
+ array.end = -1;
+ return array;
}
- ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
- function getEnclosingBlockScopeContainer(node) {
- var current = node.parent;
- while (current) {
- if (isFunctionLike(current)) {
- return current;
- }
- switch (current.kind) {
- case 248:
- case 220:
- case 244:
- case 218:
- case 199:
- case 200:
- case 201:
- return current;
- case 192:
- if (!isFunctionLike(current.parent)) {
- return current;
- }
- }
- current = current.parent;
+ ts.createSynthesizedNodeArray = createSynthesizedNodeArray;
+ function createDiagnosticCollection() {
+ var nonFileDiagnostics = [];
+ var fileDiagnostics = {};
+ var diagnosticsModified = false;
+ var modificationCount = 0;
+ return {
+ add: add,
+ getGlobalDiagnostics: getGlobalDiagnostics,
+ getDiagnostics: getDiagnostics,
+ getModificationCount: getModificationCount,
+ reattachFileDiagnostics: reattachFileDiagnostics
+ };
+ function getModificationCount() {
+ return modificationCount;
}
- }
- ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
- function isCatchClauseVariableDeclaration(declaration) {
- return declaration &&
- declaration.kind === 211 &&
- declaration.parent &&
- declaration.parent.kind === 244;
- }
- ts.isCatchClauseVariableDeclaration = isCatchClauseVariableDeclaration;
- function declarationNameToString(name) {
- return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
- }
- ts.declarationNameToString = declarationNameToString;
- function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
- var sourceFile = getSourceFileOfNode(node);
- var span = getErrorSpanForNode(sourceFile, node);
- return ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
- }
- ts.createDiagnosticForNode = createDiagnosticForNode;
- function createDiagnosticForNodeFromMessageChain(node, messageChain) {
- var sourceFile = getSourceFileOfNode(node);
- var span = getErrorSpanForNode(sourceFile, node);
- return {
- file: sourceFile,
- start: span.start,
- length: span.length,
- code: messageChain.code,
- category: messageChain.category,
- messageText: messageChain.next ? messageChain : messageChain.messageText
- };
- }
- ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain;
- function getSpanOfTokenAtPosition(sourceFile, pos) {
- var scanner = ts.createScanner(sourceFile.languageVersion, true, sourceFile.languageVariant, sourceFile.text, undefined, pos);
- scanner.scan();
- var start = scanner.getTokenPos();
- return ts.createTextSpanFromBounds(start, scanner.getTextPos());
- }
- ts.getSpanOfTokenAtPosition = getSpanOfTokenAtPosition;
- function getErrorSpanForNode(sourceFile, node) {
- var errorNode = node;
- switch (node.kind) {
- case 248:
- var pos_1 = ts.skipTrivia(sourceFile.text, 0, false);
- if (pos_1 === sourceFile.text.length) {
- return ts.createTextSpan(0, 0);
+ function reattachFileDiagnostics(newFile) {
+ if (!ts.hasProperty(fileDiagnostics, newFile.fileName)) {
+ return;
+ }
+ for (var _i = 0, _a = fileDiagnostics[newFile.fileName]; _i < _a.length; _i++) {
+ var diagnostic = _a[_i];
+ diagnostic.file = newFile;
+ }
+ }
+ function add(diagnostic) {
+ var diagnostics;
+ if (diagnostic.file) {
+ diagnostics = fileDiagnostics[diagnostic.file.fileName];
+ if (!diagnostics) {
+ diagnostics = [];
+ fileDiagnostics[diagnostic.file.fileName] = diagnostics;
}
- return getSpanOfTokenAtPosition(sourceFile, pos_1);
- case 211:
- case 163:
- case 214:
- case 186:
- case 215:
- case 218:
- case 217:
- case 247:
- case 213:
- case 173:
- errorNode = node.name;
- break;
+ }
+ else {
+ diagnostics = nonFileDiagnostics;
+ }
+ diagnostics.push(diagnostic);
+ diagnosticsModified = true;
+ modificationCount++;
}
- if (errorNode === undefined) {
- return getSpanOfTokenAtPosition(sourceFile, node.pos);
+ function getGlobalDiagnostics() {
+ sortAndDeduplicate();
+ return nonFileDiagnostics;
+ }
+ function getDiagnostics(fileName) {
+ sortAndDeduplicate();
+ if (fileName) {
+ return fileDiagnostics[fileName] || [];
+ }
+ var allDiagnostics = [];
+ function pushDiagnostic(d) {
+ allDiagnostics.push(d);
+ }
+ ts.forEach(nonFileDiagnostics, pushDiagnostic);
+ for (var key in fileDiagnostics) {
+ if (ts.hasProperty(fileDiagnostics, key)) {
+ ts.forEach(fileDiagnostics[key], pushDiagnostic);
+ }
+ }
+ return ts.sortAndDeduplicateDiagnostics(allDiagnostics);
+ }
+ function sortAndDeduplicate() {
+ if (!diagnosticsModified) {
+ return;
+ }
+ diagnosticsModified = false;
+ nonFileDiagnostics = ts.sortAndDeduplicateDiagnostics(nonFileDiagnostics);
+ for (var key in fileDiagnostics) {
+ if (ts.hasProperty(fileDiagnostics, key)) {
+ fileDiagnostics[key] = ts.sortAndDeduplicateDiagnostics(fileDiagnostics[key]);
+ }
+ }
}
- var pos = nodeIsMissing(errorNode)
- ? errorNode.pos
- : ts.skipTrivia(sourceFile.text, errorNode.pos);
- return ts.createTextSpanFromBounds(pos, errorNode.end);
}
- ts.getErrorSpanForNode = getErrorSpanForNode;
- function isExternalModule(file) {
- return file.externalModuleIndicator !== undefined;
+ ts.createDiagnosticCollection = createDiagnosticCollection;
+ var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
+ var escapedCharsMap = {
+ "\0": "\\0",
+ "\t": "\\t",
+ "\v": "\\v",
+ "\f": "\\f",
+ "\b": "\\b",
+ "\r": "\\r",
+ "\n": "\\n",
+ "\\": "\\\\",
+ "\"": "\\\"",
+ "\u2028": "\\u2028",
+ "\u2029": "\\u2029",
+ "\u0085": "\\u0085"
+ };
+ function escapeString(s) {
+ s = escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, getReplacement) : s;
+ return s;
+ function getReplacement(c) {
+ return escapedCharsMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
+ }
}
- ts.isExternalModule = isExternalModule;
- function isDeclarationFile(file) {
- return (file.flags & 4096) !== 0;
+ ts.escapeString = escapeString;
+ function isIntrinsicJsxName(name) {
+ var ch = name.substr(0, 1);
+ return ch.toLowerCase() === ch;
}
- ts.isDeclarationFile = isDeclarationFile;
- function isConstEnumDeclaration(node) {
- return node.kind === 217 && isConst(node);
+ ts.isIntrinsicJsxName = isIntrinsicJsxName;
+ function get16BitUnicodeEscapeSequence(charCode) {
+ var hexCharCode = charCode.toString(16).toUpperCase();
+ var paddedHexCode = ("0000" + hexCharCode).slice(-4);
+ return "\\u" + paddedHexCode;
}
- ts.isConstEnumDeclaration = isConstEnumDeclaration;
- function walkUpBindingElementsAndPatterns(node) {
- while (node && (node.kind === 163 || isBindingPattern(node))) {
- node = node.parent;
+ var nonAsciiCharacters = /[^\u0000-\u007F]/g;
+ function escapeNonAsciiCharacters(s) {
+ return nonAsciiCharacters.test(s) ?
+ s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) :
+ s;
+ }
+ ts.escapeNonAsciiCharacters = escapeNonAsciiCharacters;
+ var indentStrings = ["", " "];
+ function getIndentString(level) {
+ if (indentStrings[level] === undefined) {
+ indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
}
- return node;
+ return indentStrings[level];
}
- function getCombinedNodeFlags(node) {
- node = walkUpBindingElementsAndPatterns(node);
- var flags = node.flags;
- if (node.kind === 211) {
- node = node.parent;
+ ts.getIndentString = getIndentString;
+ function getIndentSize() {
+ return indentStrings[1].length;
+ }
+ ts.getIndentSize = getIndentSize;
+ function createTextWriter(newLine) {
+ var output;
+ var indent;
+ var lineStart;
+ var lineCount;
+ var linePos;
+ function write(s) {
+ if (s && s.length) {
+ if (lineStart) {
+ output += getIndentString(indent);
+ lineStart = false;
+ }
+ output += s;
+ }
}
- if (node && node.kind === 212) {
- flags |= node.flags;
- node = node.parent;
+ function reset() {
+ output = "";
+ indent = 0;
+ lineStart = true;
+ lineCount = 0;
+ linePos = 0;
}
- if (node && node.kind === 193) {
- flags |= node.flags;
+ function rawWrite(s) {
+ if (s !== undefined) {
+ if (lineStart) {
+ lineStart = false;
+ }
+ output += s;
+ }
}
- return flags;
+ function writeLiteral(s) {
+ if (s && s.length) {
+ write(s);
+ var lineStartsOfS = ts.computeLineStarts(s);
+ if (lineStartsOfS.length > 1) {
+ lineCount = lineCount + lineStartsOfS.length - 1;
+ linePos = output.length - s.length + ts.lastOrUndefined(lineStartsOfS);
+ }
+ }
+ }
+ function writeLine() {
+ if (!lineStart) {
+ output += newLine;
+ lineCount++;
+ linePos = output.length;
+ lineStart = true;
+ }
+ }
+ function writeTextOfNode(text, node) {
+ write(getTextOfNodeFromSourceText(text, node));
+ }
+ reset();
+ return {
+ write: write,
+ rawWrite: rawWrite,
+ writeTextOfNode: writeTextOfNode,
+ writeLiteral: writeLiteral,
+ writeLine: writeLine,
+ increaseIndent: function () { return indent++; },
+ decreaseIndent: function () { return indent--; },
+ getIndent: function () { return indent; },
+ getTextPos: function () { return output.length; },
+ getLine: function () { return lineCount + 1; },
+ getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; },
+ getText: function () { return output; },
+ reset: reset
+ };
}
- ts.getCombinedNodeFlags = getCombinedNodeFlags;
- function isConst(node) {
- return !!(getCombinedNodeFlags(node) & 16384);
+ ts.createTextWriter = createTextWriter;
+ function getExternalModuleNameFromPath(host, fileName) {
+ var dir = host.getCurrentDirectory();
+ var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, fileName, dir, function (f) { return host.getCanonicalFileName(f); }, false);
+ return ts.removeFileExtension(relativePath);
}
- ts.isConst = isConst;
- function isLet(node) {
- return !!(getCombinedNodeFlags(node) & 8192);
+ ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
+ function getOwnEmitOutputFilePath(sourceFile, host, extension) {
+ var compilerOptions = host.getCompilerOptions();
+ var emitOutputFilePathWithoutExtension;
+ if (compilerOptions.outDir) {
+ emitOutputFilePathWithoutExtension = ts.removeFileExtension(getSourceFilePathInNewDir(sourceFile, host, compilerOptions.outDir));
+ }
+ else {
+ emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
+ }
+ return emitOutputFilePathWithoutExtension + extension;
}
- ts.isLet = isLet;
- function isPrologueDirective(node) {
- return node.kind === 195 && node.expression.kind === 9;
+ ts.getOwnEmitOutputFilePath = getOwnEmitOutputFilePath;
+ function getSourceFilePathInNewDir(sourceFile, host, newDirPath) {
+ var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, host.getCurrentDirectory());
+ sourceFilePath = sourceFilePath.replace(host.getCommonSourceDirectory(), "");
+ return ts.combinePaths(newDirPath, sourceFilePath);
}
- ts.isPrologueDirective = isPrologueDirective;
- function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
- return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
+ ts.getSourceFilePathInNewDir = getSourceFilePathInNewDir;
+ function writeFile(host, diagnostics, fileName, data, writeByteOrderMark) {
+ host.writeFile(fileName, data, writeByteOrderMark, function (hostErrorMessage) {
+ diagnostics.push(ts.createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
+ });
}
- ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
- function getJsDocComments(node, sourceFileOfNode) {
- var commentRanges = (node.kind === 138 || node.kind === 137) ?
- ts.concatenate(ts.getTrailingCommentRanges(sourceFileOfNode.text, node.pos), ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) :
- getLeadingCommentRangesOfNode(node, sourceFileOfNode);
- return ts.filter(commentRanges, isJsDocComment);
- function isJsDocComment(comment) {
- return sourceFileOfNode.text.charCodeAt(comment.pos + 1) === 42 &&
- sourceFileOfNode.text.charCodeAt(comment.pos + 2) === 42 &&
- sourceFileOfNode.text.charCodeAt(comment.pos + 3) !== 47;
- }
+ ts.writeFile = writeFile;
+ function getLineOfLocalPosition(currentSourceFile, pos) {
+ return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line;
}
- ts.getJsDocComments = getJsDocComments;
- ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/;
- ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/;
- function isTypeNode(node) {
- if (151 <= node.kind && node.kind <= 160) {
- return true;
- }
- switch (node.kind) {
- case 117:
- case 128:
- case 130:
- case 120:
- case 131:
- return true;
- case 103:
- return node.parent.kind !== 177;
- case 9:
- return node.parent.kind === 138;
- case 188:
- return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
- case 69:
- if (node.parent.kind === 135 && node.parent.right === node) {
- node = node.parent;
- }
- else if (node.parent.kind === 166 && node.parent.name === node) {
- node = node.parent;
- }
- ts.Debug.assert(node.kind === 69 || node.kind === 135 || node.kind === 166, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'.");
- case 135:
- case 166:
- case 97:
- var parent_1 = node.parent;
- if (parent_1.kind === 154) {
- return false;
- }
- if (151 <= parent_1.kind && parent_1.kind <= 160) {
- return true;
- }
- switch (parent_1.kind) {
- case 188:
- return !isExpressionWithTypeArgumentsInClassExtendsClause(parent_1);
- case 137:
- return node === parent_1.constraint;
- case 141:
- case 140:
- case 138:
- case 211:
- return node === parent_1.type;
- case 213:
- case 173:
- case 174:
- case 144:
- case 143:
- case 142:
- case 145:
- case 146:
- return node === parent_1.type;
- case 147:
- case 148:
- case 149:
- return node === parent_1.type;
- case 171:
- return node === parent_1.type;
- case 168:
- case 169:
- return parent_1.typeArguments && ts.indexOf(parent_1.typeArguments, node) >= 0;
- case 170:
- return false;
- }
+ ts.getLineOfLocalPosition = getLineOfLocalPosition;
+ function getLineOfLocalPositionFromLineMap(lineMap, pos) {
+ return ts.computeLineAndCharacterOfPosition(lineMap, pos).line;
+ }
+ ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
+ function getFirstConstructorWithBody(node) {
+ return ts.forEach(node.members, function (member) {
+ if (member.kind === 144 && nodeIsPresent(member.body)) {
+ return member;
+ }
+ });
+ }
+ ts.getFirstConstructorWithBody = getFirstConstructorWithBody;
+ function getSetAccessorTypeAnnotationNode(accessor) {
+ return accessor && accessor.parameters.length > 0 && accessor.parameters[0].type;
+ }
+ ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode;
+ function shouldEmitToOwnFile(sourceFile, compilerOptions) {
+ if (!isDeclarationFile(sourceFile)) {
+ if ((isExternalModule(sourceFile) || !(compilerOptions.outFile || compilerOptions.out))) {
+ return compilerOptions.isolatedModules || !ts.fileExtensionIs(sourceFile.fileName, ".js");
+ }
+ return false;
}
return false;
}
- ts.isTypeNode = isTypeNode;
- function forEachReturnStatement(body, visitor) {
- return traverse(body);
- function traverse(node) {
- switch (node.kind) {
- case 204:
- return visitor(node);
- case 220:
- case 192:
- case 196:
- case 197:
- case 198:
- case 199:
- case 200:
- case 201:
- case 205:
- case 206:
- case 241:
- case 242:
- case 207:
- case 209:
- case 244:
- return ts.forEachChild(node, traverse);
+ ts.shouldEmitToOwnFile = shouldEmitToOwnFile;
+ function getAllAccessorDeclarations(declarations, accessor) {
+ var firstAccessor;
+ var secondAccessor;
+ var getAccessor;
+ var setAccessor;
+ if (hasDynamicName(accessor)) {
+ firstAccessor = accessor;
+ if (accessor.kind === 145) {
+ getAccessor = accessor;
+ }
+ else if (accessor.kind === 146) {
+ setAccessor = accessor;
+ }
+ else {
+ ts.Debug.fail("Accessor has wrong kind");
}
}
- }
- ts.forEachReturnStatement = forEachReturnStatement;
- function forEachYieldExpression(body, visitor) {
- return traverse(body);
- function traverse(node) {
- switch (node.kind) {
- case 184:
- visitor(node);
- var operand = node.expression;
- if (operand) {
- traverse(operand);
- }
- case 217:
- case 215:
- case 218:
- case 216:
- case 214:
- case 186:
- return;
- default:
- if (isFunctionLike(node)) {
- var name_5 = node.name;
- if (name_5 && name_5.kind === 136) {
- traverse(name_5.expression);
- return;
+ else {
+ ts.forEach(declarations, function (member) {
+ if ((member.kind === 145 || member.kind === 146)
+ && (member.flags & 64) === (accessor.flags & 64)) {
+ var memberName = getPropertyNameForPropertyNameNode(member.name);
+ var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
+ if (memberName === accessorName) {
+ if (!firstAccessor) {
+ firstAccessor = member;
+ }
+ else if (!secondAccessor) {
+ secondAccessor = member;
+ }
+ if (member.kind === 145 && !getAccessor) {
+ getAccessor = member;
+ }
+ if (member.kind === 146 && !setAccessor) {
+ setAccessor = member;
}
}
- else if (!isTypeNode(node)) {
- ts.forEachChild(node, traverse);
- }
- }
+ }
+ });
}
+ return {
+ firstAccessor: firstAccessor,
+ secondAccessor: secondAccessor,
+ getAccessor: getAccessor,
+ setAccessor: setAccessor
+ };
}
- ts.forEachYieldExpression = forEachYieldExpression;
- function isVariableLike(node) {
- if (node) {
- switch (node.kind) {
- case 163:
- case 247:
- case 138:
- case 245:
- case 141:
- case 140:
- case 246:
- case 211:
- return true;
- }
+ ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
+ function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
+ if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
+ getLineOfLocalPositionFromLineMap(lineMap, node.pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
+ writer.writeLine();
}
- return false;
- }
- ts.isVariableLike = isVariableLike;
- function isAccessor(node) {
- return node && (node.kind === 145 || node.kind === 146);
- }
- ts.isAccessor = isAccessor;
- function isClassLike(node) {
- return node && (node.kind === 214 || node.kind === 186);
}
- ts.isClassLike = isClassLike;
- function isFunctionLike(node) {
- return node && isFunctionLikeKind(node.kind);
+ ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
+ function emitComments(text, lineMap, writer, comments, trailingSeparator, newLine, writeComment) {
+ var emitLeadingSpace = !trailingSeparator;
+ ts.forEach(comments, function (comment) {
+ if (emitLeadingSpace) {
+ writer.write(" ");
+ emitLeadingSpace = false;
+ }
+ writeComment(text, lineMap, writer, comment, newLine);
+ if (comment.hasTrailingNewLine) {
+ writer.writeLine();
+ }
+ else if (trailingSeparator) {
+ writer.write(" ");
+ }
+ else {
+ emitLeadingSpace = true;
+ }
+ });
}
- ts.isFunctionLike = isFunctionLike;
- function isFunctionLikeKind(kind) {
- switch (kind) {
- case 144:
- case 173:
- case 213:
- case 174:
- case 143:
- case 142:
- case 145:
- case 146:
- case 147:
- case 148:
- case 149:
- case 152:
- case 153:
- return true;
+ ts.emitComments = emitComments;
+ function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
+ var leadingComments;
+ var currentDetachedCommentInfo;
+ if (removeComments) {
+ if (node.pos === 0) {
+ leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment);
+ }
}
- }
- ts.isFunctionLikeKind = isFunctionLikeKind;
- function introducesArgumentsExoticObject(node) {
- switch (node.kind) {
- case 143:
- case 142:
- case 144:
- case 145:
- case 146:
- case 213:
- case 173:
- return true;
+ else {
+ leadingComments = ts.getLeadingCommentRanges(text, node.pos);
}
- return false;
- }
- ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject;
- function isIterationStatement(node, lookInLabeledStatements) {
- switch (node.kind) {
- case 199:
- case 200:
- case 201:
- case 197:
- case 198:
- return true;
- case 207:
- return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
+ if (leadingComments) {
+ var detachedComments = [];
+ var lastComment;
+ for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
+ var comment = leadingComments_1[_i];
+ if (lastComment) {
+ var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
+ var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
+ if (commentLine >= lastCommentLine + 2) {
+ break;
+ }
+ }
+ detachedComments.push(comment);
+ lastComment = comment;
+ }
+ if (detachedComments.length) {
+ var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.lastOrUndefined(detachedComments).end);
+ var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
+ if (nodeLine >= lastCommentLine + 2) {
+ emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
+ emitComments(text, lineMap, writer, detachedComments, true, newLine, writeComment);
+ currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end };
+ }
+ }
+ }
+ return currentDetachedCommentInfo;
+ function isPinnedComment(comment) {
+ return text.charCodeAt(comment.pos + 1) === 42 &&
+ text.charCodeAt(comment.pos + 2) === 33;
}
- return false;
- }
- ts.isIterationStatement = isIterationStatement;
- function isFunctionBlock(node) {
- return node && node.kind === 192 && isFunctionLike(node.parent);
- }
- ts.isFunctionBlock = isFunctionBlock;
- function isObjectLiteralMethod(node) {
- return node && node.kind === 143 && node.parent.kind === 165;
}
- ts.isObjectLiteralMethod = isObjectLiteralMethod;
- function getContainingFunction(node) {
- while (true) {
- node = node.parent;
- if (!node || isFunctionLike(node)) {
- return node;
+ ts.emitDetachedComments = emitDetachedComments;
+ function writeCommentRange(text, lineMap, writer, comment, newLine) {
+ if (text.charCodeAt(comment.pos + 1) === 42) {
+ var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, comment.pos);
+ var lineCount = lineMap.length;
+ var firstCommentLineIndent;
+ for (var pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
+ var nextLineStart = (currentLine + 1) === lineCount
+ ? text.length + 1
+ : lineMap[currentLine + 1];
+ if (pos !== comment.pos) {
+ if (firstCommentLineIndent === undefined) {
+ firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], comment.pos);
+ }
+ var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
+ var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
+ if (spacesToEmit > 0) {
+ var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
+ var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
+ writer.rawWrite(indentSizeSpaceString);
+ while (numberOfSingleSpacesToEmit) {
+ writer.rawWrite(" ");
+ numberOfSingleSpacesToEmit--;
+ }
+ }
+ else {
+ writer.rawWrite("");
+ }
+ }
+ writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart);
+ pos = nextLineStart;
}
}
+ else {
+ writer.write(text.substring(comment.pos, comment.end));
+ }
}
- ts.getContainingFunction = getContainingFunction;
- function getContainingClass(node) {
- while (true) {
- node = node.parent;
- if (!node || isClassLike(node)) {
- return node;
+ ts.writeCommentRange = writeCommentRange;
+ function writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart) {
+ var end = Math.min(comment.end, nextLineStart - 1);
+ var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
+ if (currentLineText) {
+ writer.write(currentLineText);
+ if (end !== comment.end) {
+ writer.writeLine();
}
}
+ else {
+ writer.writeLiteral(newLine);
+ }
}
- ts.getContainingClass = getContainingClass;
- function getThisContainer(node, includeArrowFunctions) {
- while (true) {
- node = node.parent;
- if (!node) {
- return undefined;
+ function calculateIndent(text, pos, end) {
+ var currentLineIndent = 0;
+ for (; pos < end && ts.isWhiteSpace(text.charCodeAt(pos)); pos++) {
+ if (text.charCodeAt(pos) === 9) {
+ currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
}
- switch (node.kind) {
- case 136:
- if (isClassLike(node.parent.parent)) {
- return node;
- }
- node = node.parent;
- break;
- case 139:
- if (node.parent.kind === 138 && isClassElement(node.parent.parent)) {
- node = node.parent.parent;
- }
- else if (isClassElement(node.parent)) {
- node = node.parent;
- }
- break;
- case 174:
- if (!includeArrowFunctions) {
- continue;
- }
- case 213:
- case 173:
- case 218:
- case 141:
- case 140:
- case 143:
- case 142:
- case 144:
- case 145:
- case 146:
- case 147:
- case 148:
- case 149:
- case 217:
- case 248:
- return node;
+ else {
+ currentLineIndent++;
}
}
+ return currentLineIndent;
}
- ts.getThisContainer = getThisContainer;
- function getSuperContainer(node, includeFunctions) {
- while (true) {
- node = node.parent;
- if (!node)
- return node;
- switch (node.kind) {
- case 136:
- if (isClassLike(node.parent.parent)) {
- return node;
- }
- node = node.parent;
- break;
- case 139:
- if (node.parent.kind === 138 && isClassElement(node.parent.parent)) {
- node = node.parent.parent;
- }
- else if (isClassElement(node.parent)) {
- node = node.parent;
- }
- break;
- case 213:
- case 173:
- case 174:
- if (!includeFunctions) {
- continue;
- }
- case 141:
- case 140:
- case 143:
- case 142:
- case 144:
- case 145:
- case 146:
- return node;
- }
+ function modifierToFlag(token) {
+ switch (token) {
+ case 113: return 64;
+ case 112: return 8;
+ case 111: return 32;
+ case 110: return 16;
+ case 115: return 128;
+ case 82: return 2;
+ case 122: return 4;
+ case 74: return 16384;
+ case 77: return 512;
+ case 118: return 256;
}
+ return 0;
}
- ts.getSuperContainer = getSuperContainer;
- function getEntityNameFromTypeNode(node) {
- if (node) {
- switch (node.kind) {
- case 151:
- return node.typeName;
- case 188:
- return node.expression;
+ ts.modifierToFlag = modifierToFlag;
+ function isLeftHandSideExpression(expr) {
+ if (expr) {
+ switch (expr.kind) {
+ case 166:
+ case 167:
+ case 169:
+ case 168:
+ case 233:
+ case 234:
+ case 170:
+ case 164:
+ case 172:
+ case 165:
+ case 186:
+ case 173:
case 69:
- case 135:
- return node;
+ case 10:
+ case 8:
+ case 9:
+ case 11:
+ case 183:
+ case 84:
+ case 93:
+ case 97:
+ case 99:
+ case 95:
+ return true;
}
}
- return undefined;
+ return false;
}
- ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode;
- function getInvokedExpression(node) {
- if (node.kind === 170) {
- return node.tag;
- }
- return node.expression;
+ ts.isLeftHandSideExpression = isLeftHandSideExpression;
+ function isAssignmentOperator(token) {
+ return token >= 56 && token <= 68;
}
- ts.getInvokedExpression = getInvokedExpression;
- function nodeCanBeDecorated(node) {
- switch (node.kind) {
- case 214:
- return true;
- case 141:
- return node.parent.kind === 214;
- case 138:
- return node.parent.body && node.parent.parent.kind === 214;
- case 145:
- case 146:
- case 143:
- return node.body && node.parent.kind === 214;
- }
- return false;
+ ts.isAssignmentOperator = isAssignmentOperator;
+ function isExpressionWithTypeArgumentsInClassExtendsClause(node) {
+ return node.kind === 188 &&
+ node.parent.token === 83 &&
+ isClassLike(node.parent.parent);
}
- ts.nodeCanBeDecorated = nodeCanBeDecorated;
- function nodeIsDecorated(node) {
- switch (node.kind) {
- case 214:
- if (node.decorators) {
- return true;
- }
- return false;
- case 141:
- case 138:
- if (node.decorators) {
- return true;
- }
- return false;
- case 145:
- if (node.body && node.decorators) {
- return true;
- }
- return false;
- case 143:
- case 146:
- if (node.body && node.decorators) {
- return true;
- }
- return false;
- }
- return false;
+ ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause;
+ function isSupportedExpressionWithTypeArguments(node) {
+ return isSupportedExpressionWithTypeArgumentsRest(node.expression);
}
- ts.nodeIsDecorated = nodeIsDecorated;
- function childIsDecorated(node) {
- switch (node.kind) {
- case 214:
- return ts.forEach(node.members, nodeOrChildIsDecorated);
- case 143:
- case 146:
- return ts.forEach(node.parameters, nodeIsDecorated);
+ ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments;
+ function isSupportedExpressionWithTypeArgumentsRest(node) {
+ if (node.kind === 69) {
+ return true;
+ }
+ else if (isPropertyAccessExpression(node)) {
+ return isSupportedExpressionWithTypeArgumentsRest(node.expression);
+ }
+ else {
+ return false;
}
- return false;
- }
- ts.childIsDecorated = childIsDecorated;
- function nodeOrChildIsDecorated(node) {
- return nodeIsDecorated(node) || childIsDecorated(node);
- }
- ts.nodeOrChildIsDecorated = nodeOrChildIsDecorated;
- function isPropertyAccessExpression(node) {
- return node.kind === 166;
}
- ts.isPropertyAccessExpression = isPropertyAccessExpression;
- function isElementAccessExpression(node) {
- return node.kind === 167;
+ function isRightSideOfQualifiedNameOrPropertyAccess(node) {
+ return (node.parent.kind === 135 && node.parent.right === node) ||
+ (node.parent.kind === 166 && node.parent.name === node);
}
- ts.isElementAccessExpression = isElementAccessExpression;
- function isExpression(node) {
- switch (node.kind) {
- case 95:
- case 93:
- case 99:
- case 84:
- case 10:
- case 164:
- case 165:
- case 166:
- case 167:
- case 168:
- case 169:
- case 170:
- case 189:
- case 171:
- case 172:
- case 173:
- case 186:
- case 174:
- case 177:
- case 175:
- case 176:
- case 179:
- case 180:
- case 181:
- case 182:
- case 185:
- case 183:
- case 11:
- case 187:
- case 233:
- case 234:
- case 184:
- case 178:
- return true;
- case 135:
- while (node.parent.kind === 135) {
- node = node.parent;
- }
- return node.parent.kind === 154;
- case 69:
- if (node.parent.kind === 154) {
- return true;
- }
- case 8:
- case 9:
- case 97:
- var parent_2 = node.parent;
- switch (parent_2.kind) {
- case 211:
- case 138:
- case 141:
- case 140:
- case 247:
- case 245:
- case 163:
- return parent_2.initializer === node;
- case 195:
- case 196:
- case 197:
- case 198:
- case 204:
- case 205:
- case 206:
- case 241:
- case 208:
- case 206:
- return parent_2.expression === node;
- case 199:
- var forStatement = parent_2;
- return (forStatement.initializer === node && forStatement.initializer.kind !== 212) ||
- forStatement.condition === node ||
- forStatement.incrementor === node;
- case 200:
- case 201:
- var forInStatement = parent_2;
- return (forInStatement.initializer === node && forInStatement.initializer.kind !== 212) ||
- forInStatement.expression === node;
- case 171:
- case 189:
- return node === parent_2.expression;
- case 190:
- return node === parent_2.expression;
- case 136:
- return node === parent_2.expression;
- case 139:
- case 240:
- case 239:
- return true;
- case 188:
- return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2);
- default:
- if (isExpression(parent_2)) {
- return true;
- }
- }
+ ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess;
+ function isEmptyObjectLiteralOrArrayLiteral(expression) {
+ var kind = expression.kind;
+ if (kind === 165) {
+ return expression.properties.length === 0;
+ }
+ if (kind === 164) {
+ return expression.elements.length === 0;
}
return false;
}
- ts.isExpression = isExpression;
- function isExternalModuleNameRelative(moduleName) {
- return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\";
- }
- ts.isExternalModuleNameRelative = isExternalModuleNameRelative;
- function isInstantiatedModule(node, preserveConstEnums) {
- var moduleState = ts.getModuleInstanceState(node);
- return moduleState === 1 ||
- (preserveConstEnums && moduleState === 2);
- }
- ts.isInstantiatedModule = isInstantiatedModule;
- function isExternalModuleImportEqualsDeclaration(node) {
- return node.kind === 221 && node.moduleReference.kind === 232;
+ ts.isEmptyObjectLiteralOrArrayLiteral = isEmptyObjectLiteralOrArrayLiteral;
+ function getLocalSymbolForExportDefault(symbol) {
+ return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 512) ? symbol.valueDeclaration.localSymbol : undefined;
}
- ts.isExternalModuleImportEqualsDeclaration = isExternalModuleImportEqualsDeclaration;
- function getExternalModuleImportEqualsDeclarationExpression(node) {
- ts.Debug.assert(isExternalModuleImportEqualsDeclaration(node));
- return node.moduleReference.expression;
+ ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
+ function hasJavaScriptFileExtension(fileName) {
+ return ts.fileExtensionIs(fileName, ".js") || ts.fileExtensionIs(fileName, ".jsx");
}
- ts.getExternalModuleImportEqualsDeclarationExpression = getExternalModuleImportEqualsDeclarationExpression;
- function isInternalModuleImportEqualsDeclaration(node) {
- return node.kind === 221 && node.moduleReference.kind !== 232;
+ ts.hasJavaScriptFileExtension = hasJavaScriptFileExtension;
+ function allowsJsxExpressions(fileName) {
+ return ts.fileExtensionIs(fileName, ".tsx") || ts.fileExtensionIs(fileName, ".jsx");
}
- ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
- function getExternalModuleName(node) {
- if (node.kind === 222) {
- return node.moduleSpecifier;
- }
- if (node.kind === 221) {
- var reference = node.moduleReference;
- if (reference.kind === 232) {
- return reference.expression;
+ ts.allowsJsxExpressions = allowsJsxExpressions;
+ function getExpandedCharCodes(input) {
+ var output = [];
+ var length = input.length;
+ for (var i = 0; i < length; i++) {
+ var charCode = input.charCodeAt(i);
+ if (charCode < 0x80) {
+ output.push(charCode);
+ }
+ else if (charCode < 0x800) {
+ output.push((charCode >> 6) | 192);
+ output.push((charCode & 63) | 128);
+ }
+ else if (charCode < 0x10000) {
+ output.push((charCode >> 12) | 224);
+ output.push(((charCode >> 6) & 63) | 128);
+ output.push((charCode & 63) | 128);
+ }
+ else if (charCode < 0x20000) {
+ output.push((charCode >> 18) | 240);
+ output.push(((charCode >> 12) & 63) | 128);
+ output.push(((charCode >> 6) & 63) | 128);
+ output.push((charCode & 63) | 128);
+ }
+ else {
+ ts.Debug.assert(false, "Unexpected code point");
}
}
- if (node.kind === 228) {
- return node.moduleSpecifier;
- }
+ return output;
}
- ts.getExternalModuleName = getExternalModuleName;
- function hasQuestionToken(node) {
- if (node) {
- switch (node.kind) {
- case 138:
- case 143:
- case 142:
- case 246:
- case 245:
- case 141:
- case 140:
- return node.questionToken !== undefined;
+ var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ function convertToBase64(input) {
+ var result = "";
+ var charCodes = getExpandedCharCodes(input);
+ var i = 0;
+ var length = charCodes.length;
+ var byte1, byte2, byte3, byte4;
+ while (i < length) {
+ byte1 = charCodes[i] >> 2;
+ byte2 = (charCodes[i] & 3) << 4 | charCodes[i + 1] >> 4;
+ byte3 = (charCodes[i + 1] & 15) << 2 | charCodes[i + 2] >> 6;
+ byte4 = charCodes[i + 2] & 63;
+ if (i + 1 >= length) {
+ byte3 = byte4 = 64;
}
+ else if (i + 2 >= length) {
+ byte4 = 64;
+ }
+ result += base64Digits.charAt(byte1) + base64Digits.charAt(byte2) + base64Digits.charAt(byte3) + base64Digits.charAt(byte4);
+ i += 3;
}
- return false;
+ return result;
}
- ts.hasQuestionToken = hasQuestionToken;
- function isJSDocConstructSignature(node) {
- return node.kind === 261 &&
- node.parameters.length > 0 &&
- node.parameters[0].type.kind === 263;
+ ts.convertToBase64 = convertToBase64;
+ function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) {
+ return !ts.isRootedDiskPath(absoluteOrRelativePath)
+ ? absoluteOrRelativePath
+ : ts.getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, false);
}
- ts.isJSDocConstructSignature = isJSDocConstructSignature;
- function getJSDocTag(node, kind) {
- if (node && node.jsDocComment) {
- for (var _i = 0, _a = node.jsDocComment.tags; _i < _a.length; _i++) {
- var tag = _a[_i];
- if (tag.kind === kind) {
- return tag;
- }
- }
+ ts.convertToRelativePath = convertToRelativePath;
+ var carriageReturnLineFeed = "\r\n";
+ var lineFeed = "\n";
+ function getNewLineCharacter(options) {
+ if (options.newLine === 0) {
+ return carriageReturnLineFeed;
+ }
+ else if (options.newLine === 1) {
+ return lineFeed;
+ }
+ else if (ts.sys) {
+ return ts.sys.newLine;
}
+ return carriageReturnLineFeed;
}
- function getJSDocTypeTag(node) {
- return getJSDocTag(node, 269);
+ ts.getNewLineCharacter = getNewLineCharacter;
+})(ts || (ts = {}));
+var ts;
+(function (ts) {
+ function getDefaultLibFileName(options) {
+ return options.target === 2 ? "lib.es6.d.ts" : "lib.d.ts";
}
- ts.getJSDocTypeTag = getJSDocTypeTag;
- function getJSDocReturnTag(node) {
- return getJSDocTag(node, 268);
+ ts.getDefaultLibFileName = getDefaultLibFileName;
+ function textSpanEnd(span) {
+ return span.start + span.length;
}
- ts.getJSDocReturnTag = getJSDocReturnTag;
- function getJSDocTemplateTag(node) {
- return getJSDocTag(node, 270);
+ ts.textSpanEnd = textSpanEnd;
+ function textSpanIsEmpty(span) {
+ return span.length === 0;
}
- ts.getJSDocTemplateTag = getJSDocTemplateTag;
- function getCorrespondingJSDocParameterTag(parameter) {
- if (parameter.name && parameter.name.kind === 69) {
- var parameterName = parameter.name.text;
- var docComment = parameter.parent.jsDocComment;
- if (docComment) {
- return ts.forEach(docComment.tags, function (t) {
- if (t.kind === 267) {
- var parameterTag = t;
- var name_6 = parameterTag.preParameterName || parameterTag.postParameterName;
- if (name_6.text === parameterName) {
- return t;
- }
- }
- });
- }
- }
+ ts.textSpanIsEmpty = textSpanIsEmpty;
+ function textSpanContainsPosition(span, position) {
+ return position >= span.start && position < textSpanEnd(span);
}
- ts.getCorrespondingJSDocParameterTag = getCorrespondingJSDocParameterTag;
- function hasRestParameter(s) {
- return isRestParameter(ts.lastOrUndefined(s.parameters));
+ ts.textSpanContainsPosition = textSpanContainsPosition;
+ function textSpanContainsTextSpan(span, other) {
+ return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span);
}
- ts.hasRestParameter = hasRestParameter;
- function isRestParameter(node) {
- if (node) {
- if (node.parserContextFlags & 32) {
- if (node.type && node.type.kind === 262) {
- return true;
- }
- var paramTag = getCorrespondingJSDocParameterTag(node);
- if (paramTag && paramTag.typeExpression) {
- return paramTag.typeExpression.type.kind === 262;
- }
- }
- return node.dotDotDotToken !== undefined;
+ ts.textSpanContainsTextSpan = textSpanContainsTextSpan;
+ function textSpanOverlapsWith(span, other) {
+ var overlapStart = Math.max(span.start, other.start);
+ var overlapEnd = Math.min(textSpanEnd(span), textSpanEnd(other));
+ return overlapStart < overlapEnd;
+ }
+ ts.textSpanOverlapsWith = textSpanOverlapsWith;
+ function textSpanOverlap(span1, span2) {
+ var overlapStart = Math.max(span1.start, span2.start);
+ var overlapEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
+ if (overlapStart < overlapEnd) {
+ return createTextSpanFromBounds(overlapStart, overlapEnd);
}
- return false;
+ return undefined;
}
- ts.isRestParameter = isRestParameter;
- function isLiteralKind(kind) {
- return 8 <= kind && kind <= 11;
+ ts.textSpanOverlap = textSpanOverlap;
+ function textSpanIntersectsWithTextSpan(span, other) {
+ return other.start <= textSpanEnd(span) && textSpanEnd(other) >= span.start;
}
- ts.isLiteralKind = isLiteralKind;
- function isTextualLiteralKind(kind) {
- return kind === 9 || kind === 11;
+ ts.textSpanIntersectsWithTextSpan = textSpanIntersectsWithTextSpan;
+ function textSpanIntersectsWith(span, start, length) {
+ var end = start + length;
+ return start <= textSpanEnd(span) && end >= span.start;
}
- ts.isTextualLiteralKind = isTextualLiteralKind;
- function isTemplateLiteralKind(kind) {
- return 11 <= kind && kind <= 14;
+ ts.textSpanIntersectsWith = textSpanIntersectsWith;
+ function decodedTextSpanIntersectsWith(start1, length1, start2, length2) {
+ var end1 = start1 + length1;
+ var end2 = start2 + length2;
+ return start2 <= end1 && end2 >= start1;
}
- ts.isTemplateLiteralKind = isTemplateLiteralKind;
- function isBindingPattern(node) {
- return !!node && (node.kind === 162 || node.kind === 161);
+ ts.decodedTextSpanIntersectsWith = decodedTextSpanIntersectsWith;
+ function textSpanIntersectsWithPosition(span, position) {
+ return position <= textSpanEnd(span) && position >= span.start;
}
- ts.isBindingPattern = isBindingPattern;
- function isNodeDescendentOf(node, ancestor) {
- while (node) {
- if (node === ancestor)
- return true;
- node = node.parent;
+ ts.textSpanIntersectsWithPosition = textSpanIntersectsWithPosition;
+ function textSpanIntersection(span1, span2) {
+ var intersectStart = Math.max(span1.start, span2.start);
+ var intersectEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
+ if (intersectStart <= intersectEnd) {
+ return createTextSpanFromBounds(intersectStart, intersectEnd);
}
- return false;
+ return undefined;
}
- ts.isNodeDescendentOf = isNodeDescendentOf;
- function isInAmbientContext(node) {
- while (node) {
- if (node.flags & (4 | 4096)) {
- return true;
- }
- node = node.parent;
+ ts.textSpanIntersection = textSpanIntersection;
+ function createTextSpan(start, length) {
+ if (start < 0) {
+ throw new Error("start < 0");
}
- return false;
- }
- ts.isInAmbientContext = isInAmbientContext;
- function isDeclaration(node) {
- switch (node.kind) {
- case 174:
- case 163:
- case 214:
- case 186:
- case 144:
- case 217:
- case 247:
- case 230:
- case 213:
- case 173:
- case 145:
- case 223:
- case 221:
- case 226:
- case 215:
- case 143:
- case 142:
- case 218:
- case 224:
- case 138:
- case 245:
- case 141:
- case 140:
- case 146:
- case 246:
- case 216:
- case 137:
- case 211:
- return true;
+ if (length < 0) {
+ throw new Error("length < 0");
}
- return false;
+ return { start: start, length: length };
}
- ts.isDeclaration = isDeclaration;
- function isStatement(n) {
- switch (n.kind) {
- case 203:
- case 202:
- case 210:
- case 197:
- case 195:
- case 194:
- case 200:
- case 201:
- case 199:
- case 196:
- case 207:
- case 204:
- case 206:
- case 208:
- case 209:
- case 193:
- case 198:
- case 205:
- case 227:
- return true;
- default:
- return false;
- }
+ ts.createTextSpan = createTextSpan;
+ function createTextSpanFromBounds(start, end) {
+ return createTextSpan(start, end - start);
}
- ts.isStatement = isStatement;
- function isClassElement(n) {
- switch (n.kind) {
- case 144:
- case 141:
- case 143:
- case 145:
- case 146:
- case 142:
- case 149:
- return true;
- default:
- return false;
- }
+ ts.createTextSpanFromBounds = createTextSpanFromBounds;
+ function textChangeRangeNewSpan(range) {
+ return createTextSpan(range.span.start, range.newLength);
}
- ts.isClassElement = isClassElement;
- function isDeclarationName(name) {
- if (name.kind !== 69 && name.kind !== 9 && name.kind !== 8) {
- return false;
- }
- var parent = name.parent;
- if (parent.kind === 226 || parent.kind === 230) {
- if (parent.propertyName) {
- return true;
- }
- }
- if (isDeclaration(parent)) {
- return parent.name === name;
- }
- return false;
+ ts.textChangeRangeNewSpan = textChangeRangeNewSpan;
+ function textChangeRangeIsUnchanged(range) {
+ return textSpanIsEmpty(range.span) && range.newLength === 0;
}
- ts.isDeclarationName = isDeclarationName;
- function isIdentifierName(node) {
- var parent = node.parent;
- switch (parent.kind) {
- case 141:
- case 140:
- case 143:
- case 142:
- case 145:
- case 146:
- case 247:
- case 245:
- case 166:
- return parent.name === node;
- case 135:
- if (parent.right === node) {
- while (parent.kind === 135) {
- parent = parent.parent;
- }
- return parent.kind === 154;
- }
- return false;
- case 163:
- case 226:
- return parent.propertyName === node;
- case 230:
- return true;
+ ts.textChangeRangeIsUnchanged = textChangeRangeIsUnchanged;
+ function createTextChangeRange(span, newLength) {
+ if (newLength < 0) {
+ throw new Error("newLength < 0");
}
- return false;
- }
- ts.isIdentifierName = isIdentifierName;
- function isAliasSymbolDeclaration(node) {
- return node.kind === 221 ||
- node.kind === 223 && !!node.name ||
- node.kind === 224 ||
- node.kind === 226 ||
- node.kind === 230 ||
- node.kind === 227 && node.expression.kind === 69;
- }
- ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration;
- function getClassExtendsHeritageClauseElement(node) {
- var heritageClause = getHeritageClause(node.heritageClauses, 83);
- return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
- }
- ts.getClassExtendsHeritageClauseElement = getClassExtendsHeritageClauseElement;
- function getClassImplementsHeritageClauseElements(node) {
- var heritageClause = getHeritageClause(node.heritageClauses, 106);
- return heritageClause ? heritageClause.types : undefined;
- }
- ts.getClassImplementsHeritageClauseElements = getClassImplementsHeritageClauseElements;
- function getInterfaceBaseTypeNodes(node) {
- var heritageClause = getHeritageClause(node.heritageClauses, 83);
- return heritageClause ? heritageClause.types : undefined;
+ return { span: span, newLength: newLength };
}
- ts.getInterfaceBaseTypeNodes = getInterfaceBaseTypeNodes;
- function getHeritageClause(clauses, kind) {
- if (clauses) {
- for (var _i = 0, clauses_1 = clauses; _i < clauses_1.length; _i++) {
- var clause = clauses_1[_i];
- if (clause.token === kind) {
- return clause;
- }
- }
+ ts.createTextChangeRange = createTextChangeRange;
+ ts.unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0);
+ function collapseTextChangeRangesAcrossMultipleVersions(changes) {
+ if (changes.length === 0) {
+ return ts.unchangedTextChangeRange;
}
- return undefined;
- }
- ts.getHeritageClause = getHeritageClause;
- function tryResolveScriptReference(host, sourceFile, reference) {
- if (!host.getCompilerOptions().noResolve) {
- var referenceFileName = ts.isRootedDiskPath(reference.fileName) ? reference.fileName : ts.combinePaths(ts.getDirectoryPath(sourceFile.fileName), reference.fileName);
- return host.getSourceFile(referenceFileName);
+ if (changes.length === 1) {
+ return changes[0];
}
- }
- ts.tryResolveScriptReference = tryResolveScriptReference;
- function getAncestor(node, kind) {
- while (node) {
- if (node.kind === kind) {
- return node;
- }
- node = node.parent;
+ var change0 = changes[0];
+ var oldStartN = change0.span.start;
+ var oldEndN = textSpanEnd(change0.span);
+ var newEndN = oldStartN + change0.newLength;
+ for (var i = 1; i < changes.length; i++) {
+ var nextChange = changes[i];
+ var oldStart1 = oldStartN;
+ var oldEnd1 = oldEndN;
+ var newEnd1 = newEndN;
+ var oldStart2 = nextChange.span.start;
+ var oldEnd2 = textSpanEnd(nextChange.span);
+ var newEnd2 = oldStart2 + nextChange.newLength;
+ oldStartN = Math.min(oldStart1, oldStart2);
+ oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
+ newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
}
- return undefined;
+ return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), newEndN - oldStartN);
}
- ts.getAncestor = getAncestor;
- function getFileReferenceFromReferencePath(comment, commentRange) {
- var simpleReferenceRegEx = /^\/\/\/\s*/gim;
- if (simpleReferenceRegEx.exec(comment)) {
- if (isNoDefaultLibRegEx.exec(comment)) {
- return {
- isNoDefaultLib: true
- };
- }
- else {
- var matchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment);
- if (matchResult) {
- var start = commentRange.pos;
- var end = commentRange.end;
- return {
- fileReference: {
- pos: start,
- end: end,
- fileName: matchResult[3]
- },
- isNoDefaultLib: false
- };
- }
- else {
- return {
- diagnosticMessage: ts.Diagnostics.Invalid_reference_directive_syntax,
- isNoDefaultLib: false
- };
+ ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions;
+ function getTypeParameterOwner(d) {
+ if (d && d.kind === 137) {
+ for (var current = d; current; current = current.parent) {
+ if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 215) {
+ return current;
}
}
}
- return undefined;
- }
- ts.getFileReferenceFromReferencePath = getFileReferenceFromReferencePath;
- function isKeyword(token) {
- return 70 <= token && token <= 134;
- }
- ts.isKeyword = isKeyword;
- function isTrivia(token) {
- return 2 <= token && token <= 7;
- }
- ts.isTrivia = isTrivia;
- function isAsyncFunctionLike(node) {
- return isFunctionLike(node) && (node.flags & 256) !== 0 && !isAccessor(node);
- }
- ts.isAsyncFunctionLike = isAsyncFunctionLike;
- function hasDynamicName(declaration) {
- return declaration.name &&
- declaration.name.kind === 136 &&
- !isWellKnownSymbolSyntactically(declaration.name.expression);
}
- ts.hasDynamicName = hasDynamicName;
- function isWellKnownSymbolSyntactically(node) {
- return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
- }
- ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically;
- function getPropertyNameForPropertyNameNode(name) {
- if (name.kind === 69 || name.kind === 9 || name.kind === 8) {
- return name.text;
+ ts.getTypeParameterOwner = getTypeParameterOwner;
+})(ts || (ts = {}));
+var ts;
+(function (ts) {
+ ts.parseTime = 0;
+ var NodeConstructor;
+ var SourceFileConstructor;
+ function createNode(kind, pos, end) {
+ if (kind === 248) {
+ return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
}
- if (name.kind === 136) {
- var nameExpression = name.expression;
- if (isWellKnownSymbolSyntactically(nameExpression)) {
- var rightHandSideName = nameExpression.name.text;
- return getPropertyNameForKnownSymbolName(rightHandSideName);
- }
+ else {
+ return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
}
- return undefined;
- }
- ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode;
- function getPropertyNameForKnownSymbolName(symbolName) {
- return "__@" + symbolName;
- }
- ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName;
- function isESSymbolIdentifier(node) {
- return node.kind === 69 && node.text === "Symbol";
}
- ts.isESSymbolIdentifier = isESSymbolIdentifier;
- function isModifier(token) {
- switch (token) {
- case 115:
- case 118:
- case 74:
- case 122:
- case 77:
- case 82:
- case 112:
- case 110:
- case 111:
- case 113:
- return true;
+ ts.createNode = createNode;
+ function visitNode(cbNode, node) {
+ if (node) {
+ return cbNode(node);
}
- return false;
}
- ts.isModifier = isModifier;
- function isParameterDeclaration(node) {
- var root = getRootDeclaration(node);
- return root.kind === 138;
+ function visitNodeArray(cbNodes, nodes) {
+ if (nodes) {
+ return cbNodes(nodes);
+ }
}
- ts.isParameterDeclaration = isParameterDeclaration;
- function getRootDeclaration(node) {
- while (node.kind === 163) {
- node = node.parent.parent;
- }
- return node;
- }
- ts.getRootDeclaration = getRootDeclaration;
- function nodeStartsNewLexicalEnvironment(n) {
- return isFunctionLike(n) || n.kind === 218 || n.kind === 248;
- }
- ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
- function cloneEntityName(node) {
- if (node.kind === 69) {
- var clone_1 = createSynthesizedNode(69);
- clone_1.text = node.text;
- return clone_1;
- }
- else {
- var clone_2 = createSynthesizedNode(135);
- clone_2.left = cloneEntityName(node.left);
- clone_2.left.parent = clone_2;
- clone_2.right = cloneEntityName(node.right);
- clone_2.right.parent = clone_2;
- return clone_2;
- }
- }
- ts.cloneEntityName = cloneEntityName;
- function nodeIsSynthesized(node) {
- return node.pos === -1;
- }
- ts.nodeIsSynthesized = nodeIsSynthesized;
- function createSynthesizedNode(kind, startsOnNewLine) {
- var node = ts.createNode(kind, -1, -1);
- node.startsOnNewLine = startsOnNewLine;
- return node;
- }
- ts.createSynthesizedNode = createSynthesizedNode;
- function createSynthesizedNodeArray() {
- var array = [];
- array.pos = -1;
- array.end = -1;
- return array;
- }
- ts.createSynthesizedNodeArray = createSynthesizedNodeArray;
- function createDiagnosticCollection() {
- var nonFileDiagnostics = [];
- var fileDiagnostics = {};
- var diagnosticsModified = false;
- var modificationCount = 0;
- return {
- add: add,
- getGlobalDiagnostics: getGlobalDiagnostics,
- getDiagnostics: getDiagnostics,
- getModificationCount: getModificationCount,
- reattachFileDiagnostics: reattachFileDiagnostics
- };
- function getModificationCount() {
- return modificationCount;
- }
- function reattachFileDiagnostics(newFile) {
- if (!ts.hasProperty(fileDiagnostics, newFile.fileName)) {
- return;
- }
- for (var _i = 0, _a = fileDiagnostics[newFile.fileName]; _i < _a.length; _i++) {
- var diagnostic = _a[_i];
- diagnostic.file = newFile;
- }
- }
- function add(diagnostic) {
- var diagnostics;
- if (diagnostic.file) {
- diagnostics = fileDiagnostics[diagnostic.file.fileName];
- if (!diagnostics) {
- diagnostics = [];
- fileDiagnostics[diagnostic.file.fileName] = diagnostics;
- }
- }
- else {
- diagnostics = nonFileDiagnostics;
- }
- diagnostics.push(diagnostic);
- diagnosticsModified = true;
- modificationCount++;
- }
- function getGlobalDiagnostics() {
- sortAndDeduplicate();
- return nonFileDiagnostics;
- }
- function getDiagnostics(fileName) {
- sortAndDeduplicate();
- if (fileName) {
- return fileDiagnostics[fileName] || [];
- }
- var allDiagnostics = [];
- function pushDiagnostic(d) {
- allDiagnostics.push(d);
- }
- ts.forEach(nonFileDiagnostics, pushDiagnostic);
- for (var key in fileDiagnostics) {
- if (ts.hasProperty(fileDiagnostics, key)) {
- ts.forEach(fileDiagnostics[key], pushDiagnostic);
- }
- }
- return ts.sortAndDeduplicateDiagnostics(allDiagnostics);
- }
- function sortAndDeduplicate() {
- if (!diagnosticsModified) {
- return;
- }
- diagnosticsModified = false;
- nonFileDiagnostics = ts.sortAndDeduplicateDiagnostics(nonFileDiagnostics);
- for (var key in fileDiagnostics) {
- if (ts.hasProperty(fileDiagnostics, key)) {
- fileDiagnostics[key] = ts.sortAndDeduplicateDiagnostics(fileDiagnostics[key]);
- }
- }
- }
- }
- ts.createDiagnosticCollection = createDiagnosticCollection;
- var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
- var escapedCharsMap = {
- "\0": "\\0",
- "\t": "\\t",
- "\v": "\\v",
- "\f": "\\f",
- "\b": "\\b",
- "\r": "\\r",
- "\n": "\\n",
- "\\": "\\\\",
- "\"": "\\\"",
- "\u2028": "\\u2028",
- "\u2029": "\\u2029",
- "\u0085": "\\u0085"
- };
- function escapeString(s) {
- s = escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, getReplacement) : s;
- return s;
- function getReplacement(c) {
- return escapedCharsMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
- }
- }
- ts.escapeString = escapeString;
- function isIntrinsicJsxName(name) {
- var ch = name.substr(0, 1);
- return ch.toLowerCase() === ch;
- }
- ts.isIntrinsicJsxName = isIntrinsicJsxName;
- function get16BitUnicodeEscapeSequence(charCode) {
- var hexCharCode = charCode.toString(16).toUpperCase();
- var paddedHexCode = ("0000" + hexCharCode).slice(-4);
- return "\\u" + paddedHexCode;
- }
- var nonAsciiCharacters = /[^\u0000-\u007F]/g;
- function escapeNonAsciiCharacters(s) {
- return nonAsciiCharacters.test(s) ?
- s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) :
- s;
- }
- ts.escapeNonAsciiCharacters = escapeNonAsciiCharacters;
- var indentStrings = ["", " "];
- function getIndentString(level) {
- if (indentStrings[level] === undefined) {
- indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
- }
- return indentStrings[level];
- }
- ts.getIndentString = getIndentString;
- function getIndentSize() {
- return indentStrings[1].length;
- }
- ts.getIndentSize = getIndentSize;
- function createTextWriter(newLine) {
- var output = "";
- var indent = 0;
- var lineStart = true;
- var lineCount = 0;
- var linePos = 0;
- function write(s) {
- if (s && s.length) {
- if (lineStart) {
- output += getIndentString(indent);
- lineStart = false;
- }
- output += s;
- }
- }
- function rawWrite(s) {
- if (s !== undefined) {
- if (lineStart) {
- lineStart = false;
- }
- output += s;
- }
- }
- function writeLiteral(s) {
- if (s && s.length) {
- write(s);
- var lineStartsOfS = ts.computeLineStarts(s);
- if (lineStartsOfS.length > 1) {
- lineCount = lineCount + lineStartsOfS.length - 1;
- linePos = output.length - s.length + ts.lastOrUndefined(lineStartsOfS);
- }
- }
- }
- function writeLine() {
- if (!lineStart) {
- output += newLine;
- lineCount++;
- linePos = output.length;
- lineStart = true;
- }
- }
- function writeTextOfNode(sourceFile, node) {
- write(getSourceTextOfNodeFromSourceFile(sourceFile, node));
- }
- return {
- write: write,
- rawWrite: rawWrite,
- writeTextOfNode: writeTextOfNode,
- writeLiteral: writeLiteral,
- writeLine: writeLine,
- increaseIndent: function () { return indent++; },
- decreaseIndent: function () { return indent--; },
- getIndent: function () { return indent; },
- getTextPos: function () { return output.length; },
- getLine: function () { return lineCount + 1; },
- getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; },
- getText: function () { return output; }
- };
- }
- ts.createTextWriter = createTextWriter;
- function getOwnEmitOutputFilePath(sourceFile, host, extension) {
- var compilerOptions = host.getCompilerOptions();
- var emitOutputFilePathWithoutExtension;
- if (compilerOptions.outDir) {
- emitOutputFilePathWithoutExtension = ts.removeFileExtension(getSourceFilePathInNewDir(sourceFile, host, compilerOptions.outDir));
- }
- else {
- emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
- }
- return emitOutputFilePathWithoutExtension + extension;
- }
- ts.getOwnEmitOutputFilePath = getOwnEmitOutputFilePath;
- function getSourceFilePathInNewDir(sourceFile, host, newDirPath) {
- var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, host.getCurrentDirectory());
- sourceFilePath = sourceFilePath.replace(host.getCommonSourceDirectory(), "");
- return ts.combinePaths(newDirPath, sourceFilePath);
- }
- ts.getSourceFilePathInNewDir = getSourceFilePathInNewDir;
- function writeFile(host, diagnostics, fileName, data, writeByteOrderMark) {
- host.writeFile(fileName, data, writeByteOrderMark, function (hostErrorMessage) {
- diagnostics.push(ts.createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
- });
- }
- ts.writeFile = writeFile;
- function getLineOfLocalPosition(currentSourceFile, pos) {
- return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line;
- }
- ts.getLineOfLocalPosition = getLineOfLocalPosition;
- function getFirstConstructorWithBody(node) {
- return ts.forEach(node.members, function (member) {
- if (member.kind === 144 && nodeIsPresent(member.body)) {
- return member;
- }
- });
- }
- ts.getFirstConstructorWithBody = getFirstConstructorWithBody;
- function getSetAccessorTypeAnnotationNode(accessor) {
- return accessor && accessor.parameters.length > 0 && accessor.parameters[0].type;
- }
- ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode;
- function shouldEmitToOwnFile(sourceFile, compilerOptions) {
- if (!isDeclarationFile(sourceFile)) {
- if ((isExternalModule(sourceFile) || !(compilerOptions.outFile || compilerOptions.out))) {
- return compilerOptions.isolatedModules || !ts.fileExtensionIs(sourceFile.fileName, ".js");
- }
- return false;
- }
- return false;
- }
- ts.shouldEmitToOwnFile = shouldEmitToOwnFile;
- function getAllAccessorDeclarations(declarations, accessor) {
- var firstAccessor;
- var secondAccessor;
- var getAccessor;
- var setAccessor;
- if (hasDynamicName(accessor)) {
- firstAccessor = accessor;
- if (accessor.kind === 145) {
- getAccessor = accessor;
- }
- else if (accessor.kind === 146) {
- setAccessor = accessor;
- }
- else {
- ts.Debug.fail("Accessor has wrong kind");
- }
- }
- else {
- ts.forEach(declarations, function (member) {
- if ((member.kind === 145 || member.kind === 146)
- && (member.flags & 64) === (accessor.flags & 64)) {
- var memberName = getPropertyNameForPropertyNameNode(member.name);
- var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
- if (memberName === accessorName) {
- if (!firstAccessor) {
- firstAccessor = member;
- }
- else if (!secondAccessor) {
- secondAccessor = member;
- }
- if (member.kind === 145 && !getAccessor) {
- getAccessor = member;
- }
- if (member.kind === 146 && !setAccessor) {
- setAccessor = member;
- }
- }
- }
- });
- }
- return {
- firstAccessor: firstAccessor,
- secondAccessor: secondAccessor,
- getAccessor: getAccessor,
- setAccessor: setAccessor
- };
- }
- ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
- function emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments) {
- if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
- getLineOfLocalPosition(currentSourceFile, node.pos) !== getLineOfLocalPosition(currentSourceFile, leadingComments[0].pos)) {
- writer.writeLine();
- }
- }
- ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
- function emitComments(currentSourceFile, writer, comments, trailingSeparator, newLine, writeComment) {
- var emitLeadingSpace = !trailingSeparator;
- ts.forEach(comments, function (comment) {
- if (emitLeadingSpace) {
- writer.write(" ");
- emitLeadingSpace = false;
- }
- writeComment(currentSourceFile, writer, comment, newLine);
- if (comment.hasTrailingNewLine) {
- writer.writeLine();
- }
- else if (trailingSeparator) {
- writer.write(" ");
- }
- else {
- emitLeadingSpace = true;
- }
- });
- }
- ts.emitComments = emitComments;
- function emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, removeComments) {
- var leadingComments;
- var currentDetachedCommentInfo;
- if (removeComments) {
- if (node.pos === 0) {
- leadingComments = ts.filter(ts.getLeadingCommentRanges(currentSourceFile.text, node.pos), isPinnedComment);
- }
- }
- else {
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
- }
- if (leadingComments) {
- var detachedComments = [];
- var lastComment;
- for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
- var comment = leadingComments_1[_i];
- if (lastComment) {
- var lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastComment.end);
- var commentLine = getLineOfLocalPosition(currentSourceFile, comment.pos);
- if (commentLine >= lastCommentLine + 2) {
- break;
- }
- }
- detachedComments.push(comment);
- lastComment = comment;
- }
- if (detachedComments.length) {
- var lastCommentLine = getLineOfLocalPosition(currentSourceFile, ts.lastOrUndefined(detachedComments).end);
- var nodeLine = getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node.pos));
- if (nodeLine >= lastCommentLine + 2) {
- emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
- emitComments(currentSourceFile, writer, detachedComments, true, newLine, writeComment);
- currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end };
- }
- }
- }
- return currentDetachedCommentInfo;
- function isPinnedComment(comment) {
- return currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 33;
- }
- }
- ts.emitDetachedComments = emitDetachedComments;
- function writeCommentRange(currentSourceFile, writer, comment, newLine) {
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 42) {
- var firstCommentLineAndCharacter = ts.getLineAndCharacterOfPosition(currentSourceFile, comment.pos);
- var lineCount = ts.getLineStarts(currentSourceFile).length;
- var firstCommentLineIndent;
- for (var pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
- var nextLineStart = (currentLine + 1) === lineCount
- ? currentSourceFile.text.length + 1
- : getStartPositionOfLine(currentLine + 1, currentSourceFile);
- if (pos !== comment.pos) {
- if (firstCommentLineIndent === undefined) {
- firstCommentLineIndent = calculateIndent(getStartPositionOfLine(firstCommentLineAndCharacter.line, currentSourceFile), comment.pos);
- }
- var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
- var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(pos, nextLineStart);
- if (spacesToEmit > 0) {
- var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
- var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
- writer.rawWrite(indentSizeSpaceString);
- while (numberOfSingleSpacesToEmit) {
- writer.rawWrite(" ");
- numberOfSingleSpacesToEmit--;
- }
- }
- else {
- writer.rawWrite("");
- }
- }
- writeTrimmedCurrentLine(pos, nextLineStart);
- pos = nextLineStart;
- }
- }
- else {
- writer.write(currentSourceFile.text.substring(comment.pos, comment.end));
- }
- function writeTrimmedCurrentLine(pos, nextLineStart) {
- var end = Math.min(comment.end, nextLineStart - 1);
- var currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, "");
- if (currentLineText) {
- writer.write(currentLineText);
- if (end !== comment.end) {
- writer.writeLine();
- }
- }
- else {
- writer.writeLiteral(newLine);
- }
- }
- function calculateIndent(pos, end) {
- var currentLineIndent = 0;
- for (; pos < end && ts.isWhiteSpace(currentSourceFile.text.charCodeAt(pos)); pos++) {
- if (currentSourceFile.text.charCodeAt(pos) === 9) {
- currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
- }
- else {
- currentLineIndent++;
- }
- }
- return currentLineIndent;
- }
- }
- ts.writeCommentRange = writeCommentRange;
- function modifierToFlag(token) {
- switch (token) {
- case 113: return 64;
- case 112: return 8;
- case 111: return 32;
- case 110: return 16;
- case 115: return 128;
- case 82: return 2;
- case 122: return 4;
- case 74: return 16384;
- case 77: return 512;
- case 118: return 256;
- }
- return 0;
- }
- ts.modifierToFlag = modifierToFlag;
- function isLeftHandSideExpression(expr) {
- if (expr) {
- switch (expr.kind) {
- case 166:
- case 167:
- case 169:
- case 168:
- case 233:
- case 234:
- case 170:
- case 164:
- case 172:
- case 165:
- case 186:
- case 173:
- case 69:
- case 10:
- case 8:
- case 9:
- case 11:
- case 183:
- case 84:
- case 93:
- case 97:
- case 99:
- case 95:
- return true;
- }
- }
- return false;
- }
- ts.isLeftHandSideExpression = isLeftHandSideExpression;
- function isAssignmentOperator(token) {
- return token >= 56 && token <= 68;
- }
- ts.isAssignmentOperator = isAssignmentOperator;
- function isExpressionWithTypeArgumentsInClassExtendsClause(node) {
- return node.kind === 188 &&
- node.parent.token === 83 &&
- isClassLike(node.parent.parent);
- }
- ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause;
- function isSupportedExpressionWithTypeArguments(node) {
- return isSupportedExpressionWithTypeArgumentsRest(node.expression);
- }
- ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments;
- function isSupportedExpressionWithTypeArgumentsRest(node) {
- if (node.kind === 69) {
- return true;
- }
- else if (isPropertyAccessExpression(node)) {
- return isSupportedExpressionWithTypeArgumentsRest(node.expression);
- }
- else {
- return false;
- }
- }
- function isRightSideOfQualifiedNameOrPropertyAccess(node) {
- return (node.parent.kind === 135 && node.parent.right === node) ||
- (node.parent.kind === 166 && node.parent.name === node);
- }
- ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess;
- function isEmptyObjectLiteralOrArrayLiteral(expression) {
- var kind = expression.kind;
- if (kind === 165) {
- return expression.properties.length === 0;
- }
- if (kind === 164) {
- return expression.elements.length === 0;
- }
- return false;
- }
- ts.isEmptyObjectLiteralOrArrayLiteral = isEmptyObjectLiteralOrArrayLiteral;
- function getLocalSymbolForExportDefault(symbol) {
- return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 512) ? symbol.valueDeclaration.localSymbol : undefined;
- }
- ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
- function isJavaScript(fileName) {
- return ts.fileExtensionIs(fileName, ".js");
- }
- ts.isJavaScript = isJavaScript;
- function isTsx(fileName) {
- return ts.fileExtensionIs(fileName, ".tsx");
- }
- ts.isTsx = isTsx;
- function getExpandedCharCodes(input) {
- var output = [];
- var length = input.length;
- for (var i = 0; i < length; i++) {
- var charCode = input.charCodeAt(i);
- if (charCode < 0x80) {
- output.push(charCode);
- }
- else if (charCode < 0x800) {
- output.push((charCode >> 6) | 192);
- output.push((charCode & 63) | 128);
- }
- else if (charCode < 0x10000) {
- output.push((charCode >> 12) | 224);
- output.push(((charCode >> 6) & 63) | 128);
- output.push((charCode & 63) | 128);
- }
- else if (charCode < 0x20000) {
- output.push((charCode >> 18) | 240);
- output.push(((charCode >> 12) & 63) | 128);
- output.push(((charCode >> 6) & 63) | 128);
- output.push((charCode & 63) | 128);
- }
- else {
- ts.Debug.assert(false, "Unexpected code point");
- }
- }
- return output;
- }
- var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- function convertToBase64(input) {
- var result = "";
- var charCodes = getExpandedCharCodes(input);
- var i = 0;
- var length = charCodes.length;
- var byte1, byte2, byte3, byte4;
- while (i < length) {
- byte1 = charCodes[i] >> 2;
- byte2 = (charCodes[i] & 3) << 4 | charCodes[i + 1] >> 4;
- byte3 = (charCodes[i + 1] & 15) << 2 | charCodes[i + 2] >> 6;
- byte4 = charCodes[i + 2] & 63;
- if (i + 1 >= length) {
- byte3 = byte4 = 64;
- }
- else if (i + 2 >= length) {
- byte4 = 64;
- }
- result += base64Digits.charAt(byte1) + base64Digits.charAt(byte2) + base64Digits.charAt(byte3) + base64Digits.charAt(byte4);
- i += 3;
- }
- return result;
- }
- ts.convertToBase64 = convertToBase64;
- function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) {
- return !ts.isRootedDiskPath(absoluteOrRelativePath)
- ? absoluteOrRelativePath
- : ts.getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, false);
- }
- ts.convertToRelativePath = convertToRelativePath;
- var carriageReturnLineFeed = "\r\n";
- var lineFeed = "\n";
- function getNewLineCharacter(options) {
- if (options.newLine === 0) {
- return carriageReturnLineFeed;
- }
- else if (options.newLine === 1) {
- return lineFeed;
- }
- else if (ts.sys) {
- return ts.sys.newLine;
- }
- return carriageReturnLineFeed;
- }
- ts.getNewLineCharacter = getNewLineCharacter;
-})(ts || (ts = {}));
-var ts;
-(function (ts) {
- function getDefaultLibFileName(options) {
- return options.target === 2 ? "lib.es6.d.ts" : "lib.d.ts";
- }
- ts.getDefaultLibFileName = getDefaultLibFileName;
- function textSpanEnd(span) {
- return span.start + span.length;
- }
- ts.textSpanEnd = textSpanEnd;
- function textSpanIsEmpty(span) {
- return span.length === 0;
- }
- ts.textSpanIsEmpty = textSpanIsEmpty;
- function textSpanContainsPosition(span, position) {
- return position >= span.start && position < textSpanEnd(span);
- }
- ts.textSpanContainsPosition = textSpanContainsPosition;
- function textSpanContainsTextSpan(span, other) {
- return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span);
- }
- ts.textSpanContainsTextSpan = textSpanContainsTextSpan;
- function textSpanOverlapsWith(span, other) {
- var overlapStart = Math.max(span.start, other.start);
- var overlapEnd = Math.min(textSpanEnd(span), textSpanEnd(other));
- return overlapStart < overlapEnd;
- }
- ts.textSpanOverlapsWith = textSpanOverlapsWith;
- function textSpanOverlap(span1, span2) {
- var overlapStart = Math.max(span1.start, span2.start);
- var overlapEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
- if (overlapStart < overlapEnd) {
- return createTextSpanFromBounds(overlapStart, overlapEnd);
- }
- return undefined;
- }
- ts.textSpanOverlap = textSpanOverlap;
- function textSpanIntersectsWithTextSpan(span, other) {
- return other.start <= textSpanEnd(span) && textSpanEnd(other) >= span.start;
- }
- ts.textSpanIntersectsWithTextSpan = textSpanIntersectsWithTextSpan;
- function textSpanIntersectsWith(span, start, length) {
- var end = start + length;
- return start <= textSpanEnd(span) && end >= span.start;
- }
- ts.textSpanIntersectsWith = textSpanIntersectsWith;
- function decodedTextSpanIntersectsWith(start1, length1, start2, length2) {
- var end1 = start1 + length1;
- var end2 = start2 + length2;
- return start2 <= end1 && end2 >= start1;
- }
- ts.decodedTextSpanIntersectsWith = decodedTextSpanIntersectsWith;
- function textSpanIntersectsWithPosition(span, position) {
- return position <= textSpanEnd(span) && position >= span.start;
- }
- ts.textSpanIntersectsWithPosition = textSpanIntersectsWithPosition;
- function textSpanIntersection(span1, span2) {
- var intersectStart = Math.max(span1.start, span2.start);
- var intersectEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
- if (intersectStart <= intersectEnd) {
- return createTextSpanFromBounds(intersectStart, intersectEnd);
- }
- return undefined;
- }
- ts.textSpanIntersection = textSpanIntersection;
- function createTextSpan(start, length) {
- if (start < 0) {
- throw new Error("start < 0");
- }
- if (length < 0) {
- throw new Error("length < 0");
- }
- return { start: start, length: length };
- }
- ts.createTextSpan = createTextSpan;
- function createTextSpanFromBounds(start, end) {
- return createTextSpan(start, end - start);
- }
- ts.createTextSpanFromBounds = createTextSpanFromBounds;
- function textChangeRangeNewSpan(range) {
- return createTextSpan(range.span.start, range.newLength);
- }
- ts.textChangeRangeNewSpan = textChangeRangeNewSpan;
- function textChangeRangeIsUnchanged(range) {
- return textSpanIsEmpty(range.span) && range.newLength === 0;
- }
- ts.textChangeRangeIsUnchanged = textChangeRangeIsUnchanged;
- function createTextChangeRange(span, newLength) {
- if (newLength < 0) {
- throw new Error("newLength < 0");
- }
- return { span: span, newLength: newLength };
- }
- ts.createTextChangeRange = createTextChangeRange;
- ts.unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0);
- function collapseTextChangeRangesAcrossMultipleVersions(changes) {
- if (changes.length === 0) {
- return ts.unchangedTextChangeRange;
- }
- if (changes.length === 1) {
- return changes[0];
- }
- var change0 = changes[0];
- var oldStartN = change0.span.start;
- var oldEndN = textSpanEnd(change0.span);
- var newEndN = oldStartN + change0.newLength;
- for (var i = 1; i < changes.length; i++) {
- var nextChange = changes[i];
- var oldStart1 = oldStartN;
- var oldEnd1 = oldEndN;
- var newEnd1 = newEndN;
- var oldStart2 = nextChange.span.start;
- var oldEnd2 = textSpanEnd(nextChange.span);
- var newEnd2 = oldStart2 + nextChange.newLength;
- oldStartN = Math.min(oldStart1, oldStart2);
- oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
- newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
- }
- return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), newEndN - oldStartN);
- }
- ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions;
- function getTypeParameterOwner(d) {
- if (d && d.kind === 137) {
- for (var current = d; current; current = current.parent) {
- if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 215) {
- return current;
- }
- }
- }
- }
- ts.getTypeParameterOwner = getTypeParameterOwner;
-})(ts || (ts = {}));
-var ts;
-(function (ts) {
- var nodeConstructors = new Array(272);
- ts.parseTime = 0;
- function getNodeConstructor(kind) {
- return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind));
- }
- ts.getNodeConstructor = getNodeConstructor;
- function createNode(kind, pos, end) {
- return new (getNodeConstructor(kind))(pos, end);
- }
- ts.createNode = createNode;
- function visitNode(cbNode, node) {
- if (node) {
- return cbNode(node);
- }
- }
- function visitNodeArray(cbNodes, nodes) {
- if (nodes) {
- return cbNodes(nodes);
- }
- }
- function visitEachNode(cbNode, nodes) {
- if (nodes) {
- for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
- var node = nodes_1[_i];
- var result = cbNode(node);
- if (result) {
- return result;
- }
- }
+ function visitEachNode(cbNode, nodes) {
+ if (nodes) {
+ for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+ var node = nodes_1[_i];
+ var result = cbNode(node);
+ if (result) {
+ return result;
+ }
+ }
}
}
function forEachChild(node, cbNode, cbNodeArray) {
@@ -6567,6 +5625,8 @@ var ts;
(function (Parser) {
var scanner = ts.createScanner(2, true);
var disallowInAndDecoratorContext = 1 | 4;
+ var NodeConstructor;
+ var SourceFileConstructor;
var sourceFile;
var parseDiagnostics;
var syntaxCursor;
@@ -6579,13 +5639,16 @@ var ts;
var contextFlags;
var parseErrorBeforeNextFinishedNode = false;
function parseSourceFile(fileName, _sourceText, languageVersion, _syntaxCursor, setParentNodes) {
- initializeState(fileName, _sourceText, languageVersion, _syntaxCursor);
+ var isJavaScriptFile = ts.hasJavaScriptFileExtension(fileName) || _sourceText.lastIndexOf("// @language=javascript", 0) === 0;
+ initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor);
var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes);
clearState();
return result;
}
Parser.parseSourceFile = parseSourceFile;
- function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor) {
+ function initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor) {
+ NodeConstructor = ts.objectAllocator.getNodeConstructor();
+ SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
sourceText = _sourceText;
syntaxCursor = _syntaxCursor;
parseDiagnostics = [];
@@ -6593,12 +5656,12 @@ var ts;
identifiers = {};
identifierCount = 0;
nodeCount = 0;
- contextFlags = ts.isJavaScript(fileName) ? 32 : 0;
+ contextFlags = isJavaScriptFile ? 32 : 0;
parseErrorBeforeNextFinishedNode = false;
scanner.setText(sourceText);
scanner.setOnError(scanError);
scanner.setScriptTarget(languageVersion);
- scanner.setLanguageVariant(ts.isTsx(fileName) ? 1 : 0);
+ scanner.setLanguageVariant(ts.allowsJsxExpressions(fileName) ? 1 : 0);
}
function clearState() {
scanner.setText("");
@@ -6611,6 +5674,9 @@ var ts;
}
function parseSourceFileWorker(fileName, languageVersion, setParentNodes) {
sourceFile = createSourceFile(fileName, languageVersion);
+ if (contextFlags & 32) {
+ sourceFile.parserContextFlags = 32;
+ }
token = nextToken();
processReferenceComments(sourceFile);
sourceFile.statements = parseList(0, parseStatement);
@@ -6624,7 +5690,7 @@ var ts;
if (setParentNodes) {
fixupParentReferences(sourceFile);
}
- if (ts.isJavaScript(fileName)) {
+ if (ts.isSourceFileJavaScript(sourceFile)) {
addJSDocComments();
}
return sourceFile;
@@ -6670,15 +5736,14 @@ var ts;
}
Parser.fixupParentReferences = fixupParentReferences;
function createSourceFile(fileName, languageVersion) {
- var sourceFile = createNode(248, 0);
- sourceFile.pos = 0;
- sourceFile.end = sourceText.length;
+ var sourceFile = new SourceFileConstructor(248, 0, sourceText.length);
+ nodeCount++;
sourceFile.text = sourceText;
sourceFile.bindDiagnostics = [];
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = ts.normalizePath(fileName);
sourceFile.flags = ts.fileExtensionIs(sourceFile.fileName, ".d.ts") ? 4096 : 0;
- sourceFile.languageVariant = ts.isTsx(sourceFile.fileName) ? 1 : 0;
+ sourceFile.languageVariant = ts.allowsJsxExpressions(sourceFile.fileName) ? 1 : 0;
return sourceFile;
}
function setContextFlag(val, flag) {
@@ -6900,7 +5965,7 @@ var ts;
if (!(pos >= 0)) {
pos = scanner.getStartPos();
}
- return new (nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)))(pos, pos);
+ return new NodeConstructor(kind, pos, pos);
}
function finishNode(node, end) {
node.end = end === undefined ? scanner.getStartPos() : end;
@@ -7038,7 +6103,7 @@ var ts;
case 12:
return token === 19 || token === 37 || isLiteralPropertyName();
case 9:
- return isLiteralPropertyName();
+ return token === 19 || isLiteralPropertyName();
case 7:
if (token === 15) {
return lookAhead(isValidHeritageClauseObjectLiteral);
@@ -7328,3470 +6393,4539 @@ var ts;
return true;
}
}
- return false;
+ return false;
+ }
+ function isReusableEnumMember(node) {
+ return node.kind === 247;
+ }
+ function isReusableTypeMember(node) {
+ if (node) {
+ switch (node.kind) {
+ case 148:
+ case 142:
+ case 149:
+ case 140:
+ case 147:
+ return true;
+ }
+ }
+ return false;
+ }
+ function isReusableVariableDeclaration(node) {
+ if (node.kind !== 211) {
+ return false;
+ }
+ var variableDeclarator = node;
+ return variableDeclarator.initializer === undefined;
+ }
+ function isReusableParameter(node) {
+ if (node.kind !== 138) {
+ return false;
+ }
+ var parameter = node;
+ return parameter.initializer === undefined;
+ }
+ function abortParsingListOrMoveToNextToken(kind) {
+ parseErrorAtCurrentToken(parsingContextErrors(kind));
+ if (isInSomeParsingContext()) {
+ return true;
+ }
+ nextToken();
+ return false;
+ }
+ function parsingContextErrors(context) {
+ switch (context) {
+ case 0: return ts.Diagnostics.Declaration_or_statement_expected;
+ case 1: return ts.Diagnostics.Declaration_or_statement_expected;
+ case 2: return ts.Diagnostics.case_or_default_expected;
+ case 3: return ts.Diagnostics.Statement_expected;
+ case 4: return ts.Diagnostics.Property_or_signature_expected;
+ case 5: return ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
+ case 6: return ts.Diagnostics.Enum_member_expected;
+ case 7: return ts.Diagnostics.Expression_expected;
+ case 8: return ts.Diagnostics.Variable_declaration_expected;
+ case 9: return ts.Diagnostics.Property_destructuring_pattern_expected;
+ case 10: return ts.Diagnostics.Array_element_destructuring_pattern_expected;
+ case 11: return ts.Diagnostics.Argument_expression_expected;
+ case 12: return ts.Diagnostics.Property_assignment_expected;
+ case 15: return ts.Diagnostics.Expression_or_comma_expected;
+ case 16: return ts.Diagnostics.Parameter_declaration_expected;
+ case 17: return ts.Diagnostics.Type_parameter_declaration_expected;
+ case 18: return ts.Diagnostics.Type_argument_expected;
+ case 19: return ts.Diagnostics.Type_expected;
+ case 20: return ts.Diagnostics.Unexpected_token_expected;
+ case 21: return ts.Diagnostics.Identifier_expected;
+ case 13: return ts.Diagnostics.Identifier_expected;
+ case 14: return ts.Diagnostics.Identifier_expected;
+ case 22: return ts.Diagnostics.Parameter_declaration_expected;
+ case 23: return ts.Diagnostics.Type_argument_expected;
+ case 25: return ts.Diagnostics.Type_expected;
+ case 24: return ts.Diagnostics.Property_assignment_expected;
+ }
+ }
+ ;
+ function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimeter) {
+ var saveParsingContext = parsingContext;
+ parsingContext |= 1 << kind;
+ var result = [];
+ result.pos = getNodePos();
+ var commaStart = -1;
+ while (true) {
+ if (isListElement(kind, false)) {
+ result.push(parseListElement(kind, parseElement));
+ commaStart = scanner.getTokenPos();
+ if (parseOptional(24)) {
+ continue;
+ }
+ commaStart = -1;
+ if (isListTerminator(kind)) {
+ break;
+ }
+ parseExpected(24);
+ if (considerSemicolonAsDelimeter && token === 23 && !scanner.hasPrecedingLineBreak()) {
+ nextToken();
+ }
+ continue;
+ }
+ if (isListTerminator(kind)) {
+ break;
+ }
+ if (abortParsingListOrMoveToNextToken(kind)) {
+ break;
+ }
+ }
+ if (commaStart >= 0) {
+ result.hasTrailingComma = true;
+ }
+ result.end = getNodeEnd();
+ parsingContext = saveParsingContext;
+ return result;
+ }
+ function createMissingList() {
+ var pos = getNodePos();
+ var result = [];
+ result.pos = pos;
+ result.end = pos;
+ return result;
+ }
+ function parseBracketedList(kind, parseElement, open, close) {
+ if (parseExpected(open)) {
+ var result = parseDelimitedList(kind, parseElement);
+ parseExpected(close);
+ return result;
+ }
+ return createMissingList();
+ }
+ function parseEntityName(allowReservedWords, diagnosticMessage) {
+ var entity = parseIdentifier(diagnosticMessage);
+ while (parseOptional(21)) {
+ var node = createNode(135, entity.pos);
+ node.left = entity;
+ node.right = parseRightSideOfDot(allowReservedWords);
+ entity = finishNode(node);
+ }
+ return entity;
+ }
+ function parseRightSideOfDot(allowIdentifierNames) {
+ if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token)) {
+ var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
+ if (matchesPattern) {
+ return createMissingNode(69, true, ts.Diagnostics.Identifier_expected);
+ }
+ }
+ return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
+ }
+ function parseTemplateExpression() {
+ var template = createNode(183);
+ template.head = parseLiteralNode();
+ ts.Debug.assert(template.head.kind === 12, "Template head has wrong token kind");
+ var templateSpans = [];
+ templateSpans.pos = getNodePos();
+ do {
+ templateSpans.push(parseTemplateSpan());
+ } while (ts.lastOrUndefined(templateSpans).literal.kind === 13);
+ templateSpans.end = getNodeEnd();
+ template.templateSpans = templateSpans;
+ return finishNode(template);
+ }
+ function parseTemplateSpan() {
+ var span = createNode(190);
+ span.expression = allowInAnd(parseExpression);
+ var literal;
+ if (token === 16) {
+ reScanTemplateToken();
+ literal = parseLiteralNode();
+ }
+ else {
+ literal = parseExpectedToken(14, false, ts.Diagnostics._0_expected, ts.tokenToString(16));
+ }
+ span.literal = literal;
+ return finishNode(span);
+ }
+ function parseLiteralNode(internName) {
+ var node = createNode(token);
+ var text = scanner.getTokenValue();
+ node.text = internName ? internIdentifier(text) : text;
+ if (scanner.hasExtendedUnicodeEscape()) {
+ node.hasExtendedUnicodeEscape = true;
+ }
+ if (scanner.isUnterminated()) {
+ node.isUnterminated = true;
+ }
+ var tokenPos = scanner.getTokenPos();
+ nextToken();
+ finishNode(node);
+ if (node.kind === 8
+ && sourceText.charCodeAt(tokenPos) === 48
+ && ts.isOctalDigit(sourceText.charCodeAt(tokenPos + 1))) {
+ node.flags |= 32768;
+ }
+ return node;
+ }
+ function parseTypeReferenceOrTypePredicate() {
+ var typeName = parseEntityName(false, ts.Diagnostics.Type_expected);
+ if (typeName.kind === 69 && token === 124 && !scanner.hasPrecedingLineBreak()) {
+ nextToken();
+ var node_1 = createNode(150, typeName.pos);
+ node_1.parameterName = typeName;
+ node_1.type = parseType();
+ return finishNode(node_1);
+ }
+ var node = createNode(151, typeName.pos);
+ node.typeName = typeName;
+ if (!scanner.hasPrecedingLineBreak() && token === 25) {
+ node.typeArguments = parseBracketedList(18, parseType, 25, 27);
+ }
+ return finishNode(node);
+ }
+ function parseTypeQuery() {
+ var node = createNode(154);
+ parseExpected(101);
+ node.exprName = parseEntityName(true);
+ return finishNode(node);
+ }
+ function parseTypeParameter() {
+ var node = createNode(137);
+ node.name = parseIdentifier();
+ if (parseOptional(83)) {
+ if (isStartOfType() || !isStartOfExpression()) {
+ node.constraint = parseType();
+ }
+ else {
+ node.expression = parseUnaryExpressionOrHigher();
+ }
+ }
+ return finishNode(node);
+ }
+ function parseTypeParameters() {
+ if (token === 25) {
+ return parseBracketedList(17, parseTypeParameter, 25, 27);
+ }
+ }
+ function parseParameterType() {
+ if (parseOptional(54)) {
+ return parseType();
+ }
+ return undefined;
+ }
+ function isStartOfParameter() {
+ return token === 22 || isIdentifierOrPattern() || ts.isModifier(token) || token === 55;
+ }
+ function setModifiers(node, modifiers) {
+ if (modifiers) {
+ node.flags |= modifiers.flags;
+ node.modifiers = modifiers;
+ }
+ }
+ function parseParameter() {
+ var node = createNode(138);
+ node.decorators = parseDecorators();
+ setModifiers(node, parseModifiers());
+ node.dotDotDotToken = parseOptionalToken(22);
+ node.name = parseIdentifierOrPattern();
+ if (ts.getFullWidth(node.name) === 0 && node.flags === 0 && ts.isModifier(token)) {
+ nextToken();
+ }
+ node.questionToken = parseOptionalToken(53);
+ node.type = parseParameterType();
+ node.initializer = parseBindingElementInitializer(true);
+ return finishNode(node);
+ }
+ function parseBindingElementInitializer(inParameter) {
+ return inParameter ? parseParameterInitializer() : parseNonParameterInitializer();
+ }
+ function parseParameterInitializer() {
+ return parseInitializer(true);
+ }
+ function fillSignature(returnToken, yieldContext, awaitContext, requireCompleteParameterList, signature) {
+ var returnTokenRequired = returnToken === 34;
+ signature.typeParameters = parseTypeParameters();
+ signature.parameters = parseParameterList(yieldContext, awaitContext, requireCompleteParameterList);
+ if (returnTokenRequired) {
+ parseExpected(returnToken);
+ signature.type = parseType();
+ }
+ else if (parseOptional(returnToken)) {
+ signature.type = parseType();
+ }
+ }
+ function parseParameterList(yieldContext, awaitContext, requireCompleteParameterList) {
+ if (parseExpected(17)) {
+ var savedYieldContext = inYieldContext();
+ var savedAwaitContext = inAwaitContext();
+ setYieldContext(yieldContext);
+ setAwaitContext(awaitContext);
+ var result = parseDelimitedList(16, parseParameter);
+ setYieldContext(savedYieldContext);
+ setAwaitContext(savedAwaitContext);
+ if (!parseExpected(18) && requireCompleteParameterList) {
+ return undefined;
+ }
+ return result;
+ }
+ return requireCompleteParameterList ? undefined : createMissingList();
}
- function isReusableEnumMember(node) {
- return node.kind === 247;
+ function parseTypeMemberSemicolon() {
+ if (parseOptional(24)) {
+ return;
+ }
+ parseSemicolon();
}
- function isReusableTypeMember(node) {
- if (node) {
- switch (node.kind) {
- case 148:
- case 142:
- case 149:
- case 140:
- case 147:
- return true;
- }
+ function parseSignatureMember(kind) {
+ var node = createNode(kind);
+ if (kind === 148) {
+ parseExpected(92);
}
- return false;
+ fillSignature(54, false, false, false, node);
+ parseTypeMemberSemicolon();
+ return finishNode(node);
}
- function isReusableVariableDeclaration(node) {
- if (node.kind !== 211) {
+ function isIndexSignature() {
+ if (token !== 19) {
return false;
}
- var variableDeclarator = node;
- return variableDeclarator.initializer === undefined;
+ return lookAhead(isUnambiguouslyIndexSignature);
}
- function isReusableParameter(node) {
- if (node.kind !== 138) {
+ function isUnambiguouslyIndexSignature() {
+ nextToken();
+ if (token === 22 || token === 20) {
+ return true;
+ }
+ if (ts.isModifier(token)) {
+ nextToken();
+ if (isIdentifier()) {
+ return true;
+ }
+ }
+ else if (!isIdentifier()) {
return false;
}
- var parameter = node;
- return parameter.initializer === undefined;
- }
- function abortParsingListOrMoveToNextToken(kind) {
- parseErrorAtCurrentToken(parsingContextErrors(kind));
- if (isInSomeParsingContext()) {
+ else {
+ nextToken();
+ }
+ if (token === 54 || token === 24) {
return true;
}
+ if (token !== 53) {
+ return false;
+ }
nextToken();
- return false;
+ return token === 54 || token === 24 || token === 20;
}
- function parsingContextErrors(context) {
- switch (context) {
- case 0: return ts.Diagnostics.Declaration_or_statement_expected;
- case 1: return ts.Diagnostics.Declaration_or_statement_expected;
- case 2: return ts.Diagnostics.case_or_default_expected;
- case 3: return ts.Diagnostics.Statement_expected;
- case 4: return ts.Diagnostics.Property_or_signature_expected;
- case 5: return ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
- case 6: return ts.Diagnostics.Enum_member_expected;
- case 7: return ts.Diagnostics.Expression_expected;
- case 8: return ts.Diagnostics.Variable_declaration_expected;
- case 9: return ts.Diagnostics.Property_destructuring_pattern_expected;
- case 10: return ts.Diagnostics.Array_element_destructuring_pattern_expected;
- case 11: return ts.Diagnostics.Argument_expression_expected;
- case 12: return ts.Diagnostics.Property_assignment_expected;
- case 15: return ts.Diagnostics.Expression_or_comma_expected;
- case 16: return ts.Diagnostics.Parameter_declaration_expected;
- case 17: return ts.Diagnostics.Type_parameter_declaration_expected;
- case 18: return ts.Diagnostics.Type_argument_expected;
- case 19: return ts.Diagnostics.Type_expected;
- case 20: return ts.Diagnostics.Unexpected_token_expected;
- case 21: return ts.Diagnostics.Identifier_expected;
- case 13: return ts.Diagnostics.Identifier_expected;
- case 14: return ts.Diagnostics.Identifier_expected;
- case 22: return ts.Diagnostics.Parameter_declaration_expected;
- case 23: return ts.Diagnostics.Type_argument_expected;
- case 25: return ts.Diagnostics.Type_expected;
- case 24: return ts.Diagnostics.Property_assignment_expected;
+ function parseIndexSignatureDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(149, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.parameters = parseBracketedList(16, parseParameter, 19, 20);
+ node.type = parseTypeAnnotation();
+ parseTypeMemberSemicolon();
+ return finishNode(node);
+ }
+ function parsePropertyOrMethodSignature() {
+ var fullStart = scanner.getStartPos();
+ var name = parsePropertyName();
+ var questionToken = parseOptionalToken(53);
+ if (token === 17 || token === 25) {
+ var method = createNode(142, fullStart);
+ method.name = name;
+ method.questionToken = questionToken;
+ fillSignature(54, false, false, false, method);
+ parseTypeMemberSemicolon();
+ return finishNode(method);
+ }
+ else {
+ var property = createNode(140, fullStart);
+ property.name = name;
+ property.questionToken = questionToken;
+ property.type = parseTypeAnnotation();
+ parseTypeMemberSemicolon();
+ return finishNode(property);
}
}
- ;
- function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimeter) {
- var saveParsingContext = parsingContext;
- parsingContext |= 1 << kind;
- var result = [];
- result.pos = getNodePos();
- var commaStart = -1;
- while (true) {
- if (isListElement(kind, false)) {
- result.push(parseListElement(kind, parseElement));
- commaStart = scanner.getTokenPos();
- if (parseOptional(24)) {
- continue;
+ function isStartOfTypeMember() {
+ switch (token) {
+ case 17:
+ case 25:
+ case 19:
+ return true;
+ default:
+ if (ts.isModifier(token)) {
+ var result = lookAhead(isStartOfIndexSignatureDeclaration);
+ if (result) {
+ return result;
+ }
}
- commaStart = -1;
- if (isListTerminator(kind)) {
- break;
+ return isLiteralPropertyName() && lookAhead(isTypeMemberWithLiteralPropertyName);
+ }
+ }
+ function isStartOfIndexSignatureDeclaration() {
+ while (ts.isModifier(token)) {
+ nextToken();
+ }
+ return isIndexSignature();
+ }
+ function isTypeMemberWithLiteralPropertyName() {
+ nextToken();
+ return token === 17 ||
+ token === 25 ||
+ token === 53 ||
+ token === 54 ||
+ canParseSemicolon();
+ }
+ function parseTypeMember() {
+ switch (token) {
+ case 17:
+ case 25:
+ return parseSignatureMember(147);
+ case 19:
+ return isIndexSignature()
+ ? parseIndexSignatureDeclaration(scanner.getStartPos(), undefined, undefined)
+ : parsePropertyOrMethodSignature();
+ case 92:
+ if (lookAhead(isStartOfConstructSignature)) {
+ return parseSignatureMember(148);
}
- parseExpected(24);
- if (considerSemicolonAsDelimeter && token === 23 && !scanner.hasPrecedingLineBreak()) {
- nextToken();
+ case 9:
+ case 8:
+ return parsePropertyOrMethodSignature();
+ default:
+ if (ts.isModifier(token)) {
+ var result = tryParse(parseIndexSignatureWithModifiers);
+ if (result) {
+ return result;
+ }
}
- continue;
- }
- if (isListTerminator(kind)) {
- break;
- }
- if (abortParsingListOrMoveToNextToken(kind)) {
- break;
- }
+ if (ts.tokenIsIdentifierOrKeyword(token)) {
+ return parsePropertyOrMethodSignature();
+ }
+ }
+ }
+ function parseIndexSignatureWithModifiers() {
+ var fullStart = scanner.getStartPos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ return isIndexSignature()
+ ? parseIndexSignatureDeclaration(fullStart, decorators, modifiers)
+ : undefined;
+ }
+ function isStartOfConstructSignature() {
+ nextToken();
+ return token === 17 || token === 25;
+ }
+ function parseTypeLiteral() {
+ var node = createNode(155);
+ node.members = parseObjectTypeMembers();
+ return finishNode(node);
+ }
+ function parseObjectTypeMembers() {
+ var members;
+ if (parseExpected(15)) {
+ members = parseList(4, parseTypeMember);
+ parseExpected(16);
}
- if (commaStart >= 0) {
- result.hasTrailingComma = true;
+ else {
+ members = createMissingList();
}
- result.end = getNodeEnd();
- parsingContext = saveParsingContext;
- return result;
+ return members;
}
- function createMissingList() {
- var pos = getNodePos();
- var result = [];
- result.pos = pos;
- result.end = pos;
- return result;
+ function parseTupleType() {
+ var node = createNode(157);
+ node.elementTypes = parseBracketedList(19, parseType, 19, 20);
+ return finishNode(node);
}
- function parseBracketedList(kind, parseElement, open, close) {
- if (parseExpected(open)) {
- var result = parseDelimitedList(kind, parseElement);
- parseExpected(close);
- return result;
+ function parseParenthesizedType() {
+ var node = createNode(160);
+ parseExpected(17);
+ node.type = parseType();
+ parseExpected(18);
+ return finishNode(node);
+ }
+ function parseFunctionOrConstructorType(kind) {
+ var node = createNode(kind);
+ if (kind === 153) {
+ parseExpected(92);
}
- return createMissingList();
+ fillSignature(34, false, false, false, node);
+ return finishNode(node);
}
- function parseEntityName(allowReservedWords, diagnosticMessage) {
- var entity = parseIdentifier(diagnosticMessage);
- while (parseOptional(21)) {
- var node = createNode(135, entity.pos);
- node.left = entity;
- node.right = parseRightSideOfDot(allowReservedWords);
- entity = finishNode(node);
+ function parseKeywordAndNoDot() {
+ var node = parseTokenNode();
+ return token === 21 ? undefined : node;
+ }
+ function parseNonArrayType() {
+ switch (token) {
+ case 117:
+ case 130:
+ case 128:
+ case 120:
+ case 131:
+ var node = tryParse(parseKeywordAndNoDot);
+ return node || parseTypeReferenceOrTypePredicate();
+ case 9:
+ return parseLiteralNode(true);
+ case 103:
+ case 97:
+ return parseTokenNode();
+ case 101:
+ return parseTypeQuery();
+ case 15:
+ return parseTypeLiteral();
+ case 19:
+ return parseTupleType();
+ case 17:
+ return parseParenthesizedType();
+ default:
+ return parseTypeReferenceOrTypePredicate();
}
- return entity;
}
- function parseRightSideOfDot(allowIdentifierNames) {
- if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token)) {
- var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
- if (matchesPattern) {
- return createMissingNode(69, true, ts.Diagnostics.Identifier_expected);
- }
+ function isStartOfType() {
+ switch (token) {
+ case 117:
+ case 130:
+ case 128:
+ case 120:
+ case 131:
+ case 103:
+ case 97:
+ case 101:
+ case 15:
+ case 19:
+ case 25:
+ case 92:
+ case 9:
+ return true;
+ case 17:
+ return lookAhead(isStartOfParenthesizedOrFunctionType);
+ default:
+ return isIdentifier();
}
- return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
}
- function parseTemplateExpression() {
- var template = createNode(183);
- template.head = parseLiteralNode();
- ts.Debug.assert(template.head.kind === 12, "Template head has wrong token kind");
- var templateSpans = [];
- templateSpans.pos = getNodePos();
- do {
- templateSpans.push(parseTemplateSpan());
- } while (ts.lastOrUndefined(templateSpans).literal.kind === 13);
- templateSpans.end = getNodeEnd();
- template.templateSpans = templateSpans;
- return finishNode(template);
+ function isStartOfParenthesizedOrFunctionType() {
+ nextToken();
+ return token === 18 || isStartOfParameter() || isStartOfType();
}
- function parseTemplateSpan() {
- var span = createNode(190);
- span.expression = allowInAnd(parseExpression);
- var literal;
- if (token === 16) {
- reScanTemplateToken();
- literal = parseLiteralNode();
- }
- else {
- literal = parseExpectedToken(14, false, ts.Diagnostics._0_expected, ts.tokenToString(16));
+ function parseArrayTypeOrHigher() {
+ var type = parseNonArrayType();
+ while (!scanner.hasPrecedingLineBreak() && parseOptional(19)) {
+ parseExpected(20);
+ var node = createNode(156, type.pos);
+ node.elementType = type;
+ type = finishNode(node);
}
- span.literal = literal;
- return finishNode(span);
+ return type;
}
- function parseLiteralNode(internName) {
- var node = createNode(token);
- var text = scanner.getTokenValue();
- node.text = internName ? internIdentifier(text) : text;
- if (scanner.hasExtendedUnicodeEscape()) {
- node.hasExtendedUnicodeEscape = true;
+ function parseUnionOrIntersectionType(kind, parseConstituentType, operator) {
+ var type = parseConstituentType();
+ if (token === operator) {
+ var types = [type];
+ types.pos = type.pos;
+ while (parseOptional(operator)) {
+ types.push(parseConstituentType());
+ }
+ types.end = getNodeEnd();
+ var node = createNode(kind, type.pos);
+ node.types = types;
+ type = finishNode(node);
}
- if (scanner.isUnterminated()) {
- node.isUnterminated = true;
+ return type;
+ }
+ function parseIntersectionTypeOrHigher() {
+ return parseUnionOrIntersectionType(159, parseArrayTypeOrHigher, 46);
+ }
+ function parseUnionTypeOrHigher() {
+ return parseUnionOrIntersectionType(158, parseIntersectionTypeOrHigher, 47);
+ }
+ function isStartOfFunctionType() {
+ if (token === 25) {
+ return true;
}
- var tokenPos = scanner.getTokenPos();
+ return token === 17 && lookAhead(isUnambiguouslyStartOfFunctionType);
+ }
+ function isUnambiguouslyStartOfFunctionType() {
nextToken();
- finishNode(node);
- if (node.kind === 8
- && sourceText.charCodeAt(tokenPos) === 48
- && ts.isOctalDigit(sourceText.charCodeAt(tokenPos + 1))) {
- node.flags |= 32768;
+ if (token === 18 || token === 22) {
+ return true;
}
- return node;
- }
- function parseTypeReferenceOrTypePredicate() {
- var typeName = parseEntityName(false, ts.Diagnostics.Type_expected);
- if (typeName.kind === 69 && token === 124 && !scanner.hasPrecedingLineBreak()) {
+ if (isIdentifier() || ts.isModifier(token)) {
nextToken();
- var node_1 = createNode(150, typeName.pos);
- node_1.parameterName = typeName;
- node_1.type = parseType();
- return finishNode(node_1);
- }
- var node = createNode(151, typeName.pos);
- node.typeName = typeName;
- if (!scanner.hasPrecedingLineBreak() && token === 25) {
- node.typeArguments = parseBracketedList(18, parseType, 25, 27);
- }
- return finishNode(node);
- }
- function parseTypeQuery() {
- var node = createNode(154);
- parseExpected(101);
- node.exprName = parseEntityName(true);
- return finishNode(node);
- }
- function parseTypeParameter() {
- var node = createNode(137);
- node.name = parseIdentifier();
- if (parseOptional(83)) {
- if (isStartOfType() || !isStartOfExpression()) {
- node.constraint = parseType();
+ if (token === 54 || token === 24 ||
+ token === 53 || token === 56 ||
+ isIdentifier() || ts.isModifier(token)) {
+ return true;
}
- else {
- node.expression = parseUnaryExpressionOrHigher();
+ if (token === 18) {
+ nextToken();
+ if (token === 34) {
+ return true;
+ }
}
}
- return finishNode(node);
+ return false;
}
- function parseTypeParameters() {
- if (token === 25) {
- return parseBracketedList(17, parseTypeParameter, 25, 27);
+ function parseType() {
+ return doOutsideOfContext(10, parseTypeWorker);
+ }
+ function parseTypeWorker() {
+ if (isStartOfFunctionType()) {
+ return parseFunctionOrConstructorType(152);
}
+ if (token === 92) {
+ return parseFunctionOrConstructorType(153);
+ }
+ return parseUnionTypeOrHigher();
}
- function parseParameterType() {
- if (parseOptional(54)) {
- return token === 9
- ? parseLiteralNode(true)
- : parseType();
+ function parseTypeAnnotation() {
+ return parseOptional(54) ? parseType() : undefined;
+ }
+ function isStartOfLeftHandSideExpression() {
+ switch (token) {
+ case 97:
+ case 95:
+ case 93:
+ case 99:
+ case 84:
+ case 8:
+ case 9:
+ case 11:
+ case 12:
+ case 17:
+ case 19:
+ case 15:
+ case 87:
+ case 73:
+ case 92:
+ case 39:
+ case 61:
+ case 69:
+ return true;
+ default:
+ return isIdentifier();
}
- return undefined;
- }
- function isStartOfParameter() {
- return token === 22 || isIdentifierOrPattern() || ts.isModifier(token) || token === 55;
}
- function setModifiers(node, modifiers) {
- if (modifiers) {
- node.flags |= modifiers.flags;
- node.modifiers = modifiers;
+ function isStartOfExpression() {
+ if (isStartOfLeftHandSideExpression()) {
+ return true;
}
- }
- function parseParameter() {
- var node = createNode(138);
- node.decorators = parseDecorators();
- setModifiers(node, parseModifiers());
- node.dotDotDotToken = parseOptionalToken(22);
- node.name = parseIdentifierOrPattern();
- if (ts.getFullWidth(node.name) === 0 && node.flags === 0 && ts.isModifier(token)) {
- nextToken();
+ switch (token) {
+ case 35:
+ case 36:
+ case 50:
+ case 49:
+ case 78:
+ case 101:
+ case 103:
+ case 41:
+ case 42:
+ case 25:
+ case 119:
+ case 114:
+ return true;
+ default:
+ if (isBinaryOperator()) {
+ return true;
+ }
+ return isIdentifier();
}
- node.questionToken = parseOptionalToken(53);
- node.type = parseParameterType();
- node.initializer = parseBindingElementInitializer(true);
- return finishNode(node);
}
- function parseBindingElementInitializer(inParameter) {
- return inParameter ? parseParameterInitializer() : parseNonParameterInitializer();
+ function isStartOfExpressionStatement() {
+ return token !== 15 &&
+ token !== 87 &&
+ token !== 73 &&
+ token !== 55 &&
+ isStartOfExpression();
}
- function parseParameterInitializer() {
- return parseInitializer(true);
+ function allowInAndParseExpression() {
+ return allowInAnd(parseExpression);
}
- function fillSignature(returnToken, yieldContext, awaitContext, requireCompleteParameterList, signature) {
- var returnTokenRequired = returnToken === 34;
- signature.typeParameters = parseTypeParameters();
- signature.parameters = parseParameterList(yieldContext, awaitContext, requireCompleteParameterList);
- if (returnTokenRequired) {
- parseExpected(returnToken);
- signature.type = parseType();
+ function parseExpression() {
+ var saveDecoratorContext = inDecoratorContext();
+ if (saveDecoratorContext) {
+ setDecoratorContext(false);
}
- else if (parseOptional(returnToken)) {
- signature.type = parseType();
+ var expr = parseAssignmentExpressionOrHigher();
+ var operatorToken;
+ while ((operatorToken = parseOptionalToken(24))) {
+ expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
}
+ if (saveDecoratorContext) {
+ setDecoratorContext(true);
+ }
+ return expr;
}
- function parseParameterList(yieldContext, awaitContext, requireCompleteParameterList) {
- if (parseExpected(17)) {
- var savedYieldContext = inYieldContext();
- var savedAwaitContext = inAwaitContext();
- setYieldContext(yieldContext);
- setAwaitContext(awaitContext);
- var result = parseDelimitedList(16, parseParameter);
- setYieldContext(savedYieldContext);
- setAwaitContext(savedAwaitContext);
- if (!parseExpected(18) && requireCompleteParameterList) {
+ function parseInitializer(inParameter) {
+ if (token !== 56) {
+ if (scanner.hasPrecedingLineBreak() || (inParameter && token === 15) || !isStartOfExpression()) {
return undefined;
}
- return result;
}
- return requireCompleteParameterList ? undefined : createMissingList();
+ parseExpected(56);
+ return parseAssignmentExpressionOrHigher();
}
- function parseTypeMemberSemicolon() {
- if (parseOptional(24)) {
- return;
+ function parseAssignmentExpressionOrHigher() {
+ if (isYieldExpression()) {
+ return parseYieldExpression();
}
- parseSemicolon();
- }
- function parseSignatureMember(kind) {
- var node = createNode(kind);
- if (kind === 148) {
- parseExpected(92);
+ var arrowExpression = tryParseParenthesizedArrowFunctionExpression();
+ if (arrowExpression) {
+ return arrowExpression;
}
- fillSignature(54, false, false, false, node);
- parseTypeMemberSemicolon();
- return finishNode(node);
- }
- function isIndexSignature() {
- if (token !== 19) {
- return false;
+ var expr = parseBinaryExpressionOrHigher(0);
+ if (expr.kind === 69 && token === 34) {
+ return parseSimpleArrowFunctionExpression(expr);
}
- return lookAhead(isUnambiguouslyIndexSignature);
- }
- function isUnambiguouslyIndexSignature() {
- nextToken();
- if (token === 22 || token === 20) {
- return true;
+ if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) {
+ return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
}
- if (ts.isModifier(token)) {
- nextToken();
- if (isIdentifier()) {
+ return parseConditionalExpressionRest(expr);
+ }
+ function isYieldExpression() {
+ if (token === 114) {
+ if (inYieldContext()) {
return true;
}
+ return lookAhead(nextTokenIsIdentifierOrKeywordOrNumberOnSameLine);
}
- else if (!isIdentifier()) {
- return false;
+ return false;
+ }
+ function nextTokenIsIdentifierOnSameLine() {
+ nextToken();
+ return !scanner.hasPrecedingLineBreak() && isIdentifier();
+ }
+ function parseYieldExpression() {
+ var node = createNode(184);
+ nextToken();
+ if (!scanner.hasPrecedingLineBreak() &&
+ (token === 37 || isStartOfExpression())) {
+ node.asteriskToken = parseOptionalToken(37);
+ node.expression = parseAssignmentExpressionOrHigher();
+ return finishNode(node);
}
else {
- nextToken();
+ return finishNode(node);
}
- if (token === 54 || token === 24) {
- return true;
+ }
+ function parseSimpleArrowFunctionExpression(identifier) {
+ ts.Debug.assert(token === 34, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
+ var node = createNode(174, identifier.pos);
+ var parameter = createNode(138, identifier.pos);
+ parameter.name = identifier;
+ finishNode(parameter);
+ node.parameters = [parameter];
+ node.parameters.pos = parameter.pos;
+ node.parameters.end = parameter.end;
+ node.equalsGreaterThanToken = parseExpectedToken(34, false, ts.Diagnostics._0_expected, "=>");
+ node.body = parseArrowFunctionExpressionBody(false);
+ return finishNode(node);
+ }
+ function tryParseParenthesizedArrowFunctionExpression() {
+ var triState = isParenthesizedArrowFunctionExpression();
+ if (triState === 0) {
+ return undefined;
}
- if (token !== 53) {
- return false;
+ var arrowFunction = triState === 1
+ ? parseParenthesizedArrowFunctionExpressionHead(true)
+ : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead);
+ if (!arrowFunction) {
+ return undefined;
}
- nextToken();
- return token === 54 || token === 24 || token === 20;
+ var isAsync = !!(arrowFunction.flags & 256);
+ var lastToken = token;
+ arrowFunction.equalsGreaterThanToken = parseExpectedToken(34, false, ts.Diagnostics._0_expected, "=>");
+ arrowFunction.body = (lastToken === 34 || lastToken === 15)
+ ? parseArrowFunctionExpressionBody(isAsync)
+ : parseIdentifier();
+ return finishNode(arrowFunction);
}
- function parseIndexSignatureDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(149, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.parameters = parseBracketedList(16, parseParameter, 19, 20);
- node.type = parseTypeAnnotation();
- parseTypeMemberSemicolon();
- return finishNode(node);
+ function isParenthesizedArrowFunctionExpression() {
+ if (token === 17 || token === 25 || token === 118) {
+ return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
+ }
+ if (token === 34) {
+ return 1;
+ }
+ return 0;
}
- function parsePropertyOrMethodSignature() {
- var fullStart = scanner.getStartPos();
- var name = parsePropertyName();
- var questionToken = parseOptionalToken(53);
- if (token === 17 || token === 25) {
- var method = createNode(142, fullStart);
- method.name = name;
- method.questionToken = questionToken;
- fillSignature(54, false, false, false, method);
- parseTypeMemberSemicolon();
- return finishNode(method);
+ function isParenthesizedArrowFunctionExpressionWorker() {
+ if (token === 118) {
+ nextToken();
+ if (scanner.hasPrecedingLineBreak()) {
+ return 0;
+ }
+ if (token !== 17 && token !== 25) {
+ return 0;
+ }
+ }
+ var first = token;
+ var second = nextToken();
+ if (first === 17) {
+ if (second === 18) {
+ var third = nextToken();
+ switch (third) {
+ case 34:
+ case 54:
+ case 15:
+ return 1;
+ default:
+ return 0;
+ }
+ }
+ if (second === 19 || second === 15) {
+ return 2;
+ }
+ if (second === 22) {
+ return 1;
+ }
+ if (!isIdentifier()) {
+ return 0;
+ }
+ if (nextToken() === 54) {
+ return 1;
+ }
+ return 2;
}
else {
- var property = createNode(140, fullStart);
- property.name = name;
- property.questionToken = questionToken;
- property.type = parseTypeAnnotation();
- parseTypeMemberSemicolon();
- return finishNode(property);
- }
- }
- function isStartOfTypeMember() {
- switch (token) {
- case 17:
- case 25:
- case 19:
- return true;
- default:
- if (ts.isModifier(token)) {
- var result = lookAhead(isStartOfIndexSignatureDeclaration);
- if (result) {
- return result;
+ ts.Debug.assert(first === 25);
+ if (!isIdentifier()) {
+ return 0;
+ }
+ if (sourceFile.languageVariant === 1) {
+ var isArrowFunctionInJsx = lookAhead(function () {
+ var third = nextToken();
+ if (third === 83) {
+ var fourth = nextToken();
+ switch (fourth) {
+ case 56:
+ case 27:
+ return false;
+ default:
+ return true;
+ }
}
- }
- return isLiteralPropertyName() && lookAhead(isTypeMemberWithLiteralPropertyName);
- }
- }
- function isStartOfIndexSignatureDeclaration() {
- while (ts.isModifier(token)) {
- nextToken();
- }
- return isIndexSignature();
- }
- function isTypeMemberWithLiteralPropertyName() {
- nextToken();
- return token === 17 ||
- token === 25 ||
- token === 53 ||
- token === 54 ||
- canParseSemicolon();
- }
- function parseTypeMember() {
- switch (token) {
- case 17:
- case 25:
- return parseSignatureMember(147);
- case 19:
- return isIndexSignature()
- ? parseIndexSignatureDeclaration(scanner.getStartPos(), undefined, undefined)
- : parsePropertyOrMethodSignature();
- case 92:
- if (lookAhead(isStartOfConstructSignature)) {
- return parseSignatureMember(148);
- }
- case 9:
- case 8:
- return parsePropertyOrMethodSignature();
- default:
- if (ts.isModifier(token)) {
- var result = tryParse(parseIndexSignatureWithModifiers);
- if (result) {
- return result;
+ else if (third === 24) {
+ return true;
}
+ return false;
+ });
+ if (isArrowFunctionInJsx) {
+ return 1;
}
- if (ts.tokenIsIdentifierOrKeyword(token)) {
- return parsePropertyOrMethodSignature();
- }
+ return 0;
+ }
+ return 2;
}
}
- function parseIndexSignatureWithModifiers() {
- var fullStart = scanner.getStartPos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- return isIndexSignature()
- ? parseIndexSignatureDeclaration(fullStart, decorators, modifiers)
- : undefined;
- }
- function isStartOfConstructSignature() {
- nextToken();
- return token === 17 || token === 25;
+ function parsePossibleParenthesizedArrowFunctionExpressionHead() {
+ return parseParenthesizedArrowFunctionExpressionHead(false);
}
- function parseTypeLiteral() {
- var node = createNode(155);
- node.members = parseObjectTypeMembers();
- return finishNode(node);
+ function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) {
+ var node = createNode(174);
+ setModifiers(node, parseModifiersForArrowFunction());
+ var isAsync = !!(node.flags & 256);
+ fillSignature(54, false, isAsync, !allowAmbiguity, node);
+ if (!node.parameters) {
+ return undefined;
+ }
+ if (!allowAmbiguity && token !== 34 && token !== 15) {
+ return undefined;
+ }
+ return node;
}
- function parseObjectTypeMembers() {
- var members;
- if (parseExpected(15)) {
- members = parseList(4, parseTypeMember);
- parseExpected(16);
+ function parseArrowFunctionExpressionBody(isAsync) {
+ if (token === 15) {
+ return parseFunctionBlock(false, isAsync, false);
}
- else {
- members = createMissingList();
+ if (token !== 23 &&
+ token !== 87 &&
+ token !== 73 &&
+ isStartOfStatement() &&
+ !isStartOfExpressionStatement()) {
+ return parseFunctionBlock(false, isAsync, true);
}
- return members;
+ return isAsync
+ ? doInAwaitContext(parseAssignmentExpressionOrHigher)
+ : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
}
- function parseTupleType() {
- var node = createNode(157);
- node.elementTypes = parseBracketedList(19, parseType, 19, 20);
+ function parseConditionalExpressionRest(leftOperand) {
+ var questionToken = parseOptionalToken(53);
+ if (!questionToken) {
+ return leftOperand;
+ }
+ var node = createNode(182, leftOperand.pos);
+ node.condition = leftOperand;
+ node.questionToken = questionToken;
+ node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
+ node.colonToken = parseExpectedToken(54, false, ts.Diagnostics._0_expected, ts.tokenToString(54));
+ node.whenFalse = parseAssignmentExpressionOrHigher();
return finishNode(node);
}
- function parseParenthesizedType() {
- var node = createNode(160);
- parseExpected(17);
- node.type = parseType();
- parseExpected(18);
- return finishNode(node);
+ function parseBinaryExpressionOrHigher(precedence) {
+ var leftOperand = parseUnaryExpressionOrHigher();
+ return parseBinaryExpressionRest(precedence, leftOperand);
}
- function parseFunctionOrConstructorType(kind) {
- var node = createNode(kind);
- if (kind === 153) {
- parseExpected(92);
- }
- fillSignature(34, false, false, false, node);
- return finishNode(node);
+ function isInOrOfKeyword(t) {
+ return t === 90 || t === 134;
}
- function parseKeywordAndNoDot() {
- var node = parseTokenNode();
- return token === 21 ? undefined : node;
+ function parseBinaryExpressionRest(precedence, leftOperand) {
+ while (true) {
+ reScanGreaterToken();
+ var newPrecedence = getBinaryOperatorPrecedence();
+ var consumeCurrentOperator = token === 38 ?
+ newPrecedence >= precedence :
+ newPrecedence > precedence;
+ if (!consumeCurrentOperator) {
+ break;
+ }
+ if (token === 90 && inDisallowInContext()) {
+ break;
+ }
+ if (token === 116) {
+ if (scanner.hasPrecedingLineBreak()) {
+ break;
+ }
+ else {
+ nextToken();
+ leftOperand = makeAsExpression(leftOperand, parseType());
+ }
+ }
+ else {
+ leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+ }
+ }
+ return leftOperand;
}
- function parseNonArrayType() {
- switch (token) {
- case 117:
- case 130:
- case 128:
- case 120:
- case 131:
- var node = tryParse(parseKeywordAndNoDot);
- return node || parseTypeReferenceOrTypePredicate();
- case 103:
- case 97:
- return parseTokenNode();
- case 101:
- return parseTypeQuery();
- case 15:
- return parseTypeLiteral();
- case 19:
- return parseTupleType();
- case 17:
- return parseParenthesizedType();
- default:
- return parseTypeReferenceOrTypePredicate();
+ function isBinaryOperator() {
+ if (inDisallowInContext() && token === 90) {
+ return false;
}
+ return getBinaryOperatorPrecedence() > 0;
}
- function isStartOfType() {
+ function getBinaryOperatorPrecedence() {
switch (token) {
- case 117:
- case 130:
- case 128:
- case 120:
- case 131:
- case 103:
- case 97:
- case 101:
- case 15:
- case 19:
- case 25:
- case 92:
- return true;
- case 17:
- return lookAhead(isStartOfParenthesizedOrFunctionType);
- default:
- return isIdentifier();
+ case 52:
+ return 1;
+ case 51:
+ return 2;
+ case 47:
+ return 3;
+ case 48:
+ return 4;
+ case 46:
+ return 5;
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ return 6;
+ case 25:
+ case 27:
+ case 28:
+ case 29:
+ case 91:
+ case 90:
+ case 116:
+ return 7;
+ case 43:
+ case 44:
+ case 45:
+ return 8;
+ case 35:
+ case 36:
+ return 9;
+ case 37:
+ case 39:
+ case 40:
+ return 10;
+ case 38:
+ return 11;
}
+ return -1;
}
- function isStartOfParenthesizedOrFunctionType() {
- nextToken();
- return token === 18 || isStartOfParameter() || isStartOfType();
- }
- function parseArrayTypeOrHigher() {
- var type = parseNonArrayType();
- while (!scanner.hasPrecedingLineBreak() && parseOptional(19)) {
- parseExpected(20);
- var node = createNode(156, type.pos);
- node.elementType = type;
- type = finishNode(node);
- }
- return type;
+ function makeBinaryExpression(left, operatorToken, right) {
+ var node = createNode(181, left.pos);
+ node.left = left;
+ node.operatorToken = operatorToken;
+ node.right = right;
+ return finishNode(node);
}
- function parseUnionOrIntersectionType(kind, parseConstituentType, operator) {
- var type = parseConstituentType();
- if (token === operator) {
- var types = [type];
- types.pos = type.pos;
- while (parseOptional(operator)) {
- types.push(parseConstituentType());
- }
- types.end = getNodeEnd();
- var node = createNode(kind, type.pos);
- node.types = types;
- type = finishNode(node);
- }
- return type;
+ function makeAsExpression(left, right) {
+ var node = createNode(189, left.pos);
+ node.expression = left;
+ node.type = right;
+ return finishNode(node);
}
- function parseIntersectionTypeOrHigher() {
- return parseUnionOrIntersectionType(159, parseArrayTypeOrHigher, 46);
+ function parsePrefixUnaryExpression() {
+ var node = createNode(179);
+ node.operator = token;
+ nextToken();
+ node.operand = parseSimpleUnaryExpression();
+ return finishNode(node);
}
- function parseUnionTypeOrHigher() {
- return parseUnionOrIntersectionType(158, parseIntersectionTypeOrHigher, 47);
+ function parseDeleteExpression() {
+ var node = createNode(175);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
}
- function isStartOfFunctionType() {
- if (token === 25) {
- return true;
- }
- return token === 17 && lookAhead(isUnambiguouslyStartOfFunctionType);
+ function parseTypeOfExpression() {
+ var node = createNode(176);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
}
- function isUnambiguouslyStartOfFunctionType() {
+ function parseVoidExpression() {
+ var node = createNode(177);
nextToken();
- if (token === 18 || token === 22) {
- return true;
- }
- if (isIdentifier() || ts.isModifier(token)) {
- nextToken();
- if (token === 54 || token === 24 ||
- token === 53 || token === 56 ||
- isIdentifier() || ts.isModifier(token)) {
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function isAwaitExpression() {
+ if (token === 119) {
+ if (inAwaitContext()) {
return true;
}
- if (token === 18) {
- nextToken();
- if (token === 34) {
- return true;
- }
- }
+ return lookAhead(nextTokenIsIdentifierOnSameLine);
}
return false;
}
- function parseType() {
- return doOutsideOfContext(10, parseTypeWorker);
+ function parseAwaitExpression() {
+ var node = createNode(178);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
}
- function parseTypeWorker() {
- if (isStartOfFunctionType()) {
- return parseFunctionOrConstructorType(152);
+ function parseUnaryExpressionOrHigher() {
+ if (isAwaitExpression()) {
+ return parseAwaitExpression();
}
- if (token === 92) {
- return parseFunctionOrConstructorType(153);
+ if (isIncrementExpression()) {
+ var incrementExpression = parseIncrementExpression();
+ return token === 38 ?
+ parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
+ incrementExpression;
}
- return parseUnionTypeOrHigher();
- }
- function parseTypeAnnotation() {
- return parseOptional(54) ? parseType() : undefined;
- }
- function isStartOfLeftHandSideExpression() {
- switch (token) {
- case 97:
- case 95:
- case 93:
- case 99:
- case 84:
- case 8:
- case 9:
- case 11:
- case 12:
- case 17:
- case 19:
- case 15:
- case 87:
- case 73:
- case 92:
- case 39:
- case 61:
- case 69:
- return true;
- default:
- return isIdentifier();
+ var unaryOperator = token;
+ var simpleUnaryExpression = parseSimpleUnaryExpression();
+ if (token === 38) {
+ var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
+ if (simpleUnaryExpression.kind === 171) {
+ parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
+ }
+ else {
+ parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
+ }
}
+ return simpleUnaryExpression;
}
- function isStartOfExpression() {
- if (isStartOfLeftHandSideExpression()) {
- return true;
- }
+ function parseSimpleUnaryExpression() {
switch (token) {
case 35:
case 36:
case 50:
case 49:
+ return parsePrefixUnaryExpression();
case 78:
+ return parseDeleteExpression();
case 101:
+ return parseTypeOfExpression();
case 103:
- case 41:
- case 42:
+ return parseVoidExpression();
case 25:
- case 119:
- case 114:
- return true;
+ return parseTypeAssertion();
default:
- if (isBinaryOperator()) {
- return true;
- }
- return isIdentifier();
- }
- }
- function isStartOfExpressionStatement() {
- return token !== 15 &&
- token !== 87 &&
- token !== 73 &&
- token !== 55 &&
- isStartOfExpression();
- }
- function allowInAndParseExpression() {
- return allowInAnd(parseExpression);
- }
- function parseExpression() {
- var saveDecoratorContext = inDecoratorContext();
- if (saveDecoratorContext) {
- setDecoratorContext(false);
- }
- var expr = parseAssignmentExpressionOrHigher();
- var operatorToken;
- while ((operatorToken = parseOptionalToken(24))) {
- expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
- }
- if (saveDecoratorContext) {
- setDecoratorContext(true);
- }
- return expr;
- }
- function parseInitializer(inParameter) {
- if (token !== 56) {
- if (scanner.hasPrecedingLineBreak() || (inParameter && token === 15) || !isStartOfExpression()) {
- return undefined;
- }
- }
- parseExpected(56);
- return parseAssignmentExpressionOrHigher();
- }
- function parseAssignmentExpressionOrHigher() {
- if (isYieldExpression()) {
- return parseYieldExpression();
- }
- var arrowExpression = tryParseParenthesizedArrowFunctionExpression();
- if (arrowExpression) {
- return arrowExpression;
- }
- var expr = parseBinaryExpressionOrHigher(0);
- if (expr.kind === 69 && token === 34) {
- return parseSimpleArrowFunctionExpression(expr);
- }
- if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) {
- return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
+ return parseIncrementExpression();
}
- return parseConditionalExpressionRest(expr);
}
- function isYieldExpression() {
- if (token === 114) {
- if (inYieldContext()) {
+ function isIncrementExpression() {
+ switch (token) {
+ case 35:
+ case 36:
+ case 50:
+ case 49:
+ case 78:
+ case 101:
+ case 103:
+ return false;
+ case 25:
+ if (sourceFile.languageVariant !== 1) {
+ return false;
+ }
+ default:
return true;
- }
- return lookAhead(nextTokenIsIdentifierOrKeywordOrNumberOnSameLine);
}
- return false;
- }
- function nextTokenIsIdentifierOnSameLine() {
- nextToken();
- return !scanner.hasPrecedingLineBreak() && isIdentifier();
}
- function parseYieldExpression() {
- var node = createNode(184);
- nextToken();
- if (!scanner.hasPrecedingLineBreak() &&
- (token === 37 || isStartOfExpression())) {
- node.asteriskToken = parseOptionalToken(37);
- node.expression = parseAssignmentExpressionOrHigher();
+ function parseIncrementExpression() {
+ if (token === 41 || token === 42) {
+ var node = createNode(179);
+ node.operator = token;
+ nextToken();
+ node.operand = parseLeftHandSideExpressionOrHigher();
return finishNode(node);
}
- else {
+ else if (sourceFile.languageVariant === 1 && token === 25 && lookAhead(nextTokenIsIdentifierOrKeyword)) {
+ return parseJsxElementOrSelfClosingElement(true);
+ }
+ var expression = parseLeftHandSideExpressionOrHigher();
+ ts.Debug.assert(ts.isLeftHandSideExpression(expression));
+ if ((token === 41 || token === 42) && !scanner.hasPrecedingLineBreak()) {
+ var node = createNode(180, expression.pos);
+ node.operand = expression;
+ node.operator = token;
+ nextToken();
return finishNode(node);
}
+ return expression;
}
- function parseSimpleArrowFunctionExpression(identifier) {
- ts.Debug.assert(token === 34, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
- var node = createNode(174, identifier.pos);
- var parameter = createNode(138, identifier.pos);
- parameter.name = identifier;
- finishNode(parameter);
- node.parameters = [parameter];
- node.parameters.pos = parameter.pos;
- node.parameters.end = parameter.end;
- node.equalsGreaterThanToken = parseExpectedToken(34, false, ts.Diagnostics._0_expected, "=>");
- node.body = parseArrowFunctionExpressionBody(false);
+ function parseLeftHandSideExpressionOrHigher() {
+ var expression = token === 95
+ ? parseSuperExpression()
+ : parseMemberExpressionOrHigher();
+ return parseCallExpressionRest(expression);
+ }
+ function parseMemberExpressionOrHigher() {
+ var expression = parsePrimaryExpression();
+ return parseMemberExpressionRest(expression);
+ }
+ function parseSuperExpression() {
+ var expression = parseTokenNode();
+ if (token === 17 || token === 21 || token === 19) {
+ return expression;
+ }
+ var node = createNode(166, expression.pos);
+ node.expression = expression;
+ node.dotToken = parseExpectedToken(21, false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
+ node.name = parseRightSideOfDot(true);
return finishNode(node);
}
- function tryParseParenthesizedArrowFunctionExpression() {
- var triState = isParenthesizedArrowFunctionExpression();
- if (triState === 0) {
- return undefined;
+ function parseJsxElementOrSelfClosingElement(inExpressionContext) {
+ var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
+ var result;
+ if (opening.kind === 235) {
+ var node = createNode(233, opening.pos);
+ node.openingElement = opening;
+ node.children = parseJsxChildren(node.openingElement.tagName);
+ node.closingElement = parseJsxClosingElement(inExpressionContext);
+ result = finishNode(node);
}
- var arrowFunction = triState === 1
- ? parseParenthesizedArrowFunctionExpressionHead(true)
- : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead);
- if (!arrowFunction) {
- return undefined;
+ else {
+ ts.Debug.assert(opening.kind === 234);
+ result = opening;
}
- var isAsync = !!(arrowFunction.flags & 256);
- var lastToken = token;
- arrowFunction.equalsGreaterThanToken = parseExpectedToken(34, false, ts.Diagnostics._0_expected, "=>");
- arrowFunction.body = (lastToken === 34 || lastToken === 15)
- ? parseArrowFunctionExpressionBody(isAsync)
- : parseIdentifier();
- return finishNode(arrowFunction);
- }
- function isParenthesizedArrowFunctionExpression() {
- if (token === 17 || token === 25 || token === 118) {
- return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
+ if (inExpressionContext && token === 25) {
+ var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(true); });
+ if (invalidElement) {
+ parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
+ var badNode = createNode(181, result.pos);
+ badNode.end = invalidElement.end;
+ badNode.left = result;
+ badNode.right = invalidElement;
+ badNode.operatorToken = createMissingNode(24, false, undefined);
+ badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
+ return badNode;
+ }
}
- if (token === 34) {
- return 1;
+ return result;
+ }
+ function parseJsxText() {
+ var node = createNode(236, scanner.getStartPos());
+ token = scanner.scanJsxToken();
+ return finishNode(node);
+ }
+ function parseJsxChild() {
+ switch (token) {
+ case 236:
+ return parseJsxText();
+ case 15:
+ return parseJsxExpression(false);
+ case 25:
+ return parseJsxElementOrSelfClosingElement(false);
}
- return 0;
+ ts.Debug.fail("Unknown JSX child kind " + token);
}
- function isParenthesizedArrowFunctionExpressionWorker() {
- if (token === 118) {
- nextToken();
- if (scanner.hasPrecedingLineBreak()) {
- return 0;
+ function parseJsxChildren(openingTagName) {
+ var result = [];
+ result.pos = scanner.getStartPos();
+ var saveParsingContext = parsingContext;
+ parsingContext |= 1 << 14;
+ while (true) {
+ token = scanner.reScanJsxToken();
+ if (token === 26) {
+ break;
}
- if (token !== 17 && token !== 25) {
- return 0;
+ else if (token === 1) {
+ parseErrorAtCurrentToken(ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, openingTagName));
+ break;
}
+ result.push(parseJsxChild());
}
- var first = token;
- var second = nextToken();
- if (first === 17) {
- if (second === 18) {
- var third = nextToken();
- switch (third) {
- case 34:
- case 54:
- case 15:
- return 1;
- default:
- return 0;
- }
- }
- if (second === 19 || second === 15) {
- return 2;
- }
- if (second === 22) {
- return 1;
- }
- if (!isIdentifier()) {
- return 0;
- }
- if (nextToken() === 54) {
- return 1;
- }
- return 2;
+ result.end = scanner.getTokenPos();
+ parsingContext = saveParsingContext;
+ return result;
+ }
+ function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
+ var fullStart = scanner.getStartPos();
+ parseExpected(25);
+ var tagName = parseJsxElementName();
+ var attributes = parseList(13, parseJsxAttribute);
+ var node;
+ if (token === 27) {
+ node = createNode(235, fullStart);
+ scanJsxText();
}
else {
- ts.Debug.assert(first === 25);
- if (!isIdentifier()) {
- return 0;
+ parseExpected(39);
+ if (inExpressionContext) {
+ parseExpected(27);
}
- if (sourceFile.languageVariant === 1) {
- var isArrowFunctionInJsx = lookAhead(function () {
- var third = nextToken();
- if (third === 83) {
- var fourth = nextToken();
- switch (fourth) {
- case 56:
- case 27:
- return false;
- default:
- return true;
- }
- }
- else if (third === 24) {
- return true;
- }
- return false;
- });
- if (isArrowFunctionInJsx) {
- return 1;
- }
- return 0;
+ else {
+ parseExpected(27, undefined, false);
+ scanJsxText();
}
- return 2;
+ node = createNode(234, fullStart);
}
+ node.tagName = tagName;
+ node.attributes = attributes;
+ return finishNode(node);
}
- function parsePossibleParenthesizedArrowFunctionExpressionHead() {
- return parseParenthesizedArrowFunctionExpressionHead(false);
+ function parseJsxElementName() {
+ scanJsxIdentifier();
+ var elementName = parseIdentifierName();
+ while (parseOptional(21)) {
+ scanJsxIdentifier();
+ var node = createNode(135, elementName.pos);
+ node.left = elementName;
+ node.right = parseIdentifierName();
+ elementName = finishNode(node);
+ }
+ return elementName;
}
- function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) {
- var node = createNode(174);
- setModifiers(node, parseModifiersForArrowFunction());
- var isAsync = !!(node.flags & 256);
- fillSignature(54, false, isAsync, !allowAmbiguity, node);
- if (!node.parameters) {
- return undefined;
+ function parseJsxExpression(inExpressionContext) {
+ var node = createNode(240);
+ parseExpected(15);
+ if (token !== 16) {
+ node.expression = parseExpression();
}
- if (!allowAmbiguity && token !== 34 && token !== 15) {
- return undefined;
+ if (inExpressionContext) {
+ parseExpected(16);
+ }
+ else {
+ parseExpected(16, undefined, false);
+ scanJsxText();
}
- return node;
+ return finishNode(node);
}
- function parseArrowFunctionExpressionBody(isAsync) {
+ function parseJsxAttribute() {
if (token === 15) {
- return parseFunctionBlock(false, isAsync, false);
+ return parseJsxSpreadAttribute();
}
- if (token !== 23 &&
- token !== 87 &&
- token !== 73 &&
- isStartOfStatement() &&
- !isStartOfExpressionStatement()) {
- return parseFunctionBlock(false, isAsync, true);
+ scanJsxIdentifier();
+ var node = createNode(238);
+ node.name = parseIdentifierName();
+ if (parseOptional(56)) {
+ switch (token) {
+ case 9:
+ node.initializer = parseLiteralNode();
+ break;
+ default:
+ node.initializer = parseJsxExpression(true);
+ break;
+ }
}
- return isAsync
- ? doInAwaitContext(parseAssignmentExpressionOrHigher)
- : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
+ return finishNode(node);
}
- function parseConditionalExpressionRest(leftOperand) {
- var questionToken = parseOptionalToken(53);
- if (!questionToken) {
- return leftOperand;
- }
- var node = createNode(182, leftOperand.pos);
- node.condition = leftOperand;
- node.questionToken = questionToken;
- node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
- node.colonToken = parseExpectedToken(54, false, ts.Diagnostics._0_expected, ts.tokenToString(54));
- node.whenFalse = parseAssignmentExpressionOrHigher();
+ function parseJsxSpreadAttribute() {
+ var node = createNode(239);
+ parseExpected(15);
+ parseExpected(22);
+ node.expression = parseExpression();
+ parseExpected(16);
return finishNode(node);
}
- function parseBinaryExpressionOrHigher(precedence) {
- var leftOperand = parseUnaryExpressionOrHigher();
- return parseBinaryExpressionRest(precedence, leftOperand);
+ function parseJsxClosingElement(inExpressionContext) {
+ var node = createNode(237);
+ parseExpected(26);
+ node.tagName = parseJsxElementName();
+ if (inExpressionContext) {
+ parseExpected(27);
+ }
+ else {
+ parseExpected(27, undefined, false);
+ scanJsxText();
+ }
+ return finishNode(node);
}
- function isInOrOfKeyword(t) {
- return t === 90 || t === 134;
+ function parseTypeAssertion() {
+ var node = createNode(171);
+ parseExpected(25);
+ node.type = parseType();
+ parseExpected(27);
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
}
- function parseBinaryExpressionRest(precedence, leftOperand) {
+ function parseMemberExpressionRest(expression) {
while (true) {
- reScanGreaterToken();
- var newPrecedence = getBinaryOperatorPrecedence();
- var consumeCurrentOperator = token === 38 ?
- newPrecedence >= precedence :
- newPrecedence > precedence;
- if (!consumeCurrentOperator) {
- break;
- }
- if (token === 90 && inDisallowInContext()) {
- break;
+ var dotToken = parseOptionalToken(21);
+ if (dotToken) {
+ var propertyAccess = createNode(166, expression.pos);
+ propertyAccess.expression = expression;
+ propertyAccess.dotToken = dotToken;
+ propertyAccess.name = parseRightSideOfDot(true);
+ expression = finishNode(propertyAccess);
+ continue;
}
- if (token === 116) {
- if (scanner.hasPrecedingLineBreak()) {
- break;
+ if (!inDecoratorContext() && parseOptional(19)) {
+ var indexedAccess = createNode(167, expression.pos);
+ indexedAccess.expression = expression;
+ if (token !== 20) {
+ indexedAccess.argumentExpression = allowInAnd(parseExpression);
+ if (indexedAccess.argumentExpression.kind === 9 || indexedAccess.argumentExpression.kind === 8) {
+ var literal = indexedAccess.argumentExpression;
+ literal.text = internIdentifier(literal.text);
+ }
}
- else {
- nextToken();
- leftOperand = makeAsExpression(leftOperand, parseType());
+ parseExpected(20);
+ expression = finishNode(indexedAccess);
+ continue;
+ }
+ if (token === 11 || token === 12) {
+ var tagExpression = createNode(170, expression.pos);
+ tagExpression.tag = expression;
+ tagExpression.template = token === 11
+ ? parseLiteralNode()
+ : parseTemplateExpression();
+ expression = finishNode(tagExpression);
+ continue;
+ }
+ return expression;
+ }
+ }
+ function parseCallExpressionRest(expression) {
+ while (true) {
+ expression = parseMemberExpressionRest(expression);
+ if (token === 25) {
+ var typeArguments = tryParse(parseTypeArgumentsInExpression);
+ if (!typeArguments) {
+ return expression;
}
+ var callExpr = createNode(168, expression.pos);
+ callExpr.expression = expression;
+ callExpr.typeArguments = typeArguments;
+ callExpr.arguments = parseArgumentList();
+ expression = finishNode(callExpr);
+ continue;
}
- else {
- leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+ else if (token === 17) {
+ var callExpr = createNode(168, expression.pos);
+ callExpr.expression = expression;
+ callExpr.arguments = parseArgumentList();
+ expression = finishNode(callExpr);
+ continue;
}
+ return expression;
}
- return leftOperand;
}
- function isBinaryOperator() {
- if (inDisallowInContext() && token === 90) {
- return false;
+ function parseArgumentList() {
+ parseExpected(17);
+ var result = parseDelimitedList(11, parseArgumentExpression);
+ parseExpected(18);
+ return result;
+ }
+ function parseTypeArgumentsInExpression() {
+ if (!parseOptional(25)) {
+ return undefined;
}
- return getBinaryOperatorPrecedence() > 0;
+ var typeArguments = parseDelimitedList(18, parseType);
+ if (!parseExpected(27)) {
+ return undefined;
+ }
+ return typeArguments && canFollowTypeArgumentsInExpression()
+ ? typeArguments
+ : undefined;
}
- function getBinaryOperatorPrecedence() {
+ function canFollowTypeArgumentsInExpression() {
switch (token) {
- case 52:
- return 1;
- case 51:
- return 2;
- case 47:
- return 3;
- case 48:
- return 4;
- case 46:
- return 5;
+ case 17:
+ case 21:
+ case 18:
+ case 20:
+ case 54:
+ case 23:
+ case 53:
case 30:
- case 31:
case 32:
+ case 31:
case 33:
- return 6;
- case 25:
- case 27:
- case 28:
- case 29:
- case 91:
- case 90:
- case 116:
- return 7;
- case 43:
- case 44:
- case 45:
- return 8;
- case 35:
- case 36:
- return 9;
- case 37:
+ case 51:
+ case 52:
+ case 48:
+ case 46:
+ case 47:
+ case 16:
+ case 1:
+ return true;
+ case 24:
+ case 15:
+ default:
+ return false;
+ }
+ }
+ function parsePrimaryExpression() {
+ switch (token) {
+ case 8:
+ case 9:
+ case 11:
+ return parseLiteralNode();
+ case 97:
+ case 95:
+ case 93:
+ case 99:
+ case 84:
+ return parseTokenNode();
+ case 17:
+ return parseParenthesizedExpression();
+ case 19:
+ return parseArrayLiteralExpression();
+ case 15:
+ return parseObjectLiteralExpression();
+ case 118:
+ if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
+ break;
+ }
+ return parseFunctionExpression();
+ case 73:
+ return parseClassExpression();
+ case 87:
+ return parseFunctionExpression();
+ case 92:
+ return parseNewExpression();
case 39:
- case 40:
- return 10;
- case 38:
- return 11;
+ case 61:
+ if (reScanSlashToken() === 10) {
+ return parseLiteralNode();
+ }
+ break;
+ case 12:
+ return parseTemplateExpression();
}
- return -1;
- }
- function makeBinaryExpression(left, operatorToken, right) {
- var node = createNode(181, left.pos);
- node.left = left;
- node.operatorToken = operatorToken;
- node.right = right;
- return finishNode(node);
+ return parseIdentifier(ts.Diagnostics.Expression_expected);
}
- function makeAsExpression(left, right) {
- var node = createNode(189, left.pos);
- node.expression = left;
- node.type = right;
+ function parseParenthesizedExpression() {
+ var node = createNode(172);
+ parseExpected(17);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18);
return finishNode(node);
}
- function parsePrefixUnaryExpression() {
- var node = createNode(179);
- node.operator = token;
- nextToken();
- node.operand = parseSimpleUnaryExpression();
+ function parseSpreadElement() {
+ var node = createNode(185);
+ parseExpected(22);
+ node.expression = parseAssignmentExpressionOrHigher();
return finishNode(node);
}
- function parseDeleteExpression() {
- var node = createNode(175);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function parseArgumentOrArrayLiteralElement() {
+ return token === 22 ? parseSpreadElement() :
+ token === 24 ? createNode(187) :
+ parseAssignmentExpressionOrHigher();
}
- function parseTypeOfExpression() {
- var node = createNode(176);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function parseArgumentExpression() {
+ return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
}
- function parseVoidExpression() {
- var node = createNode(177);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
+ function parseArrayLiteralExpression() {
+ var node = createNode(164);
+ parseExpected(19);
+ if (scanner.hasPrecedingLineBreak())
+ node.flags |= 1024;
+ node.elements = parseDelimitedList(15, parseArgumentOrArrayLiteralElement);
+ parseExpected(20);
return finishNode(node);
}
- function isAwaitExpression() {
- if (token === 119) {
- if (inAwaitContext()) {
- return true;
- }
- return lookAhead(nextTokenIsIdentifierOnSameLine);
+ function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
+ if (parseContextualModifier(123)) {
+ return parseAccessorDeclaration(145, fullStart, decorators, modifiers);
}
- return false;
- }
- function parseAwaitExpression() {
- var node = createNode(178);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ else if (parseContextualModifier(129)) {
+ return parseAccessorDeclaration(146, fullStart, decorators, modifiers);
+ }
+ return undefined;
}
- function parseUnaryExpressionOrHigher() {
- if (isAwaitExpression()) {
- return parseAwaitExpression();
+ function parseObjectLiteralElement() {
+ var fullStart = scanner.getStartPos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
+ if (accessor) {
+ return accessor;
}
- if (isIncrementExpression()) {
- var incrementExpression = parseIncrementExpression();
- return token === 38 ?
- parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
- incrementExpression;
+ var asteriskToken = parseOptionalToken(37);
+ var tokenIsIdentifier = isIdentifier();
+ var nameToken = token;
+ var propertyName = parsePropertyName();
+ var questionToken = parseOptionalToken(53);
+ if (asteriskToken || token === 17 || token === 25) {
+ return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
}
- var unaryOperator = token;
- var simpleUnaryExpression = parseSimpleUnaryExpression();
- if (token === 38) {
- var diagnostic;
- var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
- if (simpleUnaryExpression.kind === 171) {
- parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
- }
- else {
- parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
+ var isShorthandPropertyAssignment = tokenIsIdentifier && (token === 24 || token === 16 || token === 56);
+ if (isShorthandPropertyAssignment) {
+ var shorthandDeclaration = createNode(246, fullStart);
+ shorthandDeclaration.name = propertyName;
+ shorthandDeclaration.questionToken = questionToken;
+ var equalsToken = parseOptionalToken(56);
+ if (equalsToken) {
+ shorthandDeclaration.equalsToken = equalsToken;
+ shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
}
+ return finishNode(shorthandDeclaration);
}
- return simpleUnaryExpression;
- }
- function parseSimpleUnaryExpression() {
- switch (token) {
- case 35:
- case 36:
- case 50:
- case 49:
- return parsePrefixUnaryExpression();
- case 78:
- return parseDeleteExpression();
- case 101:
- return parseTypeOfExpression();
- case 103:
- return parseVoidExpression();
- case 25:
- return parseTypeAssertion();
- default:
- return parseIncrementExpression();
+ else {
+ var propertyAssignment = createNode(245, fullStart);
+ propertyAssignment.name = propertyName;
+ propertyAssignment.questionToken = questionToken;
+ parseExpected(54);
+ propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
+ return finishNode(propertyAssignment);
}
}
- function isIncrementExpression() {
- switch (token) {
- case 35:
- case 36:
- case 50:
- case 49:
- case 78:
- case 101:
- case 103:
- return false;
- case 25:
- if (sourceFile.languageVariant !== 1) {
- return false;
- }
- default:
- return true;
+ function parseObjectLiteralExpression() {
+ var node = createNode(165);
+ parseExpected(15);
+ if (scanner.hasPrecedingLineBreak()) {
+ node.flags |= 1024;
}
+ node.properties = parseDelimitedList(12, parseObjectLiteralElement, true);
+ parseExpected(16);
+ return finishNode(node);
}
- function parseIncrementExpression() {
- if (token === 41 || token === 42) {
- var node = createNode(179);
- node.operator = token;
- nextToken();
- node.operand = parseLeftHandSideExpressionOrHigher();
- return finishNode(node);
- }
- else if (sourceFile.languageVariant === 1 && token === 25 && lookAhead(nextTokenIsIdentifierOrKeyword)) {
- return parseJsxElementOrSelfClosingElement(true);
+ function parseFunctionExpression() {
+ var saveDecoratorContext = inDecoratorContext();
+ if (saveDecoratorContext) {
+ setDecoratorContext(false);
}
- var expression = parseLeftHandSideExpressionOrHigher();
- ts.Debug.assert(ts.isLeftHandSideExpression(expression));
- if ((token === 41 || token === 42) && !scanner.hasPrecedingLineBreak()) {
- var node = createNode(180, expression.pos);
- node.operand = expression;
- node.operator = token;
- nextToken();
- return finishNode(node);
+ var node = createNode(173);
+ setModifiers(node, parseModifiers());
+ parseExpected(87);
+ node.asteriskToken = parseOptionalToken(37);
+ var isGenerator = !!node.asteriskToken;
+ var isAsync = !!(node.flags & 256);
+ node.name =
+ isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
+ isGenerator ? doInYieldContext(parseOptionalIdentifier) :
+ isAsync ? doInAwaitContext(parseOptionalIdentifier) :
+ parseOptionalIdentifier();
+ fillSignature(54, isGenerator, isAsync, false, node);
+ node.body = parseFunctionBlock(isGenerator, isAsync, false);
+ if (saveDecoratorContext) {
+ setDecoratorContext(true);
}
- return expression;
- }
- function parseLeftHandSideExpressionOrHigher() {
- var expression = token === 95
- ? parseSuperExpression()
- : parseMemberExpressionOrHigher();
- return parseCallExpressionRest(expression);
+ return finishNode(node);
}
- function parseMemberExpressionOrHigher() {
- var expression = parsePrimaryExpression();
- return parseMemberExpressionRest(expression);
+ function parseOptionalIdentifier() {
+ return isIdentifier() ? parseIdentifier() : undefined;
}
- function parseSuperExpression() {
- var expression = parseTokenNode();
- if (token === 17 || token === 21 || token === 19) {
- return expression;
+ function parseNewExpression() {
+ var node = createNode(169);
+ parseExpected(92);
+ node.expression = parseMemberExpressionOrHigher();
+ node.typeArguments = tryParse(parseTypeArgumentsInExpression);
+ if (node.typeArguments || token === 17) {
+ node.arguments = parseArgumentList();
}
- var node = createNode(166, expression.pos);
- node.expression = expression;
- node.dotToken = parseExpectedToken(21, false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
- node.name = parseRightSideOfDot(true);
return finishNode(node);
}
- function parseJsxElementOrSelfClosingElement(inExpressionContext) {
- var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
- var result;
- if (opening.kind === 235) {
- var node = createNode(233, opening.pos);
- node.openingElement = opening;
- node.children = parseJsxChildren(node.openingElement.tagName);
- node.closingElement = parseJsxClosingElement(inExpressionContext);
- result = finishNode(node);
+ function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
+ var node = createNode(192);
+ if (parseExpected(15, diagnosticMessage) || ignoreMissingOpenBrace) {
+ node.statements = parseList(1, parseStatement);
+ parseExpected(16);
}
else {
- ts.Debug.assert(opening.kind === 234);
- result = opening;
+ node.statements = createMissingList();
+ }
+ return finishNode(node);
+ }
+ function parseFunctionBlock(allowYield, allowAwait, ignoreMissingOpenBrace, diagnosticMessage) {
+ var savedYieldContext = inYieldContext();
+ setYieldContext(allowYield);
+ var savedAwaitContext = inAwaitContext();
+ setAwaitContext(allowAwait);
+ var saveDecoratorContext = inDecoratorContext();
+ if (saveDecoratorContext) {
+ setDecoratorContext(false);
}
- if (inExpressionContext && token === 25) {
- var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(true); });
- if (invalidElement) {
- parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
- var badNode = createNode(181, result.pos);
- badNode.end = invalidElement.end;
- badNode.left = result;
- badNode.right = invalidElement;
- badNode.operatorToken = createMissingNode(24, false, undefined);
- badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
- return badNode;
- }
+ var block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
+ if (saveDecoratorContext) {
+ setDecoratorContext(true);
}
- return result;
+ setYieldContext(savedYieldContext);
+ setAwaitContext(savedAwaitContext);
+ return block;
}
- function parseJsxText() {
- var node = createNode(236, scanner.getStartPos());
- token = scanner.scanJsxToken();
+ function parseEmptyStatement() {
+ var node = createNode(194);
+ parseExpected(23);
return finishNode(node);
}
- function parseJsxChild() {
- switch (token) {
- case 236:
- return parseJsxText();
- case 15:
- return parseJsxExpression(false);
- case 25:
- return parseJsxElementOrSelfClosingElement(false);
- }
- ts.Debug.fail("Unknown JSX child kind " + token);
+ function parseIfStatement() {
+ var node = createNode(196);
+ parseExpected(88);
+ parseExpected(17);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18);
+ node.thenStatement = parseStatement();
+ node.elseStatement = parseOptional(80) ? parseStatement() : undefined;
+ return finishNode(node);
}
- function parseJsxChildren(openingTagName) {
- var result = [];
- result.pos = scanner.getStartPos();
- var saveParsingContext = parsingContext;
- parsingContext |= 1 << 14;
- while (true) {
- token = scanner.reScanJsxToken();
- if (token === 26) {
- break;
+ function parseDoStatement() {
+ var node = createNode(197);
+ parseExpected(79);
+ node.statement = parseStatement();
+ parseExpected(104);
+ parseExpected(17);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18);
+ parseOptional(23);
+ return finishNode(node);
+ }
+ function parseWhileStatement() {
+ var node = createNode(198);
+ parseExpected(104);
+ parseExpected(17);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18);
+ node.statement = parseStatement();
+ return finishNode(node);
+ }
+ function parseForOrForInOrForOfStatement() {
+ var pos = getNodePos();
+ parseExpected(86);
+ parseExpected(17);
+ var initializer = undefined;
+ if (token !== 23) {
+ if (token === 102 || token === 108 || token === 74) {
+ initializer = parseVariableDeclarationList(true);
}
- else if (token === 1) {
- parseErrorAtCurrentToken(ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, openingTagName));
- break;
+ else {
+ initializer = disallowInAnd(parseExpression);
}
- result.push(parseJsxChild());
}
- result.end = scanner.getTokenPos();
- parsingContext = saveParsingContext;
- return result;
- }
- function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
- var fullStart = scanner.getStartPos();
- parseExpected(25);
- var tagName = parseJsxElementName();
- var attributes = parseList(13, parseJsxAttribute);
- var node;
- if (token === 27) {
- node = createNode(235, fullStart);
- scanJsxText();
+ var forOrForInOrForOfStatement;
+ if (parseOptional(90)) {
+ var forInStatement = createNode(200, pos);
+ forInStatement.initializer = initializer;
+ forInStatement.expression = allowInAnd(parseExpression);
+ parseExpected(18);
+ forOrForInOrForOfStatement = forInStatement;
+ }
+ else if (parseOptional(134)) {
+ var forOfStatement = createNode(201, pos);
+ forOfStatement.initializer = initializer;
+ forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
+ parseExpected(18);
+ forOrForInOrForOfStatement = forOfStatement;
}
else {
- parseExpected(39);
- if (inExpressionContext) {
- parseExpected(27);
+ var forStatement = createNode(199, pos);
+ forStatement.initializer = initializer;
+ parseExpected(23);
+ if (token !== 23 && token !== 18) {
+ forStatement.condition = allowInAnd(parseExpression);
}
- else {
- parseExpected(27, undefined, false);
- scanJsxText();
+ parseExpected(23);
+ if (token !== 18) {
+ forStatement.incrementor = allowInAnd(parseExpression);
}
- node = createNode(234, fullStart);
+ parseExpected(18);
+ forOrForInOrForOfStatement = forStatement;
}
- node.tagName = tagName;
- node.attributes = attributes;
- return finishNode(node);
+ forOrForInOrForOfStatement.statement = parseStatement();
+ return finishNode(forOrForInOrForOfStatement);
}
- function parseJsxElementName() {
- scanJsxIdentifier();
- var elementName = parseIdentifierName();
- while (parseOptional(21)) {
- scanJsxIdentifier();
- var node = createNode(135, elementName.pos);
- node.left = elementName;
- node.right = parseIdentifierName();
- elementName = finishNode(node);
+ function parseBreakOrContinueStatement(kind) {
+ var node = createNode(kind);
+ parseExpected(kind === 203 ? 70 : 75);
+ if (!canParseSemicolon()) {
+ node.label = parseIdentifier();
}
- return elementName;
+ parseSemicolon();
+ return finishNode(node);
}
- function parseJsxExpression(inExpressionContext) {
- var node = createNode(240);
- parseExpected(15);
- if (token !== 16) {
- node.expression = parseExpression();
- }
- if (inExpressionContext) {
- parseExpected(16);
- }
- else {
- parseExpected(16, undefined, false);
- scanJsxText();
+ function parseReturnStatement() {
+ var node = createNode(204);
+ parseExpected(94);
+ if (!canParseSemicolon()) {
+ node.expression = allowInAnd(parseExpression);
}
+ parseSemicolon();
return finishNode(node);
}
- function parseJsxAttribute() {
- if (token === 15) {
- return parseJsxSpreadAttribute();
- }
- scanJsxIdentifier();
- var node = createNode(238);
- node.name = parseIdentifierName();
- if (parseOptional(56)) {
- switch (token) {
- case 9:
- node.initializer = parseLiteralNode();
- break;
- default:
- node.initializer = parseJsxExpression(true);
- break;
- }
- }
+ function parseWithStatement() {
+ var node = createNode(205);
+ parseExpected(105);
+ parseExpected(17);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18);
+ node.statement = parseStatement();
return finishNode(node);
}
- function parseJsxSpreadAttribute() {
- var node = createNode(239);
+ function parseCaseClause() {
+ var node = createNode(241);
+ parseExpected(71);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(54);
+ node.statements = parseList(3, parseStatement);
+ return finishNode(node);
+ }
+ function parseDefaultClause() {
+ var node = createNode(242);
+ parseExpected(77);
+ parseExpected(54);
+ node.statements = parseList(3, parseStatement);
+ return finishNode(node);
+ }
+ function parseCaseOrDefaultClause() {
+ return token === 71 ? parseCaseClause() : parseDefaultClause();
+ }
+ function parseSwitchStatement() {
+ var node = createNode(206);
+ parseExpected(96);
+ parseExpected(17);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18);
+ var caseBlock = createNode(220, scanner.getStartPos());
parseExpected(15);
- parseExpected(22);
- node.expression = parseExpression();
+ caseBlock.clauses = parseList(2, parseCaseOrDefaultClause);
parseExpected(16);
+ node.caseBlock = finishNode(caseBlock);
+ return finishNode(node);
+ }
+ function parseThrowStatement() {
+ var node = createNode(208);
+ parseExpected(98);
+ node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
+ parseSemicolon();
+ return finishNode(node);
+ }
+ function parseTryStatement() {
+ var node = createNode(209);
+ parseExpected(100);
+ node.tryBlock = parseBlock(false);
+ node.catchClause = token === 72 ? parseCatchClause() : undefined;
+ if (!node.catchClause || token === 85) {
+ parseExpected(85);
+ node.finallyBlock = parseBlock(false);
+ }
+ return finishNode(node);
+ }
+ function parseCatchClause() {
+ var result = createNode(244);
+ parseExpected(72);
+ if (parseExpected(17)) {
+ result.variableDeclaration = parseVariableDeclaration();
+ }
+ parseExpected(18);
+ result.block = parseBlock(false);
+ return finishNode(result);
+ }
+ function parseDebuggerStatement() {
+ var node = createNode(210);
+ parseExpected(76);
+ parseSemicolon();
return finishNode(node);
}
- function parseJsxClosingElement(inExpressionContext) {
- var node = createNode(237);
- parseExpected(26);
- node.tagName = parseJsxElementName();
- if (inExpressionContext) {
- parseExpected(27);
+ function parseExpressionOrLabeledStatement() {
+ var fullStart = scanner.getStartPos();
+ var expression = allowInAnd(parseExpression);
+ if (expression.kind === 69 && parseOptional(54)) {
+ var labeledStatement = createNode(207, fullStart);
+ labeledStatement.label = expression;
+ labeledStatement.statement = parseStatement();
+ return finishNode(labeledStatement);
}
else {
- parseExpected(27, undefined, false);
- scanJsxText();
+ var expressionStatement = createNode(195, fullStart);
+ expressionStatement.expression = expression;
+ parseSemicolon();
+ return finishNode(expressionStatement);
}
- return finishNode(node);
}
- function parseTypeAssertion() {
- var node = createNode(171);
- parseExpected(25);
- node.type = parseType();
- parseExpected(27);
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function nextTokenIsIdentifierOrKeywordOnSameLine() {
+ nextToken();
+ return ts.tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
}
- function parseMemberExpressionRest(expression) {
+ function nextTokenIsFunctionKeywordOnSameLine() {
+ nextToken();
+ return token === 87 && !scanner.hasPrecedingLineBreak();
+ }
+ function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
+ nextToken();
+ return (ts.tokenIsIdentifierOrKeyword(token) || token === 8) && !scanner.hasPrecedingLineBreak();
+ }
+ function isDeclaration() {
while (true) {
- var dotToken = parseOptionalToken(21);
- if (dotToken) {
- var propertyAccess = createNode(166, expression.pos);
- propertyAccess.expression = expression;
- propertyAccess.dotToken = dotToken;
- propertyAccess.name = parseRightSideOfDot(true);
- expression = finishNode(propertyAccess);
- continue;
- }
- if (!inDecoratorContext() && parseOptional(19)) {
- var indexedAccess = createNode(167, expression.pos);
- indexedAccess.expression = expression;
- if (token !== 20) {
- indexedAccess.argumentExpression = allowInAnd(parseExpression);
- if (indexedAccess.argumentExpression.kind === 9 || indexedAccess.argumentExpression.kind === 8) {
- var literal = indexedAccess.argumentExpression;
- literal.text = internIdentifier(literal.text);
+ switch (token) {
+ case 102:
+ case 108:
+ case 74:
+ case 87:
+ case 73:
+ case 81:
+ return true;
+ case 107:
+ case 132:
+ return nextTokenIsIdentifierOnSameLine();
+ case 125:
+ case 126:
+ return nextTokenIsIdentifierOrStringLiteralOnSameLine();
+ case 115:
+ case 118:
+ case 122:
+ case 110:
+ case 111:
+ case 112:
+ nextToken();
+ if (scanner.hasPrecedingLineBreak()) {
+ return false;
}
- }
- parseExpected(20);
- expression = finishNode(indexedAccess);
- continue;
- }
- if (token === 11 || token === 12) {
- var tagExpression = createNode(170, expression.pos);
- tagExpression.tag = expression;
- tagExpression.template = token === 11
- ? parseLiteralNode()
- : parseTemplateExpression();
- expression = finishNode(tagExpression);
- continue;
+ continue;
+ case 89:
+ nextToken();
+ return token === 9 || token === 37 ||
+ token === 15 || ts.tokenIsIdentifierOrKeyword(token);
+ case 82:
+ nextToken();
+ if (token === 56 || token === 37 ||
+ token === 15 || token === 77) {
+ return true;
+ }
+ continue;
+ case 113:
+ nextToken();
+ continue;
+ default:
+ return false;
}
- return expression;
}
}
- function parseCallExpressionRest(expression) {
- while (true) {
- expression = parseMemberExpressionRest(expression);
- if (token === 25) {
- var typeArguments = tryParse(parseTypeArgumentsInExpression);
- if (!typeArguments) {
- return expression;
- }
- var callExpr = createNode(168, expression.pos);
- callExpr.expression = expression;
- callExpr.typeArguments = typeArguments;
- callExpr.arguments = parseArgumentList();
- expression = finishNode(callExpr);
- continue;
- }
- else if (token === 17) {
- var callExpr = createNode(168, expression.pos);
- callExpr.expression = expression;
- callExpr.arguments = parseArgumentList();
- expression = finishNode(callExpr);
- continue;
- }
- return expression;
+ function isStartOfDeclaration() {
+ return lookAhead(isDeclaration);
+ }
+ function isStartOfStatement() {
+ switch (token) {
+ case 55:
+ case 23:
+ case 15:
+ case 102:
+ case 108:
+ case 87:
+ case 73:
+ case 81:
+ case 88:
+ case 79:
+ case 104:
+ case 86:
+ case 75:
+ case 70:
+ case 94:
+ case 105:
+ case 96:
+ case 98:
+ case 100:
+ case 76:
+ case 72:
+ case 85:
+ return true;
+ case 74:
+ case 82:
+ case 89:
+ return isStartOfDeclaration();
+ case 118:
+ case 122:
+ case 107:
+ case 125:
+ case 126:
+ case 132:
+ return true;
+ case 112:
+ case 110:
+ case 111:
+ case 113:
+ return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
+ default:
+ return isStartOfExpression();
}
}
- function parseArgumentList() {
- parseExpected(17);
- var result = parseDelimitedList(11, parseArgumentExpression);
- parseExpected(18);
- return result;
+ function nextTokenIsIdentifierOrStartOfDestructuring() {
+ nextToken();
+ return isIdentifier() || token === 15 || token === 19;
}
- function parseTypeArgumentsInExpression() {
- if (!parseOptional(25)) {
- return undefined;
- }
- var typeArguments = parseDelimitedList(18, parseType);
- if (!parseExpected(27)) {
- return undefined;
+ function isLetDeclaration() {
+ return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
+ }
+ function parseStatement() {
+ switch (token) {
+ case 23:
+ return parseEmptyStatement();
+ case 15:
+ return parseBlock(false);
+ case 102:
+ return parseVariableStatement(scanner.getStartPos(), undefined, undefined);
+ case 108:
+ if (isLetDeclaration()) {
+ return parseVariableStatement(scanner.getStartPos(), undefined, undefined);
+ }
+ break;
+ case 87:
+ return parseFunctionDeclaration(scanner.getStartPos(), undefined, undefined);
+ case 73:
+ return parseClassDeclaration(scanner.getStartPos(), undefined, undefined);
+ case 88:
+ return parseIfStatement();
+ case 79:
+ return parseDoStatement();
+ case 104:
+ return parseWhileStatement();
+ case 86:
+ return parseForOrForInOrForOfStatement();
+ case 75:
+ return parseBreakOrContinueStatement(202);
+ case 70:
+ return parseBreakOrContinueStatement(203);
+ case 94:
+ return parseReturnStatement();
+ case 105:
+ return parseWithStatement();
+ case 96:
+ return parseSwitchStatement();
+ case 98:
+ return parseThrowStatement();
+ case 100:
+ case 72:
+ case 85:
+ return parseTryStatement();
+ case 76:
+ return parseDebuggerStatement();
+ case 55:
+ return parseDeclaration();
+ case 118:
+ case 107:
+ case 132:
+ case 125:
+ case 126:
+ case 122:
+ case 74:
+ case 81:
+ case 82:
+ case 89:
+ case 110:
+ case 111:
+ case 112:
+ case 115:
+ case 113:
+ if (isStartOfDeclaration()) {
+ return parseDeclaration();
+ }
+ break;
}
- return typeArguments && canFollowTypeArgumentsInExpression()
- ? typeArguments
- : undefined;
+ return parseExpressionOrLabeledStatement();
}
- function canFollowTypeArgumentsInExpression() {
+ function parseDeclaration() {
+ var fullStart = getNodePos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
switch (token) {
- case 17:
- case 21:
- case 18:
- case 20:
- case 54:
- case 23:
- case 53:
- case 30:
- case 32:
- case 31:
- case 33:
- case 51:
- case 52:
- case 48:
- case 46:
- case 47:
- case 16:
- case 1:
- return true;
- case 24:
- case 15:
+ case 102:
+ case 108:
+ case 74:
+ return parseVariableStatement(fullStart, decorators, modifiers);
+ case 87:
+ return parseFunctionDeclaration(fullStart, decorators, modifiers);
+ case 73:
+ return parseClassDeclaration(fullStart, decorators, modifiers);
+ case 107:
+ return parseInterfaceDeclaration(fullStart, decorators, modifiers);
+ case 132:
+ return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
+ case 81:
+ return parseEnumDeclaration(fullStart, decorators, modifiers);
+ case 125:
+ case 126:
+ return parseModuleDeclaration(fullStart, decorators, modifiers);
+ case 89:
+ return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
+ case 82:
+ nextToken();
+ return token === 77 || token === 56 ?
+ parseExportAssignment(fullStart, decorators, modifiers) :
+ parseExportDeclaration(fullStart, decorators, modifiers);
default:
- return false;
+ if (decorators || modifiers) {
+ var node = createMissingNode(231, true, ts.Diagnostics.Declaration_expected);
+ node.pos = fullStart;
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ return finishNode(node);
+ }
}
}
- function parsePrimaryExpression() {
- switch (token) {
- case 8:
- case 9:
- case 11:
- return parseLiteralNode();
- case 97:
- case 95:
- case 93:
- case 99:
- case 84:
- return parseTokenNode();
- case 17:
- return parseParenthesizedExpression();
- case 19:
- return parseArrayLiteralExpression();
- case 15:
- return parseObjectLiteralExpression();
- case 118:
- if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
- break;
- }
- return parseFunctionExpression();
- case 73:
- return parseClassExpression();
- case 87:
- return parseFunctionExpression();
- case 92:
- return parseNewExpression();
- case 39:
- case 61:
- if (reScanSlashToken() === 10) {
- return parseLiteralNode();
- }
- break;
- case 12:
- return parseTemplateExpression();
+ function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
+ nextToken();
+ return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === 9);
+ }
+ function parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage) {
+ if (token !== 15 && canParseSemicolon()) {
+ parseSemicolon();
+ return;
}
- return parseIdentifier(ts.Diagnostics.Expression_expected);
+ return parseFunctionBlock(isGenerator, isAsync, false, diagnosticMessage);
}
- function parseParenthesizedExpression() {
- var node = createNode(172);
- parseExpected(17);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18);
+ function parseArrayBindingElement() {
+ if (token === 24) {
+ return createNode(187);
+ }
+ var node = createNode(163);
+ node.dotDotDotToken = parseOptionalToken(22);
+ node.name = parseIdentifierOrPattern();
+ node.initializer = parseBindingElementInitializer(false);
return finishNode(node);
}
- function parseSpreadElement() {
- var node = createNode(185);
- parseExpected(22);
- node.expression = parseAssignmentExpressionOrHigher();
+ function parseObjectBindingElement() {
+ var node = createNode(163);
+ var tokenIsIdentifier = isIdentifier();
+ var propertyName = parsePropertyName();
+ if (tokenIsIdentifier && token !== 54) {
+ node.name = propertyName;
+ }
+ else {
+ parseExpected(54);
+ node.propertyName = propertyName;
+ node.name = parseIdentifierOrPattern();
+ }
+ node.initializer = parseBindingElementInitializer(false);
return finishNode(node);
}
- function parseArgumentOrArrayLiteralElement() {
- return token === 22 ? parseSpreadElement() :
- token === 24 ? createNode(187) :
- parseAssignmentExpressionOrHigher();
- }
- function parseArgumentExpression() {
- return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
+ function parseObjectBindingPattern() {
+ var node = createNode(161);
+ parseExpected(15);
+ node.elements = parseDelimitedList(9, parseObjectBindingElement);
+ parseExpected(16);
+ return finishNode(node);
}
- function parseArrayLiteralExpression() {
- var node = createNode(164);
+ function parseArrayBindingPattern() {
+ var node = createNode(162);
parseExpected(19);
- if (scanner.hasPrecedingLineBreak())
- node.flags |= 1024;
- node.elements = parseDelimitedList(15, parseArgumentOrArrayLiteralElement);
+ node.elements = parseDelimitedList(10, parseArrayBindingElement);
parseExpected(20);
return finishNode(node);
}
- function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
- if (parseContextualModifier(123)) {
- return parseAccessorDeclaration(145, fullStart, decorators, modifiers);
+ function isIdentifierOrPattern() {
+ return token === 15 || token === 19 || isIdentifier();
+ }
+ function parseIdentifierOrPattern() {
+ if (token === 19) {
+ return parseArrayBindingPattern();
}
- else if (parseContextualModifier(129)) {
- return parseAccessorDeclaration(146, fullStart, decorators, modifiers);
+ if (token === 15) {
+ return parseObjectBindingPattern();
}
- return undefined;
+ return parseIdentifier();
}
- function parseObjectLiteralElement() {
- var fullStart = scanner.getStartPos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
- if (accessor) {
- return accessor;
+ function parseVariableDeclaration() {
+ var node = createNode(211);
+ node.name = parseIdentifierOrPattern();
+ node.type = parseTypeAnnotation();
+ if (!isInOrOfKeyword(token)) {
+ node.initializer = parseInitializer(false);
}
- var asteriskToken = parseOptionalToken(37);
- var tokenIsIdentifier = isIdentifier();
- var nameToken = token;
- var propertyName = parsePropertyName();
- var questionToken = parseOptionalToken(53);
- if (asteriskToken || token === 17 || token === 25) {
- return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
+ return finishNode(node);
+ }
+ function parseVariableDeclarationList(inForStatementInitializer) {
+ var node = createNode(212);
+ switch (token) {
+ case 102:
+ break;
+ case 108:
+ node.flags |= 8192;
+ break;
+ case 74:
+ node.flags |= 16384;
+ break;
+ default:
+ ts.Debug.fail();
}
- var isShorthandPropertyAssignment = tokenIsIdentifier && (token === 24 || token === 16 || token === 56);
- if (isShorthandPropertyAssignment) {
- var shorthandDeclaration = createNode(246, fullStart);
- shorthandDeclaration.name = propertyName;
- shorthandDeclaration.questionToken = questionToken;
- var equalsToken = parseOptionalToken(56);
- if (equalsToken) {
- shorthandDeclaration.equalsToken = equalsToken;
- shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
- }
- return finishNode(shorthandDeclaration);
+ nextToken();
+ if (token === 134 && lookAhead(canFollowContextualOfKeyword)) {
+ node.declarations = createMissingList();
}
else {
- var propertyAssignment = createNode(245, fullStart);
- propertyAssignment.name = propertyName;
- propertyAssignment.questionToken = questionToken;
- parseExpected(54);
- propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
- return finishNode(propertyAssignment);
+ var savedDisallowIn = inDisallowInContext();
+ setDisallowInContext(inForStatementInitializer);
+ node.declarations = parseDelimitedList(8, parseVariableDeclaration);
+ setDisallowInContext(savedDisallowIn);
}
+ return finishNode(node);
}
- function parseObjectLiteralExpression() {
- var node = createNode(165);
- parseExpected(15);
- if (scanner.hasPrecedingLineBreak()) {
- node.flags |= 1024;
- }
- node.properties = parseDelimitedList(12, parseObjectLiteralElement, true);
- parseExpected(16);
+ function canFollowContextualOfKeyword() {
+ return nextTokenIsIdentifier() && nextToken() === 18;
+ }
+ function parseVariableStatement(fullStart, decorators, modifiers) {
+ var node = createNode(193, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.declarationList = parseVariableDeclarationList(false);
+ parseSemicolon();
return finishNode(node);
}
- function parseFunctionExpression() {
- var saveDecoratorContext = inDecoratorContext();
- if (saveDecoratorContext) {
- setDecoratorContext(false);
- }
- var node = createNode(173);
- setModifiers(node, parseModifiers());
+ function parseFunctionDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(213, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
parseExpected(87);
node.asteriskToken = parseOptionalToken(37);
+ node.name = node.flags & 512 ? parseOptionalIdentifier() : parseIdentifier();
var isGenerator = !!node.asteriskToken;
var isAsync = !!(node.flags & 256);
- node.name =
- isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
- isGenerator ? doInYieldContext(parseOptionalIdentifier) :
- isAsync ? doInAwaitContext(parseOptionalIdentifier) :
- parseOptionalIdentifier();
fillSignature(54, isGenerator, isAsync, false, node);
- node.body = parseFunctionBlock(isGenerator, isAsync, false);
- if (saveDecoratorContext) {
- setDecoratorContext(true);
- }
+ node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, ts.Diagnostics.or_expected);
return finishNode(node);
}
- function parseOptionalIdentifier() {
- return isIdentifier() ? parseIdentifier() : undefined;
- }
- function parseNewExpression() {
- var node = createNode(169);
- parseExpected(92);
- node.expression = parseMemberExpressionOrHigher();
- node.typeArguments = tryParse(parseTypeArgumentsInExpression);
- if (node.typeArguments || token === 17) {
- node.arguments = parseArgumentList();
- }
+ function parseConstructorDeclaration(pos, decorators, modifiers) {
+ var node = createNode(144, pos);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(121);
+ fillSignature(54, false, false, false, node);
+ node.body = parseFunctionBlockOrSemicolon(false, false, ts.Diagnostics.or_expected);
return finishNode(node);
}
- function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
- var node = createNode(192);
- if (parseExpected(15, diagnosticMessage) || ignoreMissingOpenBrace) {
- node.statements = parseList(1, parseStatement);
- parseExpected(16);
+ function parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, diagnosticMessage) {
+ var method = createNode(143, fullStart);
+ method.decorators = decorators;
+ setModifiers(method, modifiers);
+ method.asteriskToken = asteriskToken;
+ method.name = name;
+ method.questionToken = questionToken;
+ var isGenerator = !!asteriskToken;
+ var isAsync = !!(method.flags & 256);
+ fillSignature(54, isGenerator, isAsync, false, method);
+ method.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage);
+ return finishNode(method);
+ }
+ function parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken) {
+ var property = createNode(141, fullStart);
+ property.decorators = decorators;
+ setModifiers(property, modifiers);
+ property.name = name;
+ property.questionToken = questionToken;
+ property.type = parseTypeAnnotation();
+ property.initializer = modifiers && modifiers.flags & 64
+ ? allowInAnd(parseNonParameterInitializer)
+ : doOutsideOfContext(2 | 1, parseNonParameterInitializer);
+ parseSemicolon();
+ return finishNode(property);
+ }
+ function parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers) {
+ var asteriskToken = parseOptionalToken(37);
+ var name = parsePropertyName();
+ var questionToken = parseOptionalToken(53);
+ if (asteriskToken || token === 17 || token === 25) {
+ return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, ts.Diagnostics.or_expected);
}
else {
- node.statements = createMissingList();
+ return parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken);
}
- return finishNode(node);
}
- function parseFunctionBlock(allowYield, allowAwait, ignoreMissingOpenBrace, diagnosticMessage) {
- var savedYieldContext = inYieldContext();
- setYieldContext(allowYield);
- var savedAwaitContext = inAwaitContext();
- setAwaitContext(allowAwait);
- var saveDecoratorContext = inDecoratorContext();
- if (saveDecoratorContext) {
- setDecoratorContext(false);
- }
- var block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
- if (saveDecoratorContext) {
- setDecoratorContext(true);
- }
- setYieldContext(savedYieldContext);
- setAwaitContext(savedAwaitContext);
- return block;
+ function parseNonParameterInitializer() {
+ return parseInitializer(false);
}
- function parseEmptyStatement() {
- var node = createNode(194);
- parseExpected(23);
+ function parseAccessorDeclaration(kind, fullStart, decorators, modifiers) {
+ var node = createNode(kind, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.name = parsePropertyName();
+ fillSignature(54, false, false, false, node);
+ node.body = parseFunctionBlockOrSemicolon(false, false);
return finishNode(node);
}
- function parseIfStatement() {
- var node = createNode(196);
- parseExpected(88);
- parseExpected(17);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18);
- node.thenStatement = parseStatement();
- node.elseStatement = parseOptional(80) ? parseStatement() : undefined;
- return finishNode(node);
+ function isClassMemberModifier(idToken) {
+ switch (idToken) {
+ case 112:
+ case 110:
+ case 111:
+ case 113:
+ return true;
+ default:
+ return false;
+ }
}
- function parseDoStatement() {
- var node = createNode(197);
- parseExpected(79);
- node.statement = parseStatement();
- parseExpected(104);
- parseExpected(17);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18);
- parseOptional(23);
- return finishNode(node);
+ function isClassMemberStart() {
+ var idToken;
+ if (token === 55) {
+ return true;
+ }
+ while (ts.isModifier(token)) {
+ idToken = token;
+ if (isClassMemberModifier(idToken)) {
+ return true;
+ }
+ nextToken();
+ }
+ if (token === 37) {
+ return true;
+ }
+ if (isLiteralPropertyName()) {
+ idToken = token;
+ nextToken();
+ }
+ if (token === 19) {
+ return true;
+ }
+ if (idToken !== undefined) {
+ if (!ts.isKeyword(idToken) || idToken === 129 || idToken === 123) {
+ return true;
+ }
+ switch (token) {
+ case 17:
+ case 25:
+ case 54:
+ case 56:
+ case 53:
+ return true;
+ default:
+ return canParseSemicolon();
+ }
+ }
+ return false;
}
- function parseWhileStatement() {
- var node = createNode(198);
- parseExpected(104);
- parseExpected(17);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18);
- node.statement = parseStatement();
- return finishNode(node);
+ function parseDecorators() {
+ var decorators;
+ while (true) {
+ var decoratorStart = getNodePos();
+ if (!parseOptional(55)) {
+ break;
+ }
+ if (!decorators) {
+ decorators = [];
+ decorators.pos = scanner.getStartPos();
+ }
+ var decorator = createNode(139, decoratorStart);
+ decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
+ decorators.push(finishNode(decorator));
+ }
+ if (decorators) {
+ decorators.end = getNodeEnd();
+ }
+ return decorators;
}
- function parseForOrForInOrForOfStatement() {
- var pos = getNodePos();
- parseExpected(86);
- parseExpected(17);
- var initializer = undefined;
- if (token !== 23) {
- if (token === 102 || token === 108 || token === 74) {
- initializer = parseVariableDeclarationList(true);
+ function parseModifiers() {
+ var flags = 0;
+ var modifiers;
+ while (true) {
+ var modifierStart = scanner.getStartPos();
+ var modifierKind = token;
+ if (!parseAnyContextualModifier()) {
+ break;
}
- else {
- initializer = disallowInAnd(parseExpression);
+ if (!modifiers) {
+ modifiers = [];
+ modifiers.pos = modifierStart;
}
+ flags |= ts.modifierToFlag(modifierKind);
+ modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
+ }
+ if (modifiers) {
+ modifiers.flags = flags;
+ modifiers.end = scanner.getStartPos();
+ }
+ return modifiers;
+ }
+ function parseModifiersForArrowFunction() {
+ var flags = 0;
+ var modifiers;
+ if (token === 118) {
+ var modifierStart = scanner.getStartPos();
+ var modifierKind = token;
+ nextToken();
+ modifiers = [];
+ modifiers.pos = modifierStart;
+ flags |= ts.modifierToFlag(modifierKind);
+ modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
+ modifiers.flags = flags;
+ modifiers.end = scanner.getStartPos();
+ }
+ return modifiers;
+ }
+ function parseClassElement() {
+ if (token === 23) {
+ var result = createNode(191);
+ nextToken();
+ return finishNode(result);
}
- var forOrForInOrForOfStatement;
- if (parseOptional(90)) {
- var forInStatement = createNode(200, pos);
- forInStatement.initializer = initializer;
- forInStatement.expression = allowInAnd(parseExpression);
- parseExpected(18);
- forOrForInOrForOfStatement = forInStatement;
+ var fullStart = getNodePos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
+ if (accessor) {
+ return accessor;
}
- else if (parseOptional(134)) {
- var forOfStatement = createNode(201, pos);
- forOfStatement.initializer = initializer;
- forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
- parseExpected(18);
- forOrForInOrForOfStatement = forOfStatement;
+ if (token === 121) {
+ return parseConstructorDeclaration(fullStart, decorators, modifiers);
}
- else {
- var forStatement = createNode(199, pos);
- forStatement.initializer = initializer;
- parseExpected(23);
- if (token !== 23 && token !== 18) {
- forStatement.condition = allowInAnd(parseExpression);
- }
- parseExpected(23);
- if (token !== 18) {
- forStatement.incrementor = allowInAnd(parseExpression);
- }
- parseExpected(18);
- forOrForInOrForOfStatement = forStatement;
+ if (isIndexSignature()) {
+ return parseIndexSignatureDeclaration(fullStart, decorators, modifiers);
}
- forOrForInOrForOfStatement.statement = parseStatement();
- return finishNode(forOrForInOrForOfStatement);
+ if (ts.tokenIsIdentifierOrKeyword(token) ||
+ token === 9 ||
+ token === 8 ||
+ token === 37 ||
+ token === 19) {
+ return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
+ }
+ if (decorators || modifiers) {
+ var name_7 = createMissingNode(69, true, ts.Diagnostics.Declaration_expected);
+ return parsePropertyDeclaration(fullStart, decorators, modifiers, name_7, undefined);
+ }
+ ts.Debug.fail("Should not have attempted to parse class member declaration.");
}
- function parseBreakOrContinueStatement(kind) {
- var node = createNode(kind);
- parseExpected(kind === 203 ? 70 : 75);
- if (!canParseSemicolon()) {
- node.label = parseIdentifier();
+ function parseClassExpression() {
+ return parseClassDeclarationOrExpression(scanner.getStartPos(), undefined, undefined, 186);
+ }
+ function parseClassDeclaration(fullStart, decorators, modifiers) {
+ return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 214);
+ }
+ function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
+ var node = createNode(kind, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(73);
+ node.name = parseNameOfClassDeclarationOrExpression();
+ node.typeParameters = parseTypeParameters();
+ node.heritageClauses = parseHeritageClauses(true);
+ if (parseExpected(15)) {
+ node.members = parseClassMembers();
+ parseExpected(16);
+ }
+ else {
+ node.members = createMissingList();
}
- parseSemicolon();
return finishNode(node);
}
- function parseReturnStatement() {
- var node = createNode(204);
- parseExpected(94);
- if (!canParseSemicolon()) {
- node.expression = allowInAnd(parseExpression);
+ function parseNameOfClassDeclarationOrExpression() {
+ return isIdentifier() && !isImplementsClause()
+ ? parseIdentifier()
+ : undefined;
+ }
+ function isImplementsClause() {
+ return token === 106 && lookAhead(nextTokenIsIdentifierOrKeyword);
+ }
+ function parseHeritageClauses(isClassHeritageClause) {
+ if (isHeritageClause()) {
+ return parseList(20, parseHeritageClause);
}
- parseSemicolon();
- return finishNode(node);
+ return undefined;
}
- function parseWithStatement() {
- var node = createNode(205);
- parseExpected(105);
- parseExpected(17);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18);
- node.statement = parseStatement();
- return finishNode(node);
+ function parseHeritageClausesWorker() {
+ return parseList(20, parseHeritageClause);
}
- function parseCaseClause() {
- var node = createNode(241);
- parseExpected(71);
- node.expression = allowInAnd(parseExpression);
- parseExpected(54);
- node.statements = parseList(3, parseStatement);
- return finishNode(node);
+ function parseHeritageClause() {
+ if (token === 83 || token === 106) {
+ var node = createNode(243);
+ node.token = token;
+ nextToken();
+ node.types = parseDelimitedList(7, parseExpressionWithTypeArguments);
+ return finishNode(node);
+ }
+ return undefined;
}
- function parseDefaultClause() {
- var node = createNode(242);
- parseExpected(77);
- parseExpected(54);
- node.statements = parseList(3, parseStatement);
+ function parseExpressionWithTypeArguments() {
+ var node = createNode(188);
+ node.expression = parseLeftHandSideExpressionOrHigher();
+ if (token === 25) {
+ node.typeArguments = parseBracketedList(18, parseType, 25, 27);
+ }
return finishNode(node);
}
- function parseCaseOrDefaultClause() {
- return token === 71 ? parseCaseClause() : parseDefaultClause();
+ function isHeritageClause() {
+ return token === 83 || token === 106;
}
- function parseSwitchStatement() {
- var node = createNode(206);
- parseExpected(96);
- parseExpected(17);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18);
- var caseBlock = createNode(220, scanner.getStartPos());
- parseExpected(15);
- caseBlock.clauses = parseList(2, parseCaseOrDefaultClause);
- parseExpected(16);
- node.caseBlock = finishNode(caseBlock);
+ function parseClassMembers() {
+ return parseList(5, parseClassElement);
+ }
+ function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(215, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(107);
+ node.name = parseIdentifier();
+ node.typeParameters = parseTypeParameters();
+ node.heritageClauses = parseHeritageClauses(false);
+ node.members = parseObjectTypeMembers();
return finishNode(node);
}
- function parseThrowStatement() {
- var node = createNode(208);
- parseExpected(98);
- node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
+ function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(216, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(132);
+ node.name = parseIdentifier();
+ node.typeParameters = parseTypeParameters();
+ parseExpected(56);
+ node.type = parseType();
parseSemicolon();
return finishNode(node);
}
- function parseTryStatement() {
- var node = createNode(209);
- parseExpected(100);
- node.tryBlock = parseBlock(false);
- node.catchClause = token === 72 ? parseCatchClause() : undefined;
- if (!node.catchClause || token === 85) {
- parseExpected(85);
- node.finallyBlock = parseBlock(false);
- }
+ function parseEnumMember() {
+ var node = createNode(247, scanner.getStartPos());
+ node.name = parsePropertyName();
+ node.initializer = allowInAnd(parseNonParameterInitializer);
return finishNode(node);
}
- function parseCatchClause() {
- var result = createNode(244);
- parseExpected(72);
- if (parseExpected(17)) {
- result.variableDeclaration = parseVariableDeclaration();
+ function parseEnumDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(217, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(81);
+ node.name = parseIdentifier();
+ if (parseExpected(15)) {
+ node.members = parseDelimitedList(6, parseEnumMember);
+ parseExpected(16);
+ }
+ else {
+ node.members = createMissingList();
}
- parseExpected(18);
- result.block = parseBlock(false);
- return finishNode(result);
- }
- function parseDebuggerStatement() {
- var node = createNode(210);
- parseExpected(76);
- parseSemicolon();
return finishNode(node);
}
- function parseExpressionOrLabeledStatement() {
- var fullStart = scanner.getStartPos();
- var expression = allowInAnd(parseExpression);
- if (expression.kind === 69 && parseOptional(54)) {
- var labeledStatement = createNode(207, fullStart);
- labeledStatement.label = expression;
- labeledStatement.statement = parseStatement();
- return finishNode(labeledStatement);
+ function parseModuleBlock() {
+ var node = createNode(219, scanner.getStartPos());
+ if (parseExpected(15)) {
+ node.statements = parseList(1, parseStatement);
+ parseExpected(16);
}
else {
- var expressionStatement = createNode(195, fullStart);
- expressionStatement.expression = expression;
- parseSemicolon();
- return finishNode(expressionStatement);
+ node.statements = createMissingList();
}
+ return finishNode(node);
}
- function nextTokenIsIdentifierOrKeywordOnSameLine() {
- nextToken();
- return ts.tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
- }
- function nextTokenIsFunctionKeywordOnSameLine() {
- nextToken();
- return token === 87 && !scanner.hasPrecedingLineBreak();
- }
- function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
- nextToken();
- return (ts.tokenIsIdentifierOrKeyword(token) || token === 8) && !scanner.hasPrecedingLineBreak();
+ function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
+ var node = createNode(218, fullStart);
+ var namespaceFlag = flags & 65536;
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.flags |= flags;
+ node.name = parseIdentifier();
+ node.body = parseOptional(21)
+ ? parseModuleOrNamespaceDeclaration(getNodePos(), undefined, undefined, 2 | namespaceFlag)
+ : parseModuleBlock();
+ return finishNode(node);
}
- function isDeclaration() {
- while (true) {
- switch (token) {
- case 102:
- case 108:
- case 74:
- case 87:
- case 73:
- case 81:
- return true;
- case 107:
- case 132:
- return nextTokenIsIdentifierOnSameLine();
- case 125:
- case 126:
- return nextTokenIsIdentifierOrStringLiteralOnSameLine();
- case 115:
- case 118:
- case 122:
- case 110:
- case 111:
- case 112:
- nextToken();
- if (scanner.hasPrecedingLineBreak()) {
- return false;
- }
- continue;
- case 89:
- nextToken();
- return token === 9 || token === 37 ||
- token === 15 || ts.tokenIsIdentifierOrKeyword(token);
- case 82:
- nextToken();
- if (token === 56 || token === 37 ||
- token === 15 || token === 77) {
- return true;
- }
- continue;
- case 113:
- nextToken();
- continue;
- default:
- return false;
+ function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(218, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.name = parseLiteralNode(true);
+ node.body = parseModuleBlock();
+ return finishNode(node);
+ }
+ function parseModuleDeclaration(fullStart, decorators, modifiers) {
+ var flags = modifiers ? modifiers.flags : 0;
+ if (parseOptional(126)) {
+ flags |= 65536;
+ }
+ else {
+ parseExpected(125);
+ if (token === 9) {
+ return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
}
}
+ return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
}
- function isStartOfDeclaration() {
- return lookAhead(isDeclaration);
+ function isExternalModuleReference() {
+ return token === 127 &&
+ lookAhead(nextTokenIsOpenParen);
}
- function isStartOfStatement() {
- switch (token) {
- case 55:
- case 23:
- case 15:
- case 102:
- case 108:
- case 87:
- case 73:
- case 81:
- case 88:
- case 79:
- case 104:
- case 86:
- case 75:
- case 70:
- case 94:
- case 105:
- case 96:
- case 98:
- case 100:
- case 76:
- case 72:
- case 85:
- return true;
- case 74:
- case 82:
- case 89:
- return isStartOfDeclaration();
- case 118:
- case 122:
- case 107:
- case 125:
- case 126:
- case 132:
- return true;
- case 112:
- case 110:
- case 111:
- case 113:
- return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
- default:
- return isStartOfExpression();
- }
+ function nextTokenIsOpenParen() {
+ return nextToken() === 17;
}
- function nextTokenIsIdentifierOrStartOfDestructuring() {
- nextToken();
- return isIdentifier() || token === 15 || token === 19;
+ function nextTokenIsSlash() {
+ return nextToken() === 39;
}
- function isLetDeclaration() {
- return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
+ function nextTokenIsCommaOrFromKeyword() {
+ nextToken();
+ return token === 24 ||
+ token === 133;
}
- function parseStatement() {
- switch (token) {
- case 23:
- return parseEmptyStatement();
- case 15:
- return parseBlock(false);
- case 102:
- return parseVariableStatement(scanner.getStartPos(), undefined, undefined);
- case 108:
- if (isLetDeclaration()) {
- return parseVariableStatement(scanner.getStartPos(), undefined, undefined);
- }
- break;
- case 87:
- return parseFunctionDeclaration(scanner.getStartPos(), undefined, undefined);
- case 73:
- return parseClassDeclaration(scanner.getStartPos(), undefined, undefined);
- case 88:
- return parseIfStatement();
- case 79:
- return parseDoStatement();
- case 104:
- return parseWhileStatement();
- case 86:
- return parseForOrForInOrForOfStatement();
- case 75:
- return parseBreakOrContinueStatement(202);
- case 70:
- return parseBreakOrContinueStatement(203);
- case 94:
- return parseReturnStatement();
- case 105:
- return parseWithStatement();
- case 96:
- return parseSwitchStatement();
- case 98:
- return parseThrowStatement();
- case 100:
- case 72:
- case 85:
- return parseTryStatement();
- case 76:
- return parseDebuggerStatement();
- case 55:
- return parseDeclaration();
- case 118:
- case 107:
- case 132:
- case 125:
- case 126:
- case 122:
- case 74:
- case 81:
- case 82:
- case 89:
- case 110:
- case 111:
- case 112:
- case 115:
- case 113:
- if (isStartOfDeclaration()) {
- return parseDeclaration();
- }
- break;
+ function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
+ parseExpected(89);
+ var afterImportPos = scanner.getStartPos();
+ var identifier;
+ if (isIdentifier()) {
+ identifier = parseIdentifier();
+ if (token !== 24 && token !== 133) {
+ var importEqualsDeclaration = createNode(221, fullStart);
+ importEqualsDeclaration.decorators = decorators;
+ setModifiers(importEqualsDeclaration, modifiers);
+ importEqualsDeclaration.name = identifier;
+ parseExpected(56);
+ importEqualsDeclaration.moduleReference = parseModuleReference();
+ parseSemicolon();
+ return finishNode(importEqualsDeclaration);
+ }
}
- return parseExpressionOrLabeledStatement();
+ var importDeclaration = createNode(222, fullStart);
+ importDeclaration.decorators = decorators;
+ setModifiers(importDeclaration, modifiers);
+ if (identifier ||
+ token === 37 ||
+ token === 15) {
+ importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
+ parseExpected(133);
+ }
+ importDeclaration.moduleSpecifier = parseModuleSpecifier();
+ parseSemicolon();
+ return finishNode(importDeclaration);
}
- function parseDeclaration() {
- var fullStart = getNodePos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- switch (token) {
- case 102:
- case 108:
- case 74:
- return parseVariableStatement(fullStart, decorators, modifiers);
- case 87:
- return parseFunctionDeclaration(fullStart, decorators, modifiers);
- case 73:
- return parseClassDeclaration(fullStart, decorators, modifiers);
- case 107:
- return parseInterfaceDeclaration(fullStart, decorators, modifiers);
- case 132:
- return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
- case 81:
- return parseEnumDeclaration(fullStart, decorators, modifiers);
- case 125:
- case 126:
- return parseModuleDeclaration(fullStart, decorators, modifiers);
- case 89:
- return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
- case 82:
- nextToken();
- return token === 77 || token === 56 ?
- parseExportAssignment(fullStart, decorators, modifiers) :
- parseExportDeclaration(fullStart, decorators, modifiers);
- default:
- if (decorators || modifiers) {
- var node = createMissingNode(231, true, ts.Diagnostics.Declaration_expected);
- node.pos = fullStart;
- node.decorators = decorators;
- setModifiers(node, modifiers);
- return finishNode(node);
- }
+ function parseImportClause(identifier, fullStart) {
+ var importClause = createNode(223, fullStart);
+ if (identifier) {
+ importClause.name = identifier;
+ }
+ if (!importClause.name ||
+ parseOptional(24)) {
+ importClause.namedBindings = token === 37 ? parseNamespaceImport() : parseNamedImportsOrExports(225);
}
+ return finishNode(importClause);
}
- function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
- nextToken();
- return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === 9);
+ function parseModuleReference() {
+ return isExternalModuleReference()
+ ? parseExternalModuleReference()
+ : parseEntityName(false);
}
- function parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage) {
- if (token !== 15 && canParseSemicolon()) {
- parseSemicolon();
- return;
+ function parseExternalModuleReference() {
+ var node = createNode(232);
+ parseExpected(127);
+ parseExpected(17);
+ node.expression = parseModuleSpecifier();
+ parseExpected(18);
+ return finishNode(node);
+ }
+ function parseModuleSpecifier() {
+ var result = parseExpression();
+ if (result.kind === 9) {
+ internIdentifier(result.text);
}
- return parseFunctionBlock(isGenerator, isAsync, false, diagnosticMessage);
+ return result;
}
- function parseArrayBindingElement() {
- if (token === 24) {
- return createNode(187);
+ function parseNamespaceImport() {
+ var namespaceImport = createNode(224);
+ parseExpected(37);
+ parseExpected(116);
+ namespaceImport.name = parseIdentifier();
+ return finishNode(namespaceImport);
+ }
+ function parseNamedImportsOrExports(kind) {
+ var node = createNode(kind);
+ node.elements = parseBracketedList(21, kind === 225 ? parseImportSpecifier : parseExportSpecifier, 15, 16);
+ return finishNode(node);
+ }
+ function parseExportSpecifier() {
+ return parseImportOrExportSpecifier(230);
+ }
+ function parseImportSpecifier() {
+ return parseImportOrExportSpecifier(226);
+ }
+ function parseImportOrExportSpecifier(kind) {
+ var node = createNode(kind);
+ var checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
+ var checkIdentifierStart = scanner.getTokenPos();
+ var checkIdentifierEnd = scanner.getTextPos();
+ var identifierName = parseIdentifierName();
+ if (token === 116) {
+ node.propertyName = identifierName;
+ parseExpected(116);
+ checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
+ checkIdentifierStart = scanner.getTokenPos();
+ checkIdentifierEnd = scanner.getTextPos();
+ node.name = parseIdentifierName();
+ }
+ else {
+ node.name = identifierName;
+ }
+ if (kind === 226 && checkIdentifierIsKeyword) {
+ parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected);
}
- var node = createNode(163);
- node.dotDotDotToken = parseOptionalToken(22);
- node.name = parseIdentifierOrPattern();
- node.initializer = parseBindingElementInitializer(false);
return finishNode(node);
}
- function parseObjectBindingElement() {
- var node = createNode(163);
- var tokenIsIdentifier = isIdentifier();
- var propertyName = parsePropertyName();
- if (tokenIsIdentifier && token !== 54) {
- node.name = propertyName;
+ function parseExportDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(228, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ if (parseOptional(37)) {
+ parseExpected(133);
+ node.moduleSpecifier = parseModuleSpecifier();
+ }
+ else {
+ node.exportClause = parseNamedImportsOrExports(229);
+ if (token === 133 || (token === 9 && !scanner.hasPrecedingLineBreak())) {
+ parseExpected(133);
+ node.moduleSpecifier = parseModuleSpecifier();
+ }
+ }
+ parseSemicolon();
+ return finishNode(node);
+ }
+ function parseExportAssignment(fullStart, decorators, modifiers) {
+ var node = createNode(227, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ if (parseOptional(56)) {
+ node.isExportEquals = true;
+ }
+ else {
+ parseExpected(77);
+ }
+ node.expression = parseAssignmentExpressionOrHigher();
+ parseSemicolon();
+ return finishNode(node);
+ }
+ function processReferenceComments(sourceFile) {
+ var triviaScanner = ts.createScanner(sourceFile.languageVersion, false, 0, sourceText);
+ var referencedFiles = [];
+ var amdDependencies = [];
+ var amdModuleName;
+ while (true) {
+ var kind = triviaScanner.scan();
+ if (kind === 5 || kind === 4 || kind === 3) {
+ continue;
+ }
+ if (kind !== 2) {
+ break;
+ }
+ var range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
+ var comment = sourceText.substring(range.pos, range.end);
+ var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range);
+ if (referencePathMatchResult) {
+ var fileReference = referencePathMatchResult.fileReference;
+ sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
+ var diagnosticMessage = referencePathMatchResult.diagnosticMessage;
+ if (fileReference) {
+ referencedFiles.push(fileReference);
+ }
+ if (diagnosticMessage) {
+ parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage));
+ }
+ }
+ else {
+ var amdModuleNameRegEx = /^\/\/\/\s*".length;
+ return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
+ }
}
- }
- function isClassMemberStart() {
- var idToken;
- if (token === 55) {
- return true;
+ function parseQualifiedName(left) {
+ var result = createNode(135, left.pos);
+ result.left = left;
+ result.right = parseIdentifierName();
+ return finishNode(result);
}
- while (ts.isModifier(token)) {
- idToken = token;
- if (isClassMemberModifier(idToken)) {
- return true;
+ function parseJSDocRecordType() {
+ var result = createNode(257);
+ nextToken();
+ result.members = parseDelimitedList(24, parseJSDocRecordMember);
+ checkForTrailingComma(result.members);
+ parseExpected(16);
+ return finishNode(result);
+ }
+ function parseJSDocRecordMember() {
+ var result = createNode(258);
+ result.name = parseSimplePropertyName();
+ if (token === 54) {
+ nextToken();
+ result.type = parseJSDocType();
}
+ return finishNode(result);
+ }
+ function parseJSDocNonNullableType() {
+ var result = createNode(256);
nextToken();
+ result.type = parseJSDocType();
+ return finishNode(result);
}
- if (token === 37) {
- return true;
+ function parseJSDocTupleType() {
+ var result = createNode(254);
+ nextToken();
+ result.types = parseDelimitedList(25, parseJSDocType);
+ checkForTrailingComma(result.types);
+ parseExpected(20);
+ return finishNode(result);
}
- if (isLiteralPropertyName()) {
- idToken = token;
+ function checkForTrailingComma(list) {
+ if (parseDiagnostics.length === 0 && list.hasTrailingComma) {
+ var start = list.end - ",".length;
+ parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed);
+ }
+ }
+ function parseJSDocUnionType() {
+ var result = createNode(253);
nextToken();
+ result.types = parseJSDocTypeList(parseJSDocType());
+ parseExpected(18);
+ return finishNode(result);
}
- if (token === 19) {
- return true;
+ function parseJSDocTypeList(firstType) {
+ ts.Debug.assert(!!firstType);
+ var types = [];
+ types.pos = firstType.pos;
+ types.push(firstType);
+ while (parseOptional(47)) {
+ types.push(parseJSDocType());
+ }
+ types.end = scanner.getStartPos();
+ return types;
}
- if (idToken !== undefined) {
- if (!ts.isKeyword(idToken) || idToken === 129 || idToken === 123) {
- return true;
+ function parseJSDocAllType() {
+ var result = createNode(250);
+ nextToken();
+ return finishNode(result);
+ }
+ function parseJSDocUnknownOrNullableType() {
+ var pos = scanner.getStartPos();
+ nextToken();
+ if (token === 24 ||
+ token === 16 ||
+ token === 18 ||
+ token === 27 ||
+ token === 56 ||
+ token === 47) {
+ var result = createNode(251, pos);
+ return finishNode(result);
}
- switch (token) {
- case 17:
- case 25:
- case 54:
- case 56:
- case 53:
- return true;
- default:
- return canParseSemicolon();
+ else {
+ var result = createNode(255, pos);
+ result.type = parseJSDocType();
+ return finishNode(result);
}
}
- return false;
- }
- function parseDecorators() {
- var decorators;
- while (true) {
- var decoratorStart = getNodePos();
- if (!parseOptional(55)) {
- break;
+ function parseIsolatedJSDocComment(content, start, length) {
+ initializeState("file.js", content, 2, true, undefined);
+ var jsDocComment = parseJSDocComment(undefined, start, length);
+ var diagnostics = parseDiagnostics;
+ clearState();
+ return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined;
+ }
+ JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
+ function parseJSDocComment(parent, start, length) {
+ var comment = parseJSDocCommentWorker(start, length);
+ if (comment) {
+ fixupParentReferences(comment);
+ comment.parent = parent;
+ }
+ return comment;
+ }
+ JSDocParser.parseJSDocComment = parseJSDocComment;
+ function parseJSDocCommentWorker(start, length) {
+ var content = sourceText;
+ start = start || 0;
+ var end = length === undefined ? content.length : start + length;
+ length = end - start;
+ ts.Debug.assert(start >= 0);
+ ts.Debug.assert(start <= end);
+ ts.Debug.assert(end <= content.length);
+ var tags;
+ var pos;
+ if (length >= "/** */".length) {
+ if (content.charCodeAt(start) === 47 &&
+ content.charCodeAt(start + 1) === 42 &&
+ content.charCodeAt(start + 2) === 42 &&
+ content.charCodeAt(start + 3) !== 42) {
+ var canParseTag = true;
+ var seenAsterisk = true;
+ for (pos = start + "/**".length; pos < end;) {
+ var ch = content.charCodeAt(pos);
+ pos++;
+ if (ch === 64 && canParseTag) {
+ parseTag();
+ canParseTag = false;
+ continue;
+ }
+ if (ts.isLineBreak(ch)) {
+ canParseTag = true;
+ seenAsterisk = false;
+ continue;
+ }
+ if (ts.isWhiteSpace(ch)) {
+ continue;
+ }
+ if (ch === 42) {
+ if (seenAsterisk) {
+ canParseTag = false;
+ }
+ seenAsterisk = true;
+ continue;
+ }
+ canParseTag = false;
+ }
+ }
+ }
+ return createJSDocComment();
+ function createJSDocComment() {
+ if (!tags) {
+ return undefined;
+ }
+ var result = createNode(265, start);
+ result.tags = tags;
+ return finishNode(result, end);
+ }
+ function skipWhitespace() {
+ while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) {
+ pos++;
+ }
+ }
+ function parseTag() {
+ ts.Debug.assert(content.charCodeAt(pos - 1) === 64);
+ var atToken = createNode(55, pos - 1);
+ atToken.end = pos;
+ var tagName = scanIdentifier();
+ if (!tagName) {
+ return;
+ }
+ var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName);
+ addTag(tag);
+ }
+ function handleTag(atToken, tagName) {
+ if (tagName) {
+ switch (tagName.text) {
+ case "param":
+ return handleParamTag(atToken, tagName);
+ case "return":
+ case "returns":
+ return handleReturnTag(atToken, tagName);
+ case "template":
+ return handleTemplateTag(atToken, tagName);
+ case "type":
+ return handleTypeTag(atToken, tagName);
+ }
+ }
+ return undefined;
+ }
+ function handleUnknownTag(atToken, tagName) {
+ var result = createNode(266, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ return finishNode(result, pos);
+ }
+ function addTag(tag) {
+ if (tag) {
+ if (!tags) {
+ tags = [];
+ tags.pos = tag.pos;
+ }
+ tags.push(tag);
+ tags.end = tag.end;
+ }
+ }
+ function tryParseTypeExpression() {
+ skipWhitespace();
+ if (content.charCodeAt(pos) !== 123) {
+ return undefined;
+ }
+ var typeExpression = parseJSDocTypeExpression(pos, end - pos);
+ pos = typeExpression.end;
+ return typeExpression;
+ }
+ function handleParamTag(atToken, tagName) {
+ var typeExpression = tryParseTypeExpression();
+ skipWhitespace();
+ var name;
+ var isBracketed;
+ if (content.charCodeAt(pos) === 91) {
+ pos++;
+ skipWhitespace();
+ name = scanIdentifier();
+ isBracketed = true;
+ }
+ else {
+ name = scanIdentifier();
+ }
+ if (!name) {
+ parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected);
+ }
+ var preName, postName;
+ if (typeExpression) {
+ postName = name;
+ }
+ else {
+ preName = name;
+ }
+ if (!typeExpression) {
+ typeExpression = tryParseTypeExpression();
+ }
+ var result = createNode(267, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.preParameterName = preName;
+ result.typeExpression = typeExpression;
+ result.postParameterName = postName;
+ result.isBracketed = isBracketed;
+ return finishNode(result, pos);
}
- if (!decorators) {
- decorators = [];
- decorators.pos = scanner.getStartPos();
+ function handleReturnTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 268; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var result = createNode(268, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeExpression = tryParseTypeExpression();
+ return finishNode(result, pos);
}
- var decorator = createNode(139, decoratorStart);
- decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
- decorators.push(finishNode(decorator));
- }
- if (decorators) {
- decorators.end = getNodeEnd();
- }
- return decorators;
- }
- function parseModifiers() {
- var flags = 0;
- var modifiers;
- while (true) {
- var modifierStart = scanner.getStartPos();
- var modifierKind = token;
- if (!parseAnyContextualModifier()) {
- break;
+ function handleTypeTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 269; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var result = createNode(269, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeExpression = tryParseTypeExpression();
+ return finishNode(result, pos);
}
- if (!modifiers) {
- modifiers = [];
- modifiers.pos = modifierStart;
+ function handleTemplateTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 270; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var typeParameters = [];
+ typeParameters.pos = pos;
+ while (true) {
+ skipWhitespace();
+ var startPos = pos;
+ var name_8 = scanIdentifier();
+ if (!name_8) {
+ parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected);
+ return undefined;
+ }
+ var typeParameter = createNode(137, name_8.pos);
+ typeParameter.name = name_8;
+ finishNode(typeParameter, pos);
+ typeParameters.push(typeParameter);
+ skipWhitespace();
+ if (content.charCodeAt(pos) !== 44) {
+ break;
+ }
+ pos++;
+ }
+ typeParameters.end = pos;
+ var result = createNode(270, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeParameters = typeParameters;
+ return finishNode(result, pos);
+ }
+ function scanIdentifier() {
+ var startPos = pos;
+ for (; pos < end; pos++) {
+ var ch = content.charCodeAt(pos);
+ if (pos === startPos && ts.isIdentifierStart(ch, 2)) {
+ continue;
+ }
+ else if (pos > startPos && ts.isIdentifierPart(ch, 2)) {
+ continue;
+ }
+ break;
+ }
+ if (startPos === pos) {
+ return undefined;
+ }
+ var result = createNode(69, startPos);
+ result.text = content.substring(startPos, pos);
+ return finishNode(result, pos);
}
- flags |= ts.modifierToFlag(modifierKind);
- modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
- }
- if (modifiers) {
- modifiers.flags = flags;
- modifiers.end = scanner.getStartPos();
- }
- return modifiers;
- }
- function parseModifiersForArrowFunction() {
- var flags = 0;
- var modifiers;
- if (token === 118) {
- var modifierStart = scanner.getStartPos();
- var modifierKind = token;
- nextToken();
- modifiers = [];
- modifiers.pos = modifierStart;
- flags |= ts.modifierToFlag(modifierKind);
- modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
- modifiers.flags = flags;
- modifiers.end = scanner.getStartPos();
- }
- return modifiers;
- }
- function parseClassElement() {
- if (token === 23) {
- var result = createNode(191);
- nextToken();
- return finishNode(result);
- }
- var fullStart = getNodePos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
- if (accessor) {
- return accessor;
- }
- if (token === 121) {
- return parseConstructorDeclaration(fullStart, decorators, modifiers);
- }
- if (isIndexSignature()) {
- return parseIndexSignatureDeclaration(fullStart, decorators, modifiers);
- }
- if (ts.tokenIsIdentifierOrKeyword(token) ||
- token === 9 ||
- token === 8 ||
- token === 37 ||
- token === 19) {
- return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
- }
- if (decorators || modifiers) {
- var name_7 = createMissingNode(69, true, ts.Diagnostics.Declaration_expected);
- return parsePropertyDeclaration(fullStart, decorators, modifiers, name_7, undefined);
- }
- ts.Debug.fail("Should not have attempted to parse class member declaration.");
- }
- function parseClassExpression() {
- return parseClassDeclarationOrExpression(scanner.getStartPos(), undefined, undefined, 186);
- }
- function parseClassDeclaration(fullStart, decorators, modifiers) {
- return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 214);
- }
- function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
- var node = createNode(kind, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(73);
- node.name = parseNameOfClassDeclarationOrExpression();
- node.typeParameters = parseTypeParameters();
- node.heritageClauses = parseHeritageClauses(true);
- if (parseExpected(15)) {
- node.members = parseClassMembers();
- parseExpected(16);
- }
- else {
- node.members = createMissingList();
- }
- return finishNode(node);
- }
- function parseNameOfClassDeclarationOrExpression() {
- return isIdentifier() && !isImplementsClause()
- ? parseIdentifier()
- : undefined;
- }
- function isImplementsClause() {
- return token === 106 && lookAhead(nextTokenIsIdentifierOrKeyword);
- }
- function parseHeritageClauses(isClassHeritageClause) {
- if (isHeritageClause()) {
- return parseList(20, parseHeritageClause);
- }
- return undefined;
- }
- function parseHeritageClausesWorker() {
- return parseList(20, parseHeritageClause);
- }
- function parseHeritageClause() {
- if (token === 83 || token === 106) {
- var node = createNode(243);
- node.token = token;
- nextToken();
- node.types = parseDelimitedList(7, parseExpressionWithTypeArguments);
- return finishNode(node);
- }
- return undefined;
- }
- function parseExpressionWithTypeArguments() {
- var node = createNode(188);
- node.expression = parseLeftHandSideExpressionOrHigher();
- if (token === 25) {
- node.typeArguments = parseBracketedList(18, parseType, 25, 27);
- }
- return finishNode(node);
- }
- function isHeritageClause() {
- return token === 83 || token === 106;
- }
- function parseClassMembers() {
- return parseList(5, parseClassElement);
- }
- function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(215, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(107);
- node.name = parseIdentifier();
- node.typeParameters = parseTypeParameters();
- node.heritageClauses = parseHeritageClauses(false);
- node.members = parseObjectTypeMembers();
- return finishNode(node);
- }
- function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(216, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(132);
- node.name = parseIdentifier();
- node.typeParameters = parseTypeParameters();
- parseExpected(56);
- node.type = parseType();
- parseSemicolon();
- return finishNode(node);
- }
- function parseEnumMember() {
- var node = createNode(247, scanner.getStartPos());
- node.name = parsePropertyName();
- node.initializer = allowInAnd(parseNonParameterInitializer);
- return finishNode(node);
- }
- function parseEnumDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(217, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(81);
- node.name = parseIdentifier();
- if (parseExpected(15)) {
- node.members = parseDelimitedList(6, parseEnumMember);
- parseExpected(16);
- }
- else {
- node.members = createMissingList();
}
- return finishNode(node);
- }
- function parseModuleBlock() {
- var node = createNode(219, scanner.getStartPos());
- if (parseExpected(15)) {
- node.statements = parseList(1, parseStatement);
- parseExpected(16);
+ JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
+ })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
+ })(Parser || (Parser = {}));
+ var IncrementalParser;
+ (function (IncrementalParser) {
+ function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
+ aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2);
+ checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
+ if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
+ return sourceFile;
}
- else {
- node.statements = createMissingList();
+ if (sourceFile.statements.length === 0) {
+ return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, undefined, true);
}
- return finishNode(node);
- }
- function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
- var node = createNode(218, fullStart);
- var namespaceFlag = flags & 65536;
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.flags |= flags;
- node.name = parseIdentifier();
- node.body = parseOptional(21)
- ? parseModuleOrNamespaceDeclaration(getNodePos(), undefined, undefined, 2 | namespaceFlag)
- : parseModuleBlock();
- return finishNode(node);
- }
- function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(218, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.name = parseLiteralNode(true);
- node.body = parseModuleBlock();
- return finishNode(node);
+ var incrementalSourceFile = sourceFile;
+ ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
+ incrementalSourceFile.hasBeenIncrementallyParsed = true;
+ var oldText = sourceFile.text;
+ var syntaxCursor = createSyntaxCursor(sourceFile);
+ var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
+ checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
+ ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
+ ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
+ ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
+ var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
+ updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
+ var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, true);
+ return result;
}
- function parseModuleDeclaration(fullStart, decorators, modifiers) {
- var flags = modifiers ? modifiers.flags : 0;
- if (parseOptional(126)) {
- flags |= 65536;
+ IncrementalParser.updateSourceFile = updateSourceFile;
+ function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
+ if (isArray) {
+ visitArray(element);
}
else {
- parseExpected(125);
- if (token === 9) {
- return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
- }
+ visitNode(element);
}
- return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
- }
- function isExternalModuleReference() {
- return token === 127 &&
- lookAhead(nextTokenIsOpenParen);
- }
- function nextTokenIsOpenParen() {
- return nextToken() === 17;
- }
- function nextTokenIsSlash() {
- return nextToken() === 39;
- }
- function nextTokenIsCommaOrFromKeyword() {
- nextToken();
- return token === 24 ||
- token === 133;
- }
- function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
- parseExpected(89);
- var afterImportPos = scanner.getStartPos();
- var identifier;
- if (isIdentifier()) {
- identifier = parseIdentifier();
- if (token !== 24 && token !== 133) {
- var importEqualsDeclaration = createNode(221, fullStart);
- importEqualsDeclaration.decorators = decorators;
- setModifiers(importEqualsDeclaration, modifiers);
- importEqualsDeclaration.name = identifier;
- parseExpected(56);
- importEqualsDeclaration.moduleReference = parseModuleReference();
- parseSemicolon();
- return finishNode(importEqualsDeclaration);
+ return;
+ function visitNode(node) {
+ var text = "";
+ if (aggressiveChecks && shouldCheckNode(node)) {
+ text = oldText.substring(node.pos, node.end);
}
+ if (node._children) {
+ node._children = undefined;
+ }
+ if (node.jsDocComment) {
+ node.jsDocComment = undefined;
+ }
+ node.pos += delta;
+ node.end += delta;
+ if (aggressiveChecks && shouldCheckNode(node)) {
+ ts.Debug.assert(text === newText.substring(node.pos, node.end));
+ }
+ forEachChild(node, visitNode, visitArray);
+ checkNodePositions(node, aggressiveChecks);
}
- var importDeclaration = createNode(222, fullStart);
- importDeclaration.decorators = decorators;
- setModifiers(importDeclaration, modifiers);
- if (identifier ||
- token === 37 ||
- token === 15) {
- importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
- parseExpected(133);
- }
- importDeclaration.moduleSpecifier = parseModuleSpecifier();
- parseSemicolon();
- return finishNode(importDeclaration);
- }
- function parseImportClause(identifier, fullStart) {
- var importClause = createNode(223, fullStart);
- if (identifier) {
- importClause.name = identifier;
- }
- if (!importClause.name ||
- parseOptional(24)) {
- importClause.namedBindings = token === 37 ? parseNamespaceImport() : parseNamedImportsOrExports(225);
+ function visitArray(array) {
+ array._children = undefined;
+ array.pos += delta;
+ array.end += delta;
+ for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
+ var node = array_7[_i];
+ visitNode(node);
+ }
}
- return finishNode(importClause);
- }
- function parseModuleReference() {
- return isExternalModuleReference()
- ? parseExternalModuleReference()
- : parseEntityName(false);
- }
- function parseExternalModuleReference() {
- var node = createNode(232);
- parseExpected(127);
- parseExpected(17);
- node.expression = parseModuleSpecifier();
- parseExpected(18);
- return finishNode(node);
}
- function parseModuleSpecifier() {
- var result = parseExpression();
- if (result.kind === 9) {
- internIdentifier(result.text);
+ function shouldCheckNode(node) {
+ switch (node.kind) {
+ case 9:
+ case 8:
+ case 69:
+ return true;
}
- return result;
- }
- function parseNamespaceImport() {
- var namespaceImport = createNode(224);
- parseExpected(37);
- parseExpected(116);
- namespaceImport.name = parseIdentifier();
- return finishNode(namespaceImport);
- }
- function parseNamedImportsOrExports(kind) {
- var node = createNode(kind);
- node.elements = parseBracketedList(21, kind === 225 ? parseImportSpecifier : parseExportSpecifier, 15, 16);
- return finishNode(node);
- }
- function parseExportSpecifier() {
- return parseImportOrExportSpecifier(230);
- }
- function parseImportSpecifier() {
- return parseImportOrExportSpecifier(226);
+ return false;
}
- function parseImportOrExportSpecifier(kind) {
- var node = createNode(kind);
- var checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
- var checkIdentifierStart = scanner.getTokenPos();
- var checkIdentifierEnd = scanner.getTextPos();
- var identifierName = parseIdentifierName();
- if (token === 116) {
- node.propertyName = identifierName;
- parseExpected(116);
- checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
- checkIdentifierStart = scanner.getTokenPos();
- checkIdentifierEnd = scanner.getTextPos();
- node.name = parseIdentifierName();
+ function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
+ ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
+ ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
+ ts.Debug.assert(element.pos <= element.end);
+ element.pos = Math.min(element.pos, changeRangeNewEnd);
+ if (element.end >= changeRangeOldEnd) {
+ element.end += delta;
}
else {
- node.name = identifierName;
+ element.end = Math.min(element.end, changeRangeNewEnd);
}
- if (kind === 226 && checkIdentifierIsKeyword) {
- parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected);
+ ts.Debug.assert(element.pos <= element.end);
+ if (element.parent) {
+ ts.Debug.assert(element.pos >= element.parent.pos);
+ ts.Debug.assert(element.end <= element.parent.end);
}
- return finishNode(node);
}
- function parseExportDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(228, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- if (parseOptional(37)) {
- parseExpected(133);
- node.moduleSpecifier = parseModuleSpecifier();
+ function checkNodePositions(node, aggressiveChecks) {
+ if (aggressiveChecks) {
+ var pos = node.pos;
+ forEachChild(node, function (child) {
+ ts.Debug.assert(child.pos >= pos);
+ pos = child.end;
+ });
+ ts.Debug.assert(pos <= node.end);
+ }
+ }
+ function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
+ visitNode(sourceFile);
+ return;
+ function visitNode(child) {
+ ts.Debug.assert(child.pos <= child.end);
+ if (child.pos > changeRangeOldEnd) {
+ moveElementEntirelyPastChangeRange(child, false, delta, oldText, newText, aggressiveChecks);
+ return;
+ }
+ var fullEnd = child.end;
+ if (fullEnd >= changeStart) {
+ child.intersectsChange = true;
+ child._children = undefined;
+ adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
+ forEachChild(child, visitNode, visitArray);
+ checkNodePositions(child, aggressiveChecks);
+ return;
+ }
+ ts.Debug.assert(fullEnd < changeStart);
}
- else {
- node.exportClause = parseNamedImportsOrExports(229);
- if (token === 133 || (token === 9 && !scanner.hasPrecedingLineBreak())) {
- parseExpected(133);
- node.moduleSpecifier = parseModuleSpecifier();
+ function visitArray(array) {
+ ts.Debug.assert(array.pos <= array.end);
+ if (array.pos > changeRangeOldEnd) {
+ moveElementEntirelyPastChangeRange(array, true, delta, oldText, newText, aggressiveChecks);
+ return;
+ }
+ var fullEnd = array.end;
+ if (fullEnd >= changeStart) {
+ array.intersectsChange = true;
+ array._children = undefined;
+ adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
+ for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
+ var node = array_8[_i];
+ visitNode(node);
+ }
+ return;
}
+ ts.Debug.assert(fullEnd < changeStart);
}
- parseSemicolon();
- return finishNode(node);
}
- function parseExportAssignment(fullStart, decorators, modifiers) {
- var node = createNode(227, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- if (parseOptional(56)) {
- node.isExportEquals = true;
- }
- else {
- parseExpected(77);
+ function extendToAffectedRange(sourceFile, changeRange) {
+ var maxLookahead = 1;
+ var start = changeRange.span.start;
+ for (var i = 0; start > 0 && i <= maxLookahead; i++) {
+ var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
+ ts.Debug.assert(nearestNode.pos <= start);
+ var position = nearestNode.pos;
+ start = Math.max(0, position - 1);
}
- node.expression = parseAssignmentExpressionOrHigher();
- parseSemicolon();
- return finishNode(node);
+ var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
+ var finalLength = changeRange.newLength + (changeRange.span.start - start);
+ return ts.createTextChangeRange(finalSpan, finalLength);
}
- function processReferenceComments(sourceFile) {
- var triviaScanner = ts.createScanner(sourceFile.languageVersion, false, 0, sourceText);
- var referencedFiles = [];
- var amdDependencies = [];
- var amdModuleName;
- while (true) {
- var kind = triviaScanner.scan();
- if (kind === 5 || kind === 4 || kind === 3) {
- continue;
+ function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
+ var bestResult = sourceFile;
+ var lastNodeEntirelyBeforePosition;
+ forEachChild(sourceFile, visit);
+ if (lastNodeEntirelyBeforePosition) {
+ var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition);
+ if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
+ bestResult = lastChildOfLastEntireNodeBeforePosition;
}
- if (kind !== 2) {
- break;
+ }
+ return bestResult;
+ function getLastChild(node) {
+ while (true) {
+ var lastChild = getLastChildWorker(node);
+ if (lastChild) {
+ node = lastChild;
+ }
+ else {
+ return node;
+ }
}
- var range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
- var comment = sourceText.substring(range.pos, range.end);
- var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range);
- if (referencePathMatchResult) {
- var fileReference = referencePathMatchResult.fileReference;
- sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
- var diagnosticMessage = referencePathMatchResult.diagnosticMessage;
- if (fileReference) {
- referencedFiles.push(fileReference);
+ }
+ function getLastChildWorker(node) {
+ var last = undefined;
+ forEachChild(node, function (child) {
+ if (ts.nodeIsPresent(child)) {
+ last = child;
}
- if (diagnosticMessage) {
- parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage));
+ });
+ return last;
+ }
+ function visit(child) {
+ if (ts.nodeIsMissing(child)) {
+ return;
+ }
+ if (child.pos <= position) {
+ if (child.pos >= bestResult.pos) {
+ bestResult = child;
+ }
+ if (position < child.end) {
+ forEachChild(child, visit);
+ return true;
+ }
+ else {
+ ts.Debug.assert(child.end <= position);
+ lastNodeEntirelyBeforePosition = child;
}
}
else {
- var amdModuleNameRegEx = /^\/\/\/\s* position);
+ return true;
+ }
+ }
+ }
+ function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
+ var oldText = sourceFile.text;
+ if (textChangeRange) {
+ ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
+ if (aggressiveChecks || ts.Debug.shouldAssert(3)) {
+ var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
+ var newTextPrefix = newText.substr(0, textChangeRange.span.start);
+ ts.Debug.assert(oldTextPrefix === newTextPrefix);
+ var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
+ var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
+ ts.Debug.assert(oldTextSuffix === newTextSuffix);
+ }
+ }
+ }
+ function createSyntaxCursor(sourceFile) {
+ var currentArray = sourceFile.statements;
+ var currentArrayIndex = 0;
+ ts.Debug.assert(currentArrayIndex < currentArray.length);
+ var current = currentArray[currentArrayIndex];
+ var lastQueriedPosition = -1;
+ return {
+ currentNode: function (position) {
+ if (position !== lastQueriedPosition) {
+ if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
+ currentArrayIndex++;
+ current = currentArray[currentArrayIndex];
+ }
+ if (!current || current.pos !== position) {
+ findHighestListElementThatStartsAtPosition(position);
}
- amdModuleName = amdModuleNameMatchResult[2];
}
- var amdDependencyRegEx = /^\/\/\/\s*= node.pos && position < node.end) {
+ forEachChild(node, visitNode, visitArray);
+ return true;
+ }
+ return false;
+ }
+ function visitArray(array) {
+ if (position >= array.pos && position < array.end) {
+ for (var i = 0, n = array.length; i < n; i++) {
+ var child = array[i];
+ if (child) {
+ if (child.pos === position) {
+ currentArray = array;
+ currentArrayIndex = i;
+ current = child;
+ return true;
+ }
+ else {
+ if (child.pos < position && position < child.end) {
+ forEachChild(child, visitNode, visitArray);
+ return true;
+ }
+ }
+ }
}
}
+ return false;
+ }
+ }
+ }
+ })(IncrementalParser || (IncrementalParser = {}));
+})(ts || (ts = {}));
+var ts;
+(function (ts) {
+ ts.bindTime = 0;
+ function or(state1, state2) {
+ return (state1 | state2) & 2
+ ? 2
+ : (state1 & state2) & 8
+ ? 8
+ : 4;
+ }
+ function getModuleInstanceState(node) {
+ if (node.kind === 215 || node.kind === 216) {
+ return 0;
+ }
+ else if (ts.isConstEnumDeclaration(node)) {
+ return 2;
+ }
+ else if ((node.kind === 222 || node.kind === 221) && !(node.flags & 2)) {
+ return 0;
+ }
+ else if (node.kind === 219) {
+ var state = 0;
+ ts.forEachChild(node, function (n) {
+ switch (getModuleInstanceState(n)) {
+ case 0:
+ return false;
+ case 2:
+ state = 2;
+ return false;
+ case 1:
+ state = 1;
+ return true;
}
+ });
+ return state;
+ }
+ else if (node.kind === 218) {
+ return getModuleInstanceState(node.body);
+ }
+ else {
+ return 1;
+ }
+ }
+ ts.getModuleInstanceState = getModuleInstanceState;
+ var binder = createBinder();
+ function bindSourceFile(file, options) {
+ var start = new Date().getTime();
+ binder(file, options);
+ ts.bindTime += new Date().getTime() - start;
+ }
+ ts.bindSourceFile = bindSourceFile;
+ function createBinder() {
+ var file;
+ var options;
+ var parent;
+ var container;
+ var blockScopeContainer;
+ var lastContainer;
+ var seenThisKeyword;
+ var hasExplicitReturn;
+ var currentReachabilityState;
+ var labelStack;
+ var labelIndexMap;
+ var implicitLabels;
+ var inStrictMode;
+ var symbolCount = 0;
+ var Symbol;
+ var classifiableNames;
+ function bindSourceFile(f, opts) {
+ file = f;
+ options = opts;
+ inStrictMode = !!file.externalModuleIndicator;
+ classifiableNames = {};
+ Symbol = ts.objectAllocator.getSymbolConstructor();
+ if (!file.locals) {
+ bind(file);
+ file.symbolCount = symbolCount;
+ file.classifiableNames = classifiableNames;
}
- sourceFile.referencedFiles = referencedFiles;
- sourceFile.amdDependencies = amdDependencies;
- sourceFile.moduleName = amdModuleName;
+ parent = undefined;
+ container = undefined;
+ blockScopeContainer = undefined;
+ lastContainer = undefined;
+ seenThisKeyword = false;
+ hasExplicitReturn = false;
+ labelStack = undefined;
+ labelIndexMap = undefined;
+ implicitLabels = undefined;
}
- function setExternalModuleIndicator(sourceFile) {
- sourceFile.externalModuleIndicator = ts.forEach(sourceFile.statements, function (node) {
- return node.flags & 2
- || node.kind === 221 && node.moduleReference.kind === 232
- || node.kind === 222
- || node.kind === 227
- || node.kind === 228
- ? node
- : undefined;
- });
+ return bindSourceFile;
+ function createSymbol(flags, name) {
+ symbolCount++;
+ return new Symbol(flags, name);
}
- var JSDocParser;
- (function (JSDocParser) {
- function isJSDocType() {
- switch (token) {
- case 37:
- case 53:
- case 17:
- case 19:
- case 49:
- case 15:
- case 87:
- case 22:
- case 92:
- case 97:
- return true;
- }
- return ts.tokenIsIdentifierOrKeyword(token);
+ function addDeclarationToSymbol(symbol, node, symbolFlags) {
+ symbol.flags |= symbolFlags;
+ node.symbol = symbol;
+ if (!symbol.declarations) {
+ symbol.declarations = [];
}
- JSDocParser.isJSDocType = isJSDocType;
- function parseJSDocTypeExpressionForTests(content, start, length) {
- initializeState("file.js", content, 2, undefined);
- var jsDocTypeExpression = parseJSDocTypeExpression(start, length);
- var diagnostics = parseDiagnostics;
- clearState();
- return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined;
+ symbol.declarations.push(node);
+ if (symbolFlags & 1952 && !symbol.exports) {
+ symbol.exports = {};
}
- JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
- function parseJSDocTypeExpression(start, length) {
- scanner.setText(sourceText, start, length);
- token = nextToken();
- var result = createNode(249);
- parseExpected(15);
- result.type = parseJSDocTopLevelType();
- parseExpected(16);
- fixupParentReferences(result);
- return finishNode(result);
+ if (symbolFlags & 6240 && !symbol.members) {
+ symbol.members = {};
}
- JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression;
- function parseJSDocTopLevelType() {
- var type = parseJSDocType();
- if (token === 47) {
- var unionType = createNode(253, type.pos);
- unionType.types = parseJSDocTypeList(type);
- type = finishNode(unionType);
- }
- if (token === 56) {
- var optionalType = createNode(260, type.pos);
- nextToken();
- optionalType.type = type;
- type = finishNode(optionalType);
- }
- return type;
+ if (symbolFlags & 107455 && !symbol.valueDeclaration) {
+ symbol.valueDeclaration = node;
}
- function parseJSDocType() {
- var type = parseBasicTypeExpression();
- while (true) {
- if (token === 19) {
- var arrayType = createNode(252, type.pos);
- arrayType.elementType = type;
- nextToken();
- parseExpected(20);
- type = finishNode(arrayType);
- }
- else if (token === 53) {
- var nullableType = createNode(255, type.pos);
- nullableType.type = type;
- nextToken();
- type = finishNode(nullableType);
- }
- else if (token === 49) {
- var nonNullableType = createNode(256, type.pos);
- nonNullableType.type = type;
- nextToken();
- type = finishNode(nonNullableType);
- }
- else {
- break;
- }
+ }
+ function getDeclarationName(node) {
+ if (node.name) {
+ if (node.kind === 218 && node.name.kind === 9) {
+ return "\"" + node.name.text + "\"";
}
- return type;
- }
- function parseBasicTypeExpression() {
- switch (token) {
- case 37:
- return parseJSDocAllType();
- case 53:
- return parseJSDocUnknownOrNullableType();
- case 17:
- return parseJSDocUnionType();
- case 19:
- return parseJSDocTupleType();
- case 49:
- return parseJSDocNonNullableType();
- case 15:
- return parseJSDocRecordType();
- case 87:
- return parseJSDocFunctionType();
- case 22:
- return parseJSDocVariadicType();
- case 92:
- return parseJSDocConstructorType();
- case 97:
- return parseJSDocThisType();
- case 117:
- case 130:
- case 128:
- case 120:
- case 131:
- case 103:
- return parseTokenNode();
+ if (node.name.kind === 136) {
+ var nameExpression = node.name.expression;
+ if (ts.isStringOrNumericLiteral(nameExpression.kind)) {
+ return nameExpression.text;
+ }
+ ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
+ return ts.getPropertyNameForKnownSymbolName(nameExpression.name.text);
}
- return parseJSDocTypeReference();
- }
- function parseJSDocThisType() {
- var result = createNode(264);
- nextToken();
- parseExpected(54);
- result.type = parseJSDocType();
- return finishNode(result);
- }
- function parseJSDocConstructorType() {
- var result = createNode(263);
- nextToken();
- parseExpected(54);
- result.type = parseJSDocType();
- return finishNode(result);
+ return node.name.text;
}
- function parseJSDocVariadicType() {
- var result = createNode(262);
- nextToken();
- result.type = parseJSDocType();
- return finishNode(result);
+ switch (node.kind) {
+ case 144:
+ return "__constructor";
+ case 152:
+ case 147:
+ return "__call";
+ case 153:
+ case 148:
+ return "__new";
+ case 149:
+ return "__index";
+ case 228:
+ return "__export";
+ case 227:
+ return node.isExportEquals ? "export=" : "default";
+ case 181:
+ return "export=";
+ case 213:
+ case 214:
+ return node.flags & 512 ? "default" : undefined;
}
- function parseJSDocFunctionType() {
- var result = createNode(261);
- nextToken();
- parseExpected(17);
- result.parameters = parseDelimitedList(22, parseJSDocParameter);
- checkForTrailingComma(result.parameters);
- parseExpected(18);
- if (token === 54) {
- nextToken();
- result.type = parseJSDocType();
+ }
+ function getDisplayName(node) {
+ return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node);
+ }
+ function declareSymbol(symbolTable, parent, node, includes, excludes) {
+ ts.Debug.assert(!ts.hasDynamicName(node));
+ var isDefaultExport = node.flags & 512;
+ var name = isDefaultExport && parent ? "default" : getDeclarationName(node);
+ var symbol;
+ if (name !== undefined) {
+ symbol = ts.hasProperty(symbolTable, name)
+ ? symbolTable[name]
+ : (symbolTable[name] = createSymbol(0, name));
+ if (name && (includes & 788448)) {
+ classifiableNames[name] = name;
+ }
+ if (symbol.flags & excludes) {
+ if (node.name) {
+ node.name.parent = node;
+ }
+ var message = symbol.flags & 2
+ ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
+ : ts.Diagnostics.Duplicate_identifier_0;
+ ts.forEach(symbol.declarations, function (declaration) {
+ if (declaration.flags & 512) {
+ message = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
+ }
+ });
+ ts.forEach(symbol.declarations, function (declaration) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
+ });
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
+ symbol = createSymbol(0, name);
}
- return finishNode(result);
- }
- function parseJSDocParameter() {
- var parameter = createNode(138);
- parameter.type = parseJSDocType();
- return finishNode(parameter);
}
- function parseJSDocOptionalType(type) {
- var result = createNode(260, type.pos);
- nextToken();
- result.type = type;
- return finishNode(result);
+ else {
+ symbol = createSymbol(0, "__missing");
}
- function parseJSDocTypeReference() {
- var result = createNode(259);
- result.name = parseSimplePropertyName();
- while (parseOptional(21)) {
- if (token === 25) {
- result.typeArguments = parseTypeArguments();
- break;
- }
- else {
- result.name = parseQualifiedName(result.name);
- }
+ addDeclarationToSymbol(symbol, node, includes);
+ symbol.parent = parent;
+ return symbol;
+ }
+ function declareModuleMember(node, symbolFlags, symbolExcludes) {
+ var hasExportModifier = ts.getCombinedNodeFlags(node) & 2;
+ if (symbolFlags & 8388608) {
+ if (node.kind === 230 || (node.kind === 221 && hasExportModifier)) {
+ return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
+ }
+ else {
+ return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
}
- return finishNode(result);
}
- function parseTypeArguments() {
- nextToken();
- var typeArguments = parseDelimitedList(23, parseJSDocType);
- checkForTrailingComma(typeArguments);
- checkForEmptyTypeArgumentList(typeArguments);
- parseExpected(27);
- return typeArguments;
+ else {
+ if (hasExportModifier || container.flags & 131072) {
+ var exportKind = (symbolFlags & 107455 ? 1048576 : 0) |
+ (symbolFlags & 793056 ? 2097152 : 0) |
+ (symbolFlags & 1536 ? 4194304 : 0);
+ var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
+ local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
+ node.localSymbol = local;
+ return local;
+ }
+ else {
+ return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
}
- function checkForEmptyTypeArgumentList(typeArguments) {
- if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) {
- var start = typeArguments.pos - "<".length;
- var end = ts.skipTrivia(sourceText, typeArguments.end) + ">".length;
- return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
+ }
+ function bindChildren(node) {
+ var saveParent = parent;
+ var saveContainer = container;
+ var savedBlockScopeContainer = blockScopeContainer;
+ parent = node;
+ var containerFlags = getContainerFlags(node);
+ if (containerFlags & 1) {
+ container = blockScopeContainer = node;
+ if (containerFlags & 4) {
+ container.locals = {};
}
+ addToContainerChain(container);
}
- function parseQualifiedName(left) {
- var result = createNode(135, left.pos);
- result.left = left;
- result.right = parseIdentifierName();
- return finishNode(result);
+ else if (containerFlags & 2) {
+ blockScopeContainer = node;
+ blockScopeContainer.locals = undefined;
}
- function parseJSDocRecordType() {
- var result = createNode(257);
- nextToken();
- result.members = parseDelimitedList(24, parseJSDocRecordMember);
- checkForTrailingComma(result.members);
- parseExpected(16);
- return finishNode(result);
+ var savedReachabilityState;
+ var savedLabelStack;
+ var savedLabels;
+ var savedImplicitLabels;
+ var savedHasExplicitReturn;
+ var kind = node.kind;
+ var flags = node.flags;
+ flags &= ~1572864;
+ if (kind === 215) {
+ seenThisKeyword = false;
}
- function parseJSDocRecordMember() {
- var result = createNode(258);
- result.name = parseSimplePropertyName();
- if (token === 54) {
- nextToken();
- result.type = parseJSDocType();
+ var saveState = kind === 248 || kind === 219 || ts.isFunctionLikeKind(kind);
+ if (saveState) {
+ savedReachabilityState = currentReachabilityState;
+ savedLabelStack = labelStack;
+ savedLabels = labelIndexMap;
+ savedImplicitLabels = implicitLabels;
+ savedHasExplicitReturn = hasExplicitReturn;
+ currentReachabilityState = 2;
+ hasExplicitReturn = false;
+ labelStack = labelIndexMap = implicitLabels = undefined;
+ }
+ bindReachableStatement(node);
+ if (currentReachabilityState === 2 && ts.isFunctionLikeKind(kind) && ts.nodeIsPresent(node.body)) {
+ flags |= 524288;
+ if (hasExplicitReturn) {
+ flags |= 1048576;
}
- return finishNode(result);
}
- function parseJSDocNonNullableType() {
- var result = createNode(256);
- nextToken();
- result.type = parseJSDocType();
- return finishNode(result);
+ if (kind === 215) {
+ flags = seenThisKeyword ? flags | 262144 : flags & ~262144;
}
- function parseJSDocTupleType() {
- var result = createNode(254);
- nextToken();
- result.types = parseDelimitedList(25, parseJSDocType);
- checkForTrailingComma(result.types);
- parseExpected(20);
- return finishNode(result);
+ node.flags = flags;
+ if (saveState) {
+ hasExplicitReturn = savedHasExplicitReturn;
+ currentReachabilityState = savedReachabilityState;
+ labelStack = savedLabelStack;
+ labelIndexMap = savedLabels;
+ implicitLabels = savedImplicitLabels;
}
- function checkForTrailingComma(list) {
- if (parseDiagnostics.length === 0 && list.hasTrailingComma) {
- var start = list.end - ",".length;
- parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed);
- }
+ container = saveContainer;
+ parent = saveParent;
+ blockScopeContainer = savedBlockScopeContainer;
+ }
+ function bindReachableStatement(node) {
+ if (checkUnreachable(node)) {
+ ts.forEachChild(node, bind);
+ return;
}
- function parseJSDocUnionType() {
- var result = createNode(253);
- nextToken();
- result.types = parseJSDocTypeList(parseJSDocType());
- parseExpected(18);
- return finishNode(result);
+ switch (node.kind) {
+ case 198:
+ bindWhileStatement(node);
+ break;
+ case 197:
+ bindDoStatement(node);
+ break;
+ case 199:
+ bindForStatement(node);
+ break;
+ case 200:
+ case 201:
+ bindForInOrForOfStatement(node);
+ break;
+ case 196:
+ bindIfStatement(node);
+ break;
+ case 204:
+ case 208:
+ bindReturnOrThrow(node);
+ break;
+ case 203:
+ case 202:
+ bindBreakOrContinueStatement(node);
+ break;
+ case 209:
+ bindTryStatement(node);
+ break;
+ case 206:
+ bindSwitchStatement(node);
+ break;
+ case 220:
+ bindCaseBlock(node);
+ break;
+ case 207:
+ bindLabeledStatement(node);
+ break;
+ default:
+ ts.forEachChild(node, bind);
+ break;
+ }
+ }
+ function bindWhileStatement(n) {
+ var preWhileState = n.expression.kind === 84 ? 4 : currentReachabilityState;
+ var postWhileState = n.expression.kind === 99 ? 4 : currentReachabilityState;
+ bind(n.expression);
+ currentReachabilityState = preWhileState;
+ var postWhileLabel = pushImplicitLabel();
+ bind(n.statement);
+ popImplicitLabel(postWhileLabel, postWhileState);
+ }
+ function bindDoStatement(n) {
+ var preDoState = currentReachabilityState;
+ var postDoLabel = pushImplicitLabel();
+ bind(n.statement);
+ var postDoState = n.expression.kind === 99 ? 4 : preDoState;
+ popImplicitLabel(postDoLabel, postDoState);
+ bind(n.expression);
+ }
+ function bindForStatement(n) {
+ var preForState = currentReachabilityState;
+ var postForLabel = pushImplicitLabel();
+ bind(n.initializer);
+ bind(n.condition);
+ bind(n.incrementor);
+ bind(n.statement);
+ var isInfiniteLoop = (!n.condition || n.condition.kind === 99);
+ var postForState = isInfiniteLoop ? 4 : preForState;
+ popImplicitLabel(postForLabel, postForState);
+ }
+ function bindForInOrForOfStatement(n) {
+ var preStatementState = currentReachabilityState;
+ var postStatementLabel = pushImplicitLabel();
+ bind(n.initializer);
+ bind(n.expression);
+ bind(n.statement);
+ popImplicitLabel(postStatementLabel, preStatementState);
+ }
+ function bindIfStatement(n) {
+ var ifTrueState = n.expression.kind === 84 ? 4 : currentReachabilityState;
+ var ifFalseState = n.expression.kind === 99 ? 4 : currentReachabilityState;
+ currentReachabilityState = ifTrueState;
+ bind(n.expression);
+ bind(n.thenStatement);
+ if (n.elseStatement) {
+ var preElseState = currentReachabilityState;
+ currentReachabilityState = ifFalseState;
+ bind(n.elseStatement);
+ currentReachabilityState = or(currentReachabilityState, preElseState);
}
- function parseJSDocTypeList(firstType) {
- ts.Debug.assert(!!firstType);
- var types = [];
- types.pos = firstType.pos;
- types.push(firstType);
- while (parseOptional(47)) {
- types.push(parseJSDocType());
- }
- types.end = scanner.getStartPos();
- return types;
+ else {
+ currentReachabilityState = or(currentReachabilityState, ifFalseState);
}
- function parseJSDocAllType() {
- var result = createNode(250);
- nextToken();
- return finishNode(result);
+ }
+ function bindReturnOrThrow(n) {
+ bind(n.expression);
+ if (n.kind === 204) {
+ hasExplicitReturn = true;
}
- function parseJSDocUnknownOrNullableType() {
- var pos = scanner.getStartPos();
- nextToken();
- if (token === 24 ||
- token === 16 ||
- token === 18 ||
- token === 27 ||
- token === 56 ||
- token === 47) {
- var result = createNode(251, pos);
- return finishNode(result);
- }
- else {
- var result = createNode(255, pos);
- result.type = parseJSDocType();
- return finishNode(result);
+ currentReachabilityState = 4;
+ }
+ function bindBreakOrContinueStatement(n) {
+ bind(n.label);
+ var isValidJump = jumpToLabel(n.label, n.kind === 203 ? currentReachabilityState : 4);
+ if (isValidJump) {
+ currentReachabilityState = 4;
+ }
+ }
+ function bindTryStatement(n) {
+ var preTryState = currentReachabilityState;
+ bind(n.tryBlock);
+ var postTryState = currentReachabilityState;
+ currentReachabilityState = preTryState;
+ bind(n.catchClause);
+ var postCatchState = currentReachabilityState;
+ currentReachabilityState = preTryState;
+ bind(n.finallyBlock);
+ currentReachabilityState = or(postTryState, postCatchState);
+ }
+ function bindSwitchStatement(n) {
+ var preSwitchState = currentReachabilityState;
+ var postSwitchLabel = pushImplicitLabel();
+ bind(n.expression);
+ bind(n.caseBlock);
+ var hasDefault = ts.forEach(n.caseBlock.clauses, function (c) { return c.kind === 242; });
+ var postSwitchState = hasDefault && currentReachabilityState !== 2 ? 4 : preSwitchState;
+ popImplicitLabel(postSwitchLabel, postSwitchState);
+ }
+ function bindCaseBlock(n) {
+ var startState = currentReachabilityState;
+ for (var _i = 0, _a = n.clauses; _i < _a.length; _i++) {
+ var clause = _a[_i];
+ currentReachabilityState = startState;
+ bind(clause);
+ if (clause.statements.length && currentReachabilityState === 2 && options.noFallthroughCasesInSwitch) {
+ errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
}
}
- function parseIsolatedJSDocComment(content, start, length) {
- initializeState("file.js", content, 2, undefined);
- var jsDocComment = parseJSDocComment(undefined, start, length);
- var diagnostics = parseDiagnostics;
- clearState();
- return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined;
+ }
+ function bindLabeledStatement(n) {
+ bind(n.label);
+ var ok = pushNamedLabel(n.label);
+ bind(n.statement);
+ if (ok) {
+ popNamedLabel(n.label, currentReachabilityState);
}
- JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
- function parseJSDocComment(parent, start, length) {
- var comment = parseJSDocCommentWorker(start, length);
- if (comment) {
- fixupParentReferences(comment);
- comment.parent = parent;
- }
- return comment;
+ }
+ function getContainerFlags(node) {
+ switch (node.kind) {
+ case 186:
+ case 214:
+ case 215:
+ case 217:
+ case 155:
+ case 165:
+ return 1;
+ case 147:
+ case 148:
+ case 149:
+ case 143:
+ case 142:
+ case 213:
+ case 144:
+ case 145:
+ case 146:
+ case 152:
+ case 153:
+ case 173:
+ case 174:
+ case 218:
+ case 248:
+ case 216:
+ return 5;
+ case 244:
+ case 199:
+ case 200:
+ case 201:
+ case 220:
+ return 2;
+ case 192:
+ return ts.isFunctionLike(node.parent) ? 0 : 2;
}
- JSDocParser.parseJSDocComment = parseJSDocComment;
- function parseJSDocCommentWorker(start, length) {
- var content = sourceText;
- start = start || 0;
- var end = length === undefined ? content.length : start + length;
- length = end - start;
- ts.Debug.assert(start >= 0);
- ts.Debug.assert(start <= end);
- ts.Debug.assert(end <= content.length);
- var tags;
- var pos;
- if (length >= "/** */".length) {
- if (content.charCodeAt(start) === 47 &&
- content.charCodeAt(start + 1) === 42 &&
- content.charCodeAt(start + 2) === 42 &&
- content.charCodeAt(start + 3) !== 42) {
- var canParseTag = true;
- var seenAsterisk = true;
- for (pos = start + "/**".length; pos < end;) {
- var ch = content.charCodeAt(pos);
- pos++;
- if (ch === 64 && canParseTag) {
- parseTag();
- canParseTag = false;
- continue;
- }
- if (ts.isLineBreak(ch)) {
- canParseTag = true;
- seenAsterisk = false;
- continue;
- }
- if (ts.isWhiteSpace(ch)) {
- continue;
- }
- if (ch === 42) {
- if (seenAsterisk) {
- canParseTag = false;
- }
- seenAsterisk = true;
- continue;
- }
- canParseTag = false;
- }
- }
- }
- return createJSDocComment();
- function createJSDocComment() {
- if (!tags) {
- return undefined;
- }
- var result = createNode(265, start);
- result.tags = tags;
- return finishNode(result, end);
- }
- function skipWhitespace() {
- while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) {
- pos++;
- }
- }
- function parseTag() {
- ts.Debug.assert(content.charCodeAt(pos - 1) === 64);
- var atToken = createNode(55, pos - 1);
- atToken.end = pos;
- var tagName = scanIdentifier();
- if (!tagName) {
- return;
- }
- var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName);
- addTag(tag);
- }
- function handleTag(atToken, tagName) {
- if (tagName) {
- switch (tagName.text) {
- case "param":
- return handleParamTag(atToken, tagName);
- case "return":
- case "returns":
- return handleReturnTag(atToken, tagName);
- case "template":
- return handleTemplateTag(atToken, tagName);
- case "type":
- return handleTypeTag(atToken, tagName);
- }
- }
- return undefined;
- }
- function handleUnknownTag(atToken, tagName) {
- var result = createNode(266, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- return finishNode(result, pos);
- }
- function addTag(tag) {
- if (tag) {
- if (!tags) {
- tags = [];
- tags.pos = tag.pos;
- }
- tags.push(tag);
- tags.end = tag.end;
+ return 0;
+ }
+ function addToContainerChain(next) {
+ if (lastContainer) {
+ lastContainer.nextContainer = next;
+ }
+ lastContainer = next;
+ }
+ function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
+ declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes);
+ }
+ function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) {
+ switch (container.kind) {
+ case 218:
+ return declareModuleMember(node, symbolFlags, symbolExcludes);
+ case 248:
+ return declareSourceFileMember(node, symbolFlags, symbolExcludes);
+ case 186:
+ case 214:
+ return declareClassMember(node, symbolFlags, symbolExcludes);
+ case 217:
+ return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
+ case 155:
+ case 165:
+ case 215:
+ return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
+ case 152:
+ case 153:
+ case 147:
+ case 148:
+ case 149:
+ case 143:
+ case 142:
+ case 144:
+ case 145:
+ case 146:
+ case 213:
+ case 173:
+ case 174:
+ case 216:
+ return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ }
+ function declareClassMember(node, symbolFlags, symbolExcludes) {
+ return node.flags & 64
+ ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
+ : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
+ }
+ function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
+ return ts.isExternalModule(file)
+ ? declareModuleMember(node, symbolFlags, symbolExcludes)
+ : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ function hasExportDeclarations(node) {
+ var body = node.kind === 248 ? node : node.body;
+ if (body.kind === 248 || body.kind === 219) {
+ for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
+ var stat = _a[_i];
+ if (stat.kind === 228 || stat.kind === 227) {
+ return true;
}
}
- function tryParseTypeExpression() {
- skipWhitespace();
- if (content.charCodeAt(pos) !== 123) {
- return undefined;
- }
- var typeExpression = parseJSDocTypeExpression(pos, end - pos);
- pos = typeExpression.end;
- return typeExpression;
+ }
+ return false;
+ }
+ function setExportContextFlag(node) {
+ if (ts.isInAmbientContext(node) && !hasExportDeclarations(node)) {
+ node.flags |= 131072;
+ }
+ else {
+ node.flags &= ~131072;
+ }
+ }
+ function bindModuleDeclaration(node) {
+ setExportContextFlag(node);
+ if (node.name.kind === 9) {
+ declareSymbolAndAddToSymbolTable(node, 512, 106639);
+ }
+ else {
+ var state = getModuleInstanceState(node);
+ if (state === 0) {
+ declareSymbolAndAddToSymbolTable(node, 1024, 0);
}
- function handleParamTag(atToken, tagName) {
- var typeExpression = tryParseTypeExpression();
- skipWhitespace();
- var name;
- var isBracketed;
- if (content.charCodeAt(pos) === 91) {
- pos++;
- skipWhitespace();
- name = scanIdentifier();
- isBracketed = true;
- }
- else {
- name = scanIdentifier();
- }
- if (!name) {
- parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected);
- }
- var preName, postName;
- if (typeExpression) {
- postName = name;
+ else {
+ declareSymbolAndAddToSymbolTable(node, 512, 106639);
+ if (node.symbol.flags & (16 | 32 | 256)) {
+ node.symbol.constEnumOnlyModule = false;
}
else {
- preName = name;
- }
- if (!typeExpression) {
- typeExpression = tryParseTypeExpression();
- }
- var result = createNode(267, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.preParameterName = preName;
- result.typeExpression = typeExpression;
- result.postParameterName = postName;
- result.isBracketed = isBracketed;
- return finishNode(result, pos);
- }
- function handleReturnTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 268; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ var currentModuleIsConstEnumOnly = state === 2;
+ if (node.symbol.constEnumOnlyModule === undefined) {
+ node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
+ }
+ else {
+ node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
+ }
}
- var result = createNode(268, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeExpression = tryParseTypeExpression();
- return finishNode(result, pos);
}
- function handleTypeTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 269; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ }
+ function bindFunctionOrConstructorType(node) {
+ var symbol = createSymbol(131072, getDeclarationName(node));
+ addDeclarationToSymbol(symbol, node, 131072);
+ var typeLiteralSymbol = createSymbol(2048, "__type");
+ addDeclarationToSymbol(typeLiteralSymbol, node, 2048);
+ typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a);
+ var _a;
+ }
+ function bindObjectLiteralExpression(node) {
+ if (inStrictMode) {
+ var seen = {};
+ for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
+ var prop = _a[_i];
+ if (prop.name.kind !== 69) {
+ continue;
}
- var result = createNode(269, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeExpression = tryParseTypeExpression();
- return finishNode(result, pos);
- }
- function handleTemplateTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 270; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ var identifier = prop.name;
+ var currentKind = prop.kind === 245 || prop.kind === 246 || prop.kind === 143
+ ? 1
+ : 2;
+ var existingKind = seen[identifier.text];
+ if (!existingKind) {
+ seen[identifier.text] = currentKind;
+ continue;
}
- var typeParameters = [];
- typeParameters.pos = pos;
- while (true) {
- skipWhitespace();
- var startPos = pos;
- var name_8 = scanIdentifier();
- if (!name_8) {
- parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected);
- return undefined;
- }
- var typeParameter = createNode(137, name_8.pos);
- typeParameter.name = name_8;
- finishNode(typeParameter, pos);
- typeParameters.push(typeParameter);
- skipWhitespace();
- if (content.charCodeAt(pos) !== 44) {
- break;
- }
- pos++;
+ if (currentKind === 1 && existingKind === 1) {
+ var span = ts.getErrorSpanForNode(file, identifier);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
}
- typeParameters.end = pos;
- var result = createNode(270, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeParameters = typeParameters;
- return finishNode(result, pos);
}
- function scanIdentifier() {
- var startPos = pos;
- for (; pos < end; pos++) {
- var ch = content.charCodeAt(pos);
- if (pos === startPos && ts.isIdentifierStart(ch, 2)) {
- continue;
- }
- else if (pos > startPos && ts.isIdentifierPart(ch, 2)) {
- continue;
- }
+ }
+ return bindAnonymousDeclaration(node, 4096, "__object");
+ }
+ function bindAnonymousDeclaration(node, symbolFlags, name) {
+ var symbol = createSymbol(symbolFlags, name);
+ addDeclarationToSymbol(symbol, node, symbolFlags);
+ }
+ function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
+ switch (blockScopeContainer.kind) {
+ case 218:
+ declareModuleMember(node, symbolFlags, symbolExcludes);
+ break;
+ case 248:
+ if (ts.isExternalModule(container)) {
+ declareModuleMember(node, symbolFlags, symbolExcludes);
break;
}
- if (startPos === pos) {
- return undefined;
+ default:
+ if (!blockScopeContainer.locals) {
+ blockScopeContainer.locals = {};
+ addToContainerChain(blockScopeContainer);
}
- var result = createNode(69, startPos);
- result.text = content.substring(startPos, pos);
- return finishNode(result, pos);
+ declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ }
+ function bindBlockScopedVariableDeclaration(node) {
+ bindBlockScopedDeclaration(node, 2, 107455);
+ }
+ function checkStrictModeIdentifier(node) {
+ if (inStrictMode &&
+ node.originalKeywordKind >= 106 &&
+ node.originalKeywordKind <= 114 &&
+ !ts.isIdentifierName(node)) {
+ if (!file.parseDiagnostics.length) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
+ }
+ }
+ }
+ function getStrictModeIdentifierMessage(node) {
+ if (ts.getContainingClass(node)) {
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
+ }
+ if (file.externalModuleIndicator) {
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
+ }
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
+ }
+ function checkStrictModeBinaryExpression(node) {
+ if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
+ checkStrictModeEvalOrArguments(node, node.left);
+ }
+ }
+ function checkStrictModeCatchClause(node) {
+ if (inStrictMode && node.variableDeclaration) {
+ checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
+ }
+ }
+ function checkStrictModeDeleteExpression(node) {
+ if (inStrictMode && node.expression.kind === 69) {
+ var span = ts.getErrorSpanForNode(file, node.expression);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
+ }
+ }
+ function isEvalOrArgumentsIdentifier(node) {
+ return node.kind === 69 &&
+ (node.text === "eval" || node.text === "arguments");
+ }
+ function checkStrictModeEvalOrArguments(contextNode, name) {
+ if (name && name.kind === 69) {
+ var identifier = name;
+ if (isEvalOrArgumentsIdentifier(identifier)) {
+ var span = ts.getErrorSpanForNode(file, name);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
}
}
- JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
- })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
- })(Parser || (Parser = {}));
- var IncrementalParser;
- (function (IncrementalParser) {
- function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
- aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2);
- checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
- if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
- return sourceFile;
+ }
+ function getStrictModeEvalOrArgumentsMessage(node) {
+ if (ts.getContainingClass(node)) {
+ return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
}
- if (sourceFile.statements.length === 0) {
- return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, undefined, true);
+ if (file.externalModuleIndicator) {
+ return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
}
- var incrementalSourceFile = sourceFile;
- ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
- incrementalSourceFile.hasBeenIncrementallyParsed = true;
- var oldText = sourceFile.text;
- var syntaxCursor = createSyntaxCursor(sourceFile);
- var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
- checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
- ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
- ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
- ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
- var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
- updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
- var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, true);
- return result;
+ return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
}
- IncrementalParser.updateSourceFile = updateSourceFile;
- function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
- if (isArray) {
- visitArray(element);
+ function checkStrictModeFunctionName(node) {
+ if (inStrictMode) {
+ checkStrictModeEvalOrArguments(node, node.name);
}
- else {
- visitNode(element);
+ }
+ function checkStrictModeNumericLiteral(node) {
+ if (inStrictMode && node.flags & 32768) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
}
- return;
- function visitNode(node) {
- var text = "";
- if (aggressiveChecks && shouldCheckNode(node)) {
- text = oldText.substring(node.pos, node.end);
- }
- if (node._children) {
- node._children = undefined;
- }
- if (node.jsDocComment) {
- node.jsDocComment = undefined;
- }
- node.pos += delta;
- node.end += delta;
- if (aggressiveChecks && shouldCheckNode(node)) {
- ts.Debug.assert(text === newText.substring(node.pos, node.end));
+ }
+ function checkStrictModePostfixUnaryExpression(node) {
+ if (inStrictMode) {
+ checkStrictModeEvalOrArguments(node, node.operand);
+ }
+ }
+ function checkStrictModePrefixUnaryExpression(node) {
+ if (inStrictMode) {
+ if (node.operator === 41 || node.operator === 42) {
+ checkStrictModeEvalOrArguments(node, node.operand);
}
- forEachChild(node, visitNode, visitArray);
- checkNodePositions(node, aggressiveChecks);
}
- function visitArray(array) {
- array._children = undefined;
- array.pos += delta;
- array.end += delta;
- for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
- var node = array_7[_i];
- visitNode(node);
+ }
+ function checkStrictModeWithStatement(node) {
+ if (inStrictMode) {
+ errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
+ }
+ }
+ function errorOnFirstToken(node, message, arg0, arg1, arg2) {
+ var span = ts.getSpanOfTokenAtPosition(file, node.pos);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
+ }
+ function getDestructuringParameterName(node) {
+ return "__" + ts.indexOf(node.parent.parameters, node);
+ }
+ function bind(node) {
+ if (!node) {
+ return;
+ }
+ node.parent = parent;
+ var savedInStrictMode = inStrictMode;
+ if (!savedInStrictMode) {
+ updateStrictMode(node);
+ }
+ bindWorker(node);
+ bindChildren(node);
+ inStrictMode = savedInStrictMode;
+ }
+ function updateStrictMode(node) {
+ switch (node.kind) {
+ case 248:
+ case 219:
+ updateStrictModeStatementList(node.statements);
+ return;
+ case 192:
+ if (ts.isFunctionLike(node.parent)) {
+ updateStrictModeStatementList(node.statements);
+ }
+ return;
+ case 214:
+ case 186:
+ inStrictMode = true;
+ return;
+ }
+ }
+ function updateStrictModeStatementList(statements) {
+ for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
+ var statement = statements_1[_i];
+ if (!ts.isPrologueDirective(statement)) {
+ return;
+ }
+ if (isUseStrictPrologueDirective(statement)) {
+ inStrictMode = true;
+ return;
}
}
}
- function shouldCheckNode(node) {
+ function isUseStrictPrologueDirective(node) {
+ var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression);
+ return nodeText === "\"use strict\"" || nodeText === "'use strict'";
+ }
+ function bindWorker(node) {
switch (node.kind) {
- case 9:
- case 8:
case 69:
- return true;
+ return checkStrictModeIdentifier(node);
+ case 181:
+ if (ts.isInJavaScriptFile(node)) {
+ if (ts.isExportsPropertyAssignment(node)) {
+ bindExportsPropertyAssignment(node);
+ }
+ else if (ts.isModuleExportsAssignment(node)) {
+ bindModuleExportsAssignment(node);
+ }
+ }
+ return checkStrictModeBinaryExpression(node);
+ case 244:
+ return checkStrictModeCatchClause(node);
+ case 175:
+ return checkStrictModeDeleteExpression(node);
+ case 8:
+ return checkStrictModeNumericLiteral(node);
+ case 180:
+ return checkStrictModePostfixUnaryExpression(node);
+ case 179:
+ return checkStrictModePrefixUnaryExpression(node);
+ case 205:
+ return checkStrictModeWithStatement(node);
+ case 97:
+ seenThisKeyword = true;
+ return;
+ case 137:
+ return declareSymbolAndAddToSymbolTable(node, 262144, 530912);
+ case 138:
+ return bindParameter(node);
+ case 211:
+ case 163:
+ return bindVariableDeclarationOrBindingElement(node);
+ case 141:
+ case 140:
+ return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455);
+ case 245:
+ case 246:
+ return bindPropertyOrMethodOrAccessor(node, 4, 107455);
+ case 247:
+ return bindPropertyOrMethodOrAccessor(node, 8, 107455);
+ case 147:
+ case 148:
+ case 149:
+ return declareSymbolAndAddToSymbolTable(node, 131072, 0);
+ case 143:
+ case 142:
+ return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263);
+ case 213:
+ checkStrictModeFunctionName(node);
+ return declareSymbolAndAddToSymbolTable(node, 16, 106927);
+ case 144:
+ return declareSymbolAndAddToSymbolTable(node, 16384, 0);
+ case 145:
+ return bindPropertyOrMethodOrAccessor(node, 32768, 41919);
+ case 146:
+ return bindPropertyOrMethodOrAccessor(node, 65536, 74687);
+ case 152:
+ case 153:
+ return bindFunctionOrConstructorType(node);
+ case 155:
+ return bindAnonymousDeclaration(node, 2048, "__type");
+ case 165:
+ return bindObjectLiteralExpression(node);
+ case 173:
+ case 174:
+ checkStrictModeFunctionName(node);
+ var bindingName = node.name ? node.name.text : "__function";
+ return bindAnonymousDeclaration(node, 16, bindingName);
+ case 168:
+ if (ts.isInJavaScriptFile(node)) {
+ bindCallExpression(node);
+ }
+ break;
+ case 186:
+ case 214:
+ return bindClassLikeDeclaration(node);
+ case 215:
+ return bindBlockScopedDeclaration(node, 64, 792960);
+ case 216:
+ return bindBlockScopedDeclaration(node, 524288, 793056);
+ case 217:
+ return bindEnumDeclaration(node);
+ case 218:
+ return bindModuleDeclaration(node);
+ case 221:
+ case 224:
+ case 226:
+ case 230:
+ return declareSymbolAndAddToSymbolTable(node, 8388608, 8388608);
+ case 223:
+ return bindImportClause(node);
+ case 228:
+ return bindExportDeclaration(node);
+ case 227:
+ return bindExportAssignment(node);
+ case 248:
+ return bindSourceFileIfExternalModule();
}
- return false;
}
- function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
- ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
- ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
- ts.Debug.assert(element.pos <= element.end);
- element.pos = Math.min(element.pos, changeRangeNewEnd);
- if (element.end >= changeRangeOldEnd) {
- element.end += delta;
+ function bindSourceFileIfExternalModule() {
+ setExportContextFlag(file);
+ if (ts.isExternalModule(file)) {
+ bindSourceFileAsExternalModule();
+ }
+ }
+ function bindSourceFileAsExternalModule() {
+ bindAnonymousDeclaration(file, 512, "\"" + ts.removeFileExtension(file.fileName) + "\"");
+ }
+ function bindExportAssignment(node) {
+ var boundExpression = node.kind === 227 ? node.expression : node.right;
+ if (!container.symbol || !container.symbol.exports) {
+ bindAnonymousDeclaration(node, 8388608, getDeclarationName(node));
}
- else {
- element.end = Math.min(element.end, changeRangeNewEnd);
+ else if (boundExpression.kind === 69) {
+ declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608);
}
- ts.Debug.assert(element.pos <= element.end);
- if (element.parent) {
- ts.Debug.assert(element.pos >= element.parent.pos);
- ts.Debug.assert(element.end <= element.parent.end);
+ else {
+ declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608);
}
}
- function checkNodePositions(node, aggressiveChecks) {
- if (aggressiveChecks) {
- var pos = node.pos;
- forEachChild(node, function (child) {
- ts.Debug.assert(child.pos >= pos);
- pos = child.end;
- });
- ts.Debug.assert(pos <= node.end);
+ function bindExportDeclaration(node) {
+ if (!container.symbol || !container.symbol.exports) {
+ bindAnonymousDeclaration(node, 1073741824, getDeclarationName(node));
+ }
+ else if (!node.exportClause) {
+ declareSymbol(container.symbol.exports, container.symbol, node, 1073741824, 0);
}
}
- function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
- visitNode(sourceFile);
- return;
- function visitNode(child) {
- ts.Debug.assert(child.pos <= child.end);
- if (child.pos > changeRangeOldEnd) {
- moveElementEntirelyPastChangeRange(child, false, delta, oldText, newText, aggressiveChecks);
- return;
- }
- var fullEnd = child.end;
- if (fullEnd >= changeStart) {
- child.intersectsChange = true;
- child._children = undefined;
- adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
- forEachChild(child, visitNode, visitArray);
- checkNodePositions(child, aggressiveChecks);
- return;
- }
- ts.Debug.assert(fullEnd < changeStart);
+ function bindImportClause(node) {
+ if (node.name) {
+ declareSymbolAndAddToSymbolTable(node, 8388608, 8388608);
}
- function visitArray(array) {
- ts.Debug.assert(array.pos <= array.end);
- if (array.pos > changeRangeOldEnd) {
- moveElementEntirelyPastChangeRange(array, true, delta, oldText, newText, aggressiveChecks);
- return;
- }
- var fullEnd = array.end;
- if (fullEnd >= changeStart) {
- array.intersectsChange = true;
- array._children = undefined;
- adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
- for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
- var node = array_8[_i];
- visitNode(node);
- }
- return;
- }
- ts.Debug.assert(fullEnd < changeStart);
+ }
+ function setCommonJsModuleIndicator(node) {
+ if (!file.commonJsModuleIndicator) {
+ file.commonJsModuleIndicator = node;
+ bindSourceFileAsExternalModule();
}
}
- function extendToAffectedRange(sourceFile, changeRange) {
- var maxLookahead = 1;
- var start = changeRange.span.start;
- for (var i = 0; start > 0 && i <= maxLookahead; i++) {
- var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
- ts.Debug.assert(nearestNode.pos <= start);
- var position = nearestNode.pos;
- start = Math.max(0, position - 1);
+ function bindExportsPropertyAssignment(node) {
+ setCommonJsModuleIndicator(node);
+ declareSymbol(file.symbol.exports, file.symbol, node.left, 4 | 7340032, 0);
+ }
+ function bindModuleExportsAssignment(node) {
+ setCommonJsModuleIndicator(node);
+ bindExportAssignment(node);
+ }
+ function bindCallExpression(node) {
+ if (!file.commonJsModuleIndicator && ts.isRequireCall(node)) {
+ setCommonJsModuleIndicator(node);
}
- var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
- var finalLength = changeRange.newLength + (changeRange.span.start - start);
- return ts.createTextChangeRange(finalSpan, finalLength);
}
- function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
- var bestResult = sourceFile;
- var lastNodeEntirelyBeforePosition;
- forEachChild(sourceFile, visit);
- if (lastNodeEntirelyBeforePosition) {
- var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition);
- if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
- bestResult = lastChildOfLastEntireNodeBeforePosition;
+ function bindClassLikeDeclaration(node) {
+ if (node.kind === 214) {
+ bindBlockScopedDeclaration(node, 32, 899519);
+ }
+ else {
+ var bindingName = node.name ? node.name.text : "__class";
+ bindAnonymousDeclaration(node, 32, bindingName);
+ if (node.name) {
+ classifiableNames[node.name.text] = node.name.text;
}
}
- return bestResult;
- function getLastChild(node) {
- while (true) {
- var lastChild = getLastChildWorker(node);
- if (lastChild) {
- node = lastChild;
- }
- else {
- return node;
- }
+ var symbol = node.symbol;
+ var prototypeSymbol = createSymbol(4 | 134217728, "prototype");
+ if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) {
+ if (node.name) {
+ node.name.parent = node;
}
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
}
- function getLastChildWorker(node) {
- var last = undefined;
- forEachChild(node, function (child) {
- if (ts.nodeIsPresent(child)) {
- last = child;
- }
- });
- return last;
+ symbol.exports[prototypeSymbol.name] = prototypeSymbol;
+ prototypeSymbol.parent = symbol;
+ }
+ function bindEnumDeclaration(node) {
+ return ts.isConst(node)
+ ? bindBlockScopedDeclaration(node, 128, 899967)
+ : bindBlockScopedDeclaration(node, 256, 899327);
+ }
+ function bindVariableDeclarationOrBindingElement(node) {
+ if (inStrictMode) {
+ checkStrictModeEvalOrArguments(node, node.name);
}
- function visit(child) {
- if (ts.nodeIsMissing(child)) {
- return;
+ if (!ts.isBindingPattern(node.name)) {
+ if (ts.isBlockOrCatchScoped(node)) {
+ bindBlockScopedVariableDeclaration(node);
}
- if (child.pos <= position) {
- if (child.pos >= bestResult.pos) {
- bestResult = child;
- }
- if (position < child.end) {
- forEachChild(child, visit);
- return true;
- }
- else {
- ts.Debug.assert(child.end <= position);
- lastNodeEntirelyBeforePosition = child;
- }
+ else if (ts.isParameterDeclaration(node)) {
+ declareSymbolAndAddToSymbolTable(node, 1, 107455);
}
else {
- ts.Debug.assert(child.pos > position);
- return true;
+ declareSymbolAndAddToSymbolTable(node, 1, 107454);
}
}
}
- function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
- var oldText = sourceFile.text;
- if (textChangeRange) {
- ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
- if (aggressiveChecks || ts.Debug.shouldAssert(3)) {
- var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
- var newTextPrefix = newText.substr(0, textChangeRange.span.start);
- ts.Debug.assert(oldTextPrefix === newTextPrefix);
- var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
- var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
- ts.Debug.assert(oldTextSuffix === newTextSuffix);
- }
+ function bindParameter(node) {
+ if (inStrictMode) {
+ checkStrictModeEvalOrArguments(node, node.name);
+ }
+ if (ts.isBindingPattern(node.name)) {
+ bindAnonymousDeclaration(node, 1, getDestructuringParameterName(node));
+ }
+ else {
+ declareSymbolAndAddToSymbolTable(node, 1, 107455);
+ }
+ if (node.flags & 56 &&
+ node.parent.kind === 144 &&
+ ts.isClassLike(node.parent.parent)) {
+ var classDeclaration = node.parent.parent;
+ declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 107455);
}
}
- function createSyntaxCursor(sourceFile) {
- var currentArray = sourceFile.statements;
- var currentArrayIndex = 0;
- ts.Debug.assert(currentArrayIndex < currentArray.length);
- var current = currentArray[currentArrayIndex];
- var lastQueriedPosition = -1;
- return {
- currentNode: function (position) {
- if (position !== lastQueriedPosition) {
- if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
- currentArrayIndex++;
- current = currentArray[currentArrayIndex];
- }
- if (!current || current.pos !== position) {
- findHighestListElementThatStartsAtPosition(position);
- }
- }
- lastQueriedPosition = position;
- ts.Debug.assert(!current || current.pos === position);
- return current;
- }
- };
- function findHighestListElementThatStartsAtPosition(position) {
- currentArray = undefined;
- currentArrayIndex = -1;
- current = undefined;
- forEachChild(sourceFile, visitNode, visitArray);
- return;
- function visitNode(node) {
- if (position >= node.pos && position < node.end) {
- forEachChild(node, visitNode, visitArray);
- return true;
- }
- return false;
+ function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
+ return ts.hasDynamicName(node)
+ ? bindAnonymousDeclaration(node, symbolFlags, "__computed")
+ : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
+ }
+ function pushNamedLabel(name) {
+ initializeReachabilityStateIfNecessary();
+ if (ts.hasProperty(labelIndexMap, name.text)) {
+ return false;
+ }
+ labelIndexMap[name.text] = labelStack.push(1) - 1;
+ return true;
+ }
+ function pushImplicitLabel() {
+ initializeReachabilityStateIfNecessary();
+ var index = labelStack.push(1) - 1;
+ implicitLabels.push(index);
+ return index;
+ }
+ function popNamedLabel(label, outerState) {
+ var index = labelIndexMap[label.text];
+ ts.Debug.assert(index !== undefined);
+ ts.Debug.assert(labelStack.length == index + 1);
+ labelIndexMap[label.text] = undefined;
+ setCurrentStateAtLabel(labelStack.pop(), outerState, label);
+ }
+ function popImplicitLabel(implicitLabelIndex, outerState) {
+ if (labelStack.length !== implicitLabelIndex + 1) {
+ ts.Debug.assert(false, "Label stack: " + labelStack.length + ", index:" + implicitLabelIndex);
+ }
+ var i = implicitLabels.pop();
+ if (implicitLabelIndex !== i) {
+ ts.Debug.assert(false, "i: " + i + ", index: " + implicitLabelIndex);
+ }
+ setCurrentStateAtLabel(labelStack.pop(), outerState, undefined);
+ }
+ function setCurrentStateAtLabel(innerMergedState, outerState, label) {
+ if (innerMergedState === 1) {
+ if (label && !options.allowUnusedLabels) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(label, ts.Diagnostics.Unused_label));
}
- function visitArray(array) {
- if (position >= array.pos && position < array.end) {
- for (var i = 0, n = array.length; i < n; i++) {
- var child = array[i];
- if (child) {
- if (child.pos === position) {
- currentArray = array;
- currentArrayIndex = i;
- current = child;
- return true;
- }
- else {
- if (child.pos < position && position < child.end) {
- forEachChild(child, visitNode, visitArray);
- return true;
- }
- }
- }
+ currentReachabilityState = outerState;
+ }
+ else {
+ currentReachabilityState = or(innerMergedState, outerState);
+ }
+ }
+ function jumpToLabel(label, outerState) {
+ initializeReachabilityStateIfNecessary();
+ var index = label ? labelIndexMap[label.text] : ts.lastOrUndefined(implicitLabels);
+ if (index === undefined) {
+ return false;
+ }
+ var stateAtLabel = labelStack[index];
+ labelStack[index] = stateAtLabel === 1 ? outerState : or(stateAtLabel, outerState);
+ return true;
+ }
+ function checkUnreachable(node) {
+ switch (currentReachabilityState) {
+ case 4:
+ var reportError = (ts.isStatement(node) && node.kind !== 194) ||
+ node.kind === 214 ||
+ (node.kind === 218 && shouldReportErrorOnModuleDeclaration(node)) ||
+ (node.kind === 217 && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
+ if (reportError) {
+ currentReachabilityState = 8;
+ var reportUnreachableCode = !options.allowUnreachableCode &&
+ !ts.isInAmbientContext(node) &&
+ (node.kind !== 193 ||
+ ts.getCombinedNodeFlags(node.declarationList) & 24576 ||
+ ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
+ if (reportUnreachableCode) {
+ errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
}
}
+ case 8:
+ return true;
+ default:
return false;
- }
+ }
+ function shouldReportErrorOnModuleDeclaration(node) {
+ var instanceState = getModuleInstanceState(node);
+ return instanceState === 1 || (instanceState === 2 && options.preserveConstEnums);
}
}
- })(IncrementalParser || (IncrementalParser = {}));
+ function initializeReachabilityStateIfNecessary() {
+ if (labelIndexMap) {
+ return;
+ }
+ currentReachabilityState = 2;
+ labelIndexMap = {};
+ labelStack = [];
+ implicitLabels = [];
+ }
+ }
})(ts || (ts = {}));
var ts;
(function (ts) {
@@ -10853,7 +10987,7 @@ var ts;
symbolToString: symbolToString,
getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
getRootSymbols: getRootSymbols,
- getContextualType: getContextualType,
+ getContextualType: getApparentTypeOfContextualType,
getFullyQualifiedName: getFullyQualifiedName,
getResolvedSignature: getResolvedSignature,
getConstantValue: getConstantValue,
@@ -11109,7 +11243,7 @@ var ts;
return ts.getAncestor(node, 248);
}
function isGlobalSourceFile(node) {
- return node.kind === 248 && !ts.isExternalModule(node);
+ return node.kind === 248 && !ts.isExternalOrCommonJsModule(node);
}
function getSymbol(symbols, name, meaning) {
if (meaning && ts.hasProperty(symbols, name)) {
@@ -11195,23 +11329,24 @@ var ts;
}
switch (location.kind) {
case 248:
- if (!ts.isExternalModule(location))
+ if (!ts.isExternalOrCommonJsModule(location))
break;
case 218:
var moduleExports = getSymbolOfNode(location).exports;
if (location.kind === 248 ||
(location.kind === 218 && location.name.kind === 9)) {
+ if (result = moduleExports["default"]) {
+ var localSymbol = ts.getLocalSymbolForExportDefault(result);
+ if (localSymbol && (result.flags & meaning) && localSymbol.name === name) {
+ break loop;
+ }
+ result = undefined;
+ }
if (ts.hasProperty(moduleExports, name) &&
moduleExports[name].flags === 8388608 &&
ts.getDeclarationOfKind(moduleExports[name], 230)) {
break;
}
- result = moduleExports["default"];
- var localSymbol = ts.getLocalSymbolForExportDefault(result);
- if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
- break loop;
- }
- result = undefined;
}
if (result = getSymbol(moduleExports, name, meaning & 8914931)) {
break loop;
@@ -11569,6 +11704,9 @@ var ts;
if (moduleName === undefined) {
return;
}
+ if (moduleName.indexOf("!") >= 0) {
+ moduleName = moduleName.substr(0, moduleName.indexOf("!"));
+ }
var isRelative = ts.isExternalModuleNameRelative(moduleName);
if (!isRelative) {
var symbol = getSymbol(globals, "\"" + moduleName + "\"", 512);
@@ -11739,7 +11877,7 @@ var ts;
}
switch (location_1.kind) {
case 248:
- if (!ts.isExternalModule(location_1)) {
+ if (!ts.isExternalOrCommonJsModule(location_1)) {
break;
}
case 218:
@@ -11866,7 +12004,7 @@ var ts;
}
function hasExternalModuleSymbol(declaration) {
return (declaration.kind === 218 && declaration.name.kind === 9) ||
- (declaration.kind === 248 && ts.isExternalModule(declaration));
+ (declaration.kind === 248 && ts.isExternalOrCommonJsModule(declaration));
}
function hasVisibleDeclarations(symbol) {
var aliasesToMakeVisible;
@@ -12064,7 +12202,7 @@ var ts;
writeAnonymousType(type, flags);
}
else if (type.flags & 256) {
- writer.writeStringLiteral(type.text);
+ writer.writeStringLiteral("\"" + ts.escapeString(type.text) + "\"");
}
else {
writePunctuation(writer, 15);
@@ -12428,7 +12566,7 @@ var ts;
}
}
else if (node.kind === 248) {
- return ts.isExternalModule(node) ? node : undefined;
+ return ts.isExternalOrCommonJsModule(node) ? node : undefined;
}
}
ts.Debug.fail("getContainingModule cant reach here");
@@ -12633,6 +12771,23 @@ var ts;
var symbol = getSymbolOfNode(node);
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
}
+ function getTextOfPropertyName(name) {
+ switch (name.kind) {
+ case 69:
+ return name.text;
+ case 9:
+ case 8:
+ return name.text;
+ case 136:
+ if (ts.isStringOrNumericLiteral(name.expression.kind)) {
+ return name.expression.text;
+ }
+ }
+ return undefined;
+ }
+ function isComputedNonLiteralName(name) {
+ return name.kind === 136 && !ts.isStringOrNumericLiteral(name.expression.kind);
+ }
function getTypeForBindingElement(declaration) {
var pattern = declaration.parent;
var parentType = getTypeForBindingElementParent(pattern.parent);
@@ -12648,8 +12803,12 @@ var ts;
var type;
if (pattern.kind === 161) {
var name_10 = declaration.propertyName || declaration.name;
- type = getTypeOfPropertyOfType(parentType, name_10.text) ||
- isNumericLiteralName(name_10.text) && getIndexTypeOfType(parentType, 1) ||
+ if (isComputedNonLiteralName(name_10)) {
+ return anyType;
+ }
+ var text = getTextOfPropertyName(name_10);
+ type = getTypeOfPropertyOfType(parentType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1) ||
getIndexTypeOfType(parentType, 0);
if (!type) {
error(name_10, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_10));
@@ -12727,10 +12886,16 @@ var ts;
}
function getTypeFromObjectBindingPattern(pattern, includePatternInType) {
var members = {};
+ var hasComputedProperties = false;
ts.forEach(pattern.elements, function (e) {
- var flags = 4 | 67108864 | (e.initializer ? 536870912 : 0);
var name = e.propertyName || e.name;
- var symbol = createSymbol(flags, name.text);
+ if (isComputedNonLiteralName(name)) {
+ hasComputedProperties = true;
+ return;
+ }
+ var text = getTextOfPropertyName(name);
+ var flags = 4 | 67108864 | (e.initializer ? 536870912 : 0);
+ var symbol = createSymbol(flags, text);
symbol.type = getTypeFromBindingElement(e, includePatternInType);
symbol.bindingElement = e;
members[symbol.name] = symbol;
@@ -12739,6 +12904,9 @@ var ts;
if (includePatternInType) {
result.pattern = pattern;
}
+ if (hasComputedProperties) {
+ result.flags |= 67108864;
+ }
return result;
}
function getTypeFromArrayBindingPattern(pattern, includePatternInType) {
@@ -12789,6 +12957,12 @@ var ts;
if (declaration.kind === 227) {
return links.type = checkExpression(declaration.expression);
}
+ if (declaration.kind === 181) {
+ return links.type = checkExpression(declaration.right);
+ }
+ if (declaration.kind === 166) {
+ return checkExpressionCached(declaration.parent.right);
+ }
if (!pushTypeResolution(symbol, 0)) {
return unknownType;
}
@@ -13038,17 +13212,19 @@ var ts;
}
function resolveBaseTypesOfClass(type) {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
- var baseContructorType = getBaseConstructorTypeOfClass(type);
- if (!(baseContructorType.flags & 80896)) {
+ var baseConstructorType = getBaseConstructorTypeOfClass(type);
+ if (!(baseConstructorType.flags & 80896)) {
return;
}
var baseTypeNode = getBaseTypeNodeOfClass(type);
var baseType;
- if (baseContructorType.symbol && baseContructorType.symbol.flags & 32) {
- baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseContructorType.symbol);
+ var originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
+ if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 &&
+ areAllOuterTypeParametersApplied(originalBaseType)) {
+ baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
}
else {
- var constructors = getInstantiatedConstructorsForTypeArguments(baseContructorType, baseTypeNode.typeArguments);
+ var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments);
if (!constructors.length) {
error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
return;
@@ -13073,6 +13249,15 @@ var ts;
type.resolvedBaseTypes.push(baseType);
}
}
+ function areAllOuterTypeParametersApplied(type) {
+ var outerTypeParameters = type.outerTypeParameters;
+ if (outerTypeParameters) {
+ var last = outerTypeParameters.length - 1;
+ var typeArguments = type.typeArguments;
+ return outerTypeParameters[last].symbol !== typeArguments[last].symbol;
+ }
+ return true;
+ }
function resolveBaseTypesOfInterface(type) {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
@@ -13144,7 +13329,7 @@ var ts;
type.typeArguments = type.typeParameters;
type.thisType = createType(512 | 33554432);
type.thisType.symbol = symbol;
- type.thisType.constraint = getTypeWithThisArgument(type);
+ type.thisType.constraint = type;
}
}
return links.declaredType;
@@ -13619,14 +13804,19 @@ var ts;
type = getApparentType(type);
return type.flags & 49152 ? getPropertiesOfUnionOrIntersectionType(type) : getPropertiesOfObjectType(type);
}
+ function getApparentTypeOfTypeParameter(type) {
+ if (!type.resolvedApparentType) {
+ var constraintType = getConstraintOfTypeParameter(type);
+ while (constraintType && constraintType.flags & 512) {
+ constraintType = getConstraintOfTypeParameter(constraintType);
+ }
+ type.resolvedApparentType = getTypeWithThisArgument(constraintType || emptyObjectType, type);
+ }
+ return type.resolvedApparentType;
+ }
function getApparentType(type) {
if (type.flags & 512) {
- do {
- type = getConstraintOfTypeParameter(type);
- } while (type && type.flags & 512);
- if (!type) {
- type = emptyObjectType;
- }
+ type = getApparentTypeOfTypeParameter(type);
}
if (type.flags & 258) {
type = globalStringType;
@@ -13779,7 +13969,7 @@ var ts;
if (node.initializer) {
var signatureDeclaration = node.parent;
var signature = getSignatureFromDeclaration(signatureDeclaration);
- var parameterIndex = signatureDeclaration.parameters.indexOf(node);
+ var parameterIndex = ts.indexOf(signatureDeclaration.parameters, node);
ts.Debug.assert(parameterIndex >= 0);
return parameterIndex >= signature.minArgumentCount;
}
@@ -13874,6 +14064,16 @@ var ts;
}
return result;
}
+ function resolveExternalModuleTypeByLiteral(name) {
+ var moduleSym = resolveExternalModuleName(name, name);
+ if (moduleSym) {
+ var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
+ if (resolvedModuleSymbol) {
+ return getTypeOfSymbol(resolvedModuleSymbol);
+ }
+ }
+ return anyType;
+ }
function getReturnTypeOfSignature(signature) {
if (!signature.resolvedReturnType) {
if (!pushTypeResolution(signature, 3)) {
@@ -14335,11 +14535,12 @@ var ts;
return links.resolvedType;
}
function getStringLiteralType(node) {
- if (ts.hasProperty(stringLiteralTypes, node.text)) {
- return stringLiteralTypes[node.text];
+ var text = node.text;
+ if (ts.hasProperty(stringLiteralTypes, text)) {
+ return stringLiteralTypes[text];
}
- var type = stringLiteralTypes[node.text] = createType(256);
- type.text = ts.getTextOfNode(node);
+ var type = stringLiteralTypes[text] = createType(256);
+ type.text = text;
return type;
}
function getTypeFromStringLiteral(node) {
@@ -14808,7 +15009,7 @@ var ts;
return false;
}
function hasExcessProperties(source, target, reportErrors) {
- if (someConstituentTypeHasKind(target, 80896)) {
+ if (!(target.flags & 67108864) && someConstituentTypeHasKind(target, 80896)) {
for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
var prop = _a[_i];
if (!isKnownProperty(target, prop.name)) {
@@ -14898,9 +15099,6 @@ var ts;
return result;
}
function typeParameterIdenticalTo(source, target) {
- if (source.symbol.name !== target.symbol.name) {
- return 0;
- }
if (source.constraint === target.constraint) {
return -1;
}
@@ -15345,18 +15543,24 @@ var ts;
}
return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
}
+ function isMatchingSignature(source, target, partialMatch) {
+ if (source.parameters.length === target.parameters.length &&
+ source.minArgumentCount === target.minArgumentCount &&
+ source.hasRestParameter === target.hasRestParameter) {
+ return true;
+ }
+ if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (source.hasRestParameter && !target.hasRestParameter ||
+ source.hasRestParameter === target.hasRestParameter && source.parameters.length >= target.parameters.length)) {
+ return true;
+ }
+ return false;
+ }
function compareSignatures(source, target, partialMatch, ignoreReturnTypes, compareTypes) {
if (source === target) {
return -1;
}
- if (source.parameters.length !== target.parameters.length ||
- source.minArgumentCount !== target.minArgumentCount ||
- source.hasRestParameter !== target.hasRestParameter) {
- if (!partialMatch ||
- source.parameters.length < target.parameters.length && !source.hasRestParameter ||
- source.minArgumentCount > target.minArgumentCount) {
- return 0;
- }
+ if (!(isMatchingSignature(source, target, partialMatch))) {
+ return 0;
}
var result = -1;
if (source.typeParameters && target.typeParameters) {
@@ -15441,6 +15645,9 @@ var ts;
function isTupleLikeType(type) {
return !!getPropertyOfType(type, "0");
}
+ function isStringLiteralType(type) {
+ return type.flags & 256;
+ }
function isTupleType(type) {
return !!(type.flags & 8192);
}
@@ -16032,7 +16239,7 @@ var ts;
}
}
function narrowTypeByInstanceof(type, expr, assumeTrue) {
- if (isTypeAny(type) || !assumeTrue || expr.left.kind !== 69 || getResolvedSymbol(expr.left) !== symbol) {
+ if (isTypeAny(type) || expr.left.kind !== 69 || getResolvedSymbol(expr.left) !== symbol) {
return type;
}
var rightType = checkExpression(expr.right);
@@ -16060,6 +16267,12 @@ var ts;
}
}
if (targetType) {
+ if (!assumeTrue) {
+ if (type.flags & 16384) {
+ return getUnionType(ts.filter(type.types, function (t) { return !isTypeSubtypeOf(t, targetType); }));
+ }
+ return type;
+ }
return getNarrowedType(type, targetType);
}
return type;
@@ -16471,6 +16684,9 @@ var ts;
function getIndexTypeOfContextualType(type, kind) {
return applyToContextualType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); });
}
+ function contextualTypeIsStringLiteralType(type) {
+ return !!(type.flags & 16384 ? ts.forEach(type.types, isStringLiteralType) : isStringLiteralType(type));
+ }
function contextualTypeIsTupleLikeType(type) {
return !!(type.flags & 16384 ? ts.forEach(type.types, isTupleLikeType) : isTupleLikeType(type));
}
@@ -16486,7 +16702,7 @@ var ts;
}
function getContextualTypeForObjectLiteralElement(element) {
var objectLiteral = element.parent;
- var type = getContextualType(objectLiteral);
+ var type = getApparentTypeOfContextualType(objectLiteral);
if (type) {
if (!ts.hasDynamicName(element)) {
var symbolName = getSymbolOfNode(element).name;
@@ -16502,7 +16718,7 @@ var ts;
}
function getContextualTypeForElementExpression(node) {
var arrayLiteral = node.parent;
- var type = getContextualType(arrayLiteral);
+ var type = getApparentTypeOfContextualType(arrayLiteral);
if (type) {
var index = ts.indexOf(arrayLiteral.elements, node);
return getTypeOfPropertyOfContextualType(type, "" + index)
@@ -16531,11 +16747,11 @@ var ts;
}
return undefined;
}
- function getContextualType(node) {
- var type = getContextualTypeWorker(node);
+ function getApparentTypeOfContextualType(node) {
+ var type = getContextualType(node);
return type && getApparentType(type);
}
- function getContextualTypeWorker(node) {
+ function getContextualType(node) {
if (isInsideWithStatementBody(node)) {
return undefined;
}
@@ -16601,7 +16817,7 @@ var ts;
ts.Debug.assert(node.kind !== 143 || ts.isObjectLiteralMethod(node));
var type = ts.isObjectLiteralMethod(node)
? getContextualTypeForObjectLiteralMethod(node)
- : getContextualType(node);
+ : getApparentTypeOfContextualType(node);
if (!type) {
return undefined;
}
@@ -16684,7 +16900,7 @@ var ts;
type.pattern = node;
return type;
}
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
var pattern = contextualType.pattern;
if (pattern && (pattern.kind === 162 || pattern.kind === 164)) {
@@ -16739,10 +16955,11 @@ var ts;
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
var propertiesTable = {};
var propertiesArray = [];
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
var contextualTypeHasPattern = contextualType && contextualType.pattern &&
(contextualType.pattern.kind === 161 || contextualType.pattern.kind === 165);
var typeFlags = 0;
+ var patternWithComputedProperties = false;
for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
var memberDecl = _a[_i];
var member = memberDecl.symbol;
@@ -16768,8 +16985,11 @@ var ts;
if (isOptional) {
prop.flags |= 536870912;
}
+ if (ts.hasDynamicName(memberDecl)) {
+ patternWithComputedProperties = true;
+ }
}
- else if (contextualTypeHasPattern) {
+ else if (contextualTypeHasPattern && !(contextualType.flags & 67108864)) {
var impliedProp = getPropertyOfType(contextualType, member.name);
if (impliedProp) {
prop.flags |= impliedProp.flags & 536870912;
@@ -16812,7 +17032,7 @@ var ts;
var numberIndexType = getIndexType(1);
var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576;
- result.flags |= 524288 | 4194304 | freshObjectLiteralFlag | (typeFlags & 14680064);
+ result.flags |= 524288 | 4194304 | freshObjectLiteralFlag | (typeFlags & 14680064) | (patternWithComputedProperties ? 67108864 : 0);
if (inDestructuringPattern) {
result.pattern = node;
}
@@ -18027,6 +18247,9 @@ var ts;
return anyType;
}
}
+ if (ts.isInJavaScriptFile(node) && ts.isRequireCall(node)) {
+ return resolveExternalModuleTypeByLiteral(node.arguments[0]);
+ }
return getReturnTypeOfSignature(signature);
}
function checkTaggedTemplateExpression(node) {
@@ -18037,7 +18260,9 @@ var ts;
var targetType = getTypeFromTypeNode(node.type);
if (produceDiagnostics && targetType !== unknownType) {
var widenedType = getWidenedType(exprType);
- if (!(isTypeAssignableTo(targetType, widenedType))) {
+ var bothAreStringLike = someConstituentTypeHasKind(targetType, 258) &&
+ someConstituentTypeHasKind(widenedType, 258);
+ if (!bothAreStringLike && !(isTypeAssignableTo(targetType, widenedType))) {
checkTypeAssignableTo(exprType, targetType, node, ts.Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
}
}
@@ -18476,17 +18701,24 @@ var ts;
var p = properties_3[_i];
if (p.kind === 245 || p.kind === 246) {
var name_13 = p.name;
+ if (name_13.kind === 136) {
+ checkComputedPropertyName(name_13);
+ }
+ if (isComputedNonLiteralName(name_13)) {
+ continue;
+ }
+ var text = getTextOfPropertyName(name_13);
var type = isTypeAny(sourceType)
? sourceType
- : getTypeOfPropertyOfType(sourceType, name_13.text) ||
- isNumericLiteralName(name_13.text) && getIndexTypeOfType(sourceType, 1) ||
+ : getTypeOfPropertyOfType(sourceType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(sourceType, 1) ||
getIndexTypeOfType(sourceType, 0);
if (type) {
if (p.kind === 246) {
checkDestructuringAssignment(p, type);
}
else {
- checkDestructuringAssignment(p.initializer || name_13, type);
+ checkDestructuringAssignment(p.initializer, type);
}
}
else {
@@ -18664,6 +18896,9 @@ var ts;
case 31:
case 32:
case 33:
+ if (someConstituentTypeHasKind(leftType, 258) && someConstituentTypeHasKind(rightType, 258)) {
+ return booleanType;
+ }
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
reportOperatorError();
}
@@ -18771,6 +19006,13 @@ var ts;
var type2 = checkExpression(node.whenFalse, contextualMapper);
return getUnionType([type1, type2]);
}
+ function checkStringLiteralExpression(node) {
+ var contextualType = getContextualType(node);
+ if (contextualType && contextualTypeIsStringLiteralType(contextualType)) {
+ return getStringLiteralType(node);
+ }
+ return stringType;
+ }
function checkTemplateExpression(node) {
ts.forEach(node.templateSpans, function (templateSpan) {
checkExpression(templateSpan.expression);
@@ -18809,7 +19051,7 @@ var ts;
if (isInferentialContext(contextualMapper)) {
var signature = getSingleCallSignature(type);
if (signature && signature.typeParameters) {
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
if (contextualType) {
var contextualSignature = getSingleCallSignature(contextualType);
if (contextualSignature && !contextualSignature.typeParameters) {
@@ -18861,6 +19103,7 @@ var ts;
case 183:
return checkTemplateExpression(node);
case 9:
+ return checkStringLiteralExpression(node);
case 11:
return stringType;
case 10:
@@ -19922,7 +20165,7 @@ var ts;
return;
}
var parent = getDeclarationContainer(node);
- if (parent.kind === 248 && ts.isExternalModule(parent)) {
+ if (parent.kind === 248 && ts.isExternalOrCommonJsModule(parent)) {
error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
}
}
@@ -19993,6 +20236,11 @@ var ts;
checkExpressionCached(node.initializer);
}
}
+ if (node.kind === 163) {
+ if (node.propertyName && node.propertyName.kind === 136) {
+ checkComputedPropertyName(node.propertyName);
+ }
+ }
if (ts.isBindingPattern(node.name)) {
ts.forEach(node.name.elements, checkSourceElement);
}
@@ -20351,6 +20599,7 @@ var ts;
var firstDefaultClause;
var hasDuplicateDefaultClause = false;
var expressionType = checkExpression(node.expression);
+ var expressionTypeIsStringLike = someConstituentTypeHasKind(expressionType, 258);
ts.forEach(node.caseBlock.clauses, function (clause) {
if (clause.kind === 242 && !hasDuplicateDefaultClause) {
if (firstDefaultClause === undefined) {
@@ -20367,6 +20616,9 @@ var ts;
if (produceDiagnostics && clause.kind === 241) {
var caseClause = clause;
var caseType = checkExpression(caseClause.expression);
+ if (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, 258)) {
+ return;
+ }
if (!isTypeAssignableTo(expressionType, caseType)) {
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, undefined);
}
@@ -20774,11 +21026,14 @@ var ts;
var enumIsConst = ts.isConst(node);
for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
var member = _a[_i];
- if (member.name.kind === 136) {
+ if (isComputedNonLiteralName(member.name)) {
error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
- else if (isNumericLiteralName(member.name.text)) {
- error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ else {
+ var text = getTextOfPropertyName(member.name);
+ if (isNumericLiteralName(text)) {
+ error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ }
}
var previousEnumMemberIsNonConstant = autoValue === undefined;
var initializer = member.initializer;
@@ -21476,8 +21731,10 @@ var ts;
function checkSourceFileWorker(node) {
var links = getNodeLinks(node);
if (!(links.flags & 1)) {
- if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) {
- return;
+ if (compilerOptions.skipDefaultLibCheck) {
+ if (node.hasNoDefaultLib) {
+ return;
+ }
}
checkGrammarSourceFile(node);
emitExtends = false;
@@ -21486,7 +21743,7 @@ var ts;
potentialThisCollisions.length = 0;
ts.forEach(node.statements, checkSourceElement);
checkFunctionAndClassExpressionBodies(node);
- if (ts.isExternalModule(node)) {
+ if (ts.isExternalOrCommonJsModule(node)) {
checkExternalModuleExports(node);
}
if (potentialThisCollisions.length) {
@@ -21564,7 +21821,7 @@ var ts;
}
switch (location.kind) {
case 248:
- if (!ts.isExternalModule(location)) {
+ if (!ts.isExternalOrCommonJsModule(location)) {
break;
}
case 218:
@@ -22123,15 +22380,24 @@ var ts;
getReferencedValueDeclaration: getReferencedValueDeclaration,
getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
isOptionalParameter: isOptionalParameter,
- isArgumentsLocalBinding: isArgumentsLocalBinding
+ isArgumentsLocalBinding: isArgumentsLocalBinding,
+ getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration
};
}
+ function getExternalModuleFileFromDeclaration(declaration) {
+ var specifier = ts.getExternalModuleName(declaration);
+ var moduleSymbol = getSymbolAtLocation(specifier);
+ if (!moduleSymbol) {
+ return undefined;
+ }
+ return ts.getDeclarationOfKind(moduleSymbol, 248);
+ }
function initializeTypeChecker() {
ts.forEach(host.getSourceFiles(), function (file) {
ts.bindSourceFile(file, compilerOptions);
});
ts.forEach(host.getSourceFiles(), function (file) {
- if (!ts.isExternalModule(file)) {
+ if (!ts.isExternalOrCommonJsModule(file)) {
mergeSymbolTable(globals, file.locals);
}
});
@@ -22808,7 +23074,7 @@ var ts;
}
}
function checkGrammarForNonSymbolComputedProperty(node, message) {
- if (node.kind === 136 && !ts.isWellKnownSymbolSyntactically(node.expression)) {
+ if (ts.isDynamicName(node)) {
return grammarErrorOnNode(node, message);
}
}
@@ -23122,11 +23388,15 @@ var ts;
var writeTextOfNode;
var writer = createAndSetNewTextWriterWithSymbolWriter();
var enclosingDeclaration;
- var currentSourceFile;
+ var currentText;
+ var currentLineMap;
+ var currentIdentifiers;
+ var isCurrentFileExternalModule;
var reportedDeclarationError = false;
var errorNameNode;
var emitJsDocComments = compilerOptions.removeComments ? function (declaration) { } : writeJsDocComments;
var emit = compilerOptions.stripInternal ? stripInternal : emitNode;
+ var noDeclare = !root;
var moduleElementDeclarationEmitInfo = [];
var asynchronousSubModuleDeclarationEmitInfo;
var referencePathsOutput = "";
@@ -23162,21 +23432,53 @@ var ts;
}
else {
var emittedReferencedFiles = [];
+ var prevModuleElementDeclarationEmitInfo = [];
ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
+ if (!ts.isDeclarationFile(sourceFile)) {
if (!compilerOptions.noResolve) {
ts.forEach(sourceFile.referencedFiles, function (fileReference) {
var referencedFile = ts.tryResolveScriptReference(host, sourceFile, fileReference);
- if (referencedFile && (ts.isExternalModuleOrDeclarationFile(referencedFile) &&
+ if (referencedFile && (ts.isDeclarationFile(referencedFile) &&
!ts.contains(emittedReferencedFiles, referencedFile))) {
writeReferencePath(referencedFile);
emittedReferencedFiles.push(referencedFile);
}
});
}
+ }
+ if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
+ noDeclare = false;
emitSourceFile(sourceFile);
}
+ else if (ts.isExternalModule(sourceFile)) {
+ noDeclare = true;
+ write("declare module \"" + ts.getResolvedExternalModuleName(host, sourceFile) + "\" {");
+ writeLine();
+ increaseIndent();
+ emitSourceFile(sourceFile);
+ decreaseIndent();
+ write("}");
+ writeLine();
+ if (moduleElementDeclarationEmitInfo.length) {
+ var oldWriter = writer;
+ ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) {
+ if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
+ ts.Debug.assert(aliasEmitInfo.node.kind === 222);
+ createAndSetNewTextWriterWithSymbolWriter();
+ ts.Debug.assert(aliasEmitInfo.indent === 1);
+ increaseIndent();
+ writeImportDeclaration(aliasEmitInfo.node);
+ aliasEmitInfo.asynchronousOutput = writer.getText();
+ decreaseIndent();
+ }
+ });
+ setWriter(oldWriter);
+ }
+ prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
+ moduleElementDeclarationEmitInfo = [];
+ }
});
+ moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo);
}
return {
reportedDeclarationError: reportedDeclarationError,
@@ -23185,13 +23487,12 @@ var ts;
referencePathsOutput: referencePathsOutput
};
function hasInternalAnnotation(range) {
- var text = currentSourceFile.text;
- var comment = text.substring(range.pos, range.end);
+ var comment = currentText.substring(range.pos, range.end);
return comment.indexOf("@internal") >= 0;
}
function stripInternal(node) {
if (node) {
- var leadingCommentRanges = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
+ var leadingCommentRanges = ts.getLeadingCommentRanges(currentText, node.pos);
if (ts.forEach(leadingCommentRanges, hasInternalAnnotation)) {
return;
}
@@ -23272,7 +23573,7 @@ var ts;
var errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
if (errorInfo) {
if (errorInfo.typeName) {
- diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
+ diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNodeFromSourceText(currentText, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
}
else {
diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
@@ -23336,9 +23637,9 @@ var ts;
}
function writeJsDocComments(declaration) {
if (declaration) {
- var jsDocComments = ts.getJsDocComments(declaration, currentSourceFile);
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, declaration, jsDocComments);
- ts.emitComments(currentSourceFile, writer, jsDocComments, true, newLine, ts.writeCommentRange);
+ var jsDocComments = ts.getJsDocCommentsFromText(declaration, currentText);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
+ ts.emitComments(currentText, currentLineMap, writer, jsDocComments, true, newLine, ts.writeCommentRange);
}
}
function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type, getSymbolAccessibilityDiagnostic) {
@@ -23355,7 +23656,7 @@ var ts;
case 103:
case 97:
case 9:
- return writeTextOfNode(currentSourceFile, type);
+ return writeTextOfNode(currentText, type);
case 188:
return emitExpressionWithTypeArguments(type);
case 151:
@@ -23386,14 +23687,14 @@ var ts;
}
function writeEntityName(entityName) {
if (entityName.kind === 69) {
- writeTextOfNode(currentSourceFile, entityName);
+ writeTextOfNode(currentText, entityName);
}
else {
var left = entityName.kind === 135 ? entityName.left : entityName.expression;
var right = entityName.kind === 135 ? entityName.right : entityName.name;
writeEntityName(left);
write(".");
- writeTextOfNode(currentSourceFile, right);
+ writeTextOfNode(currentText, right);
}
}
function emitEntityName(entityName) {
@@ -23421,7 +23722,7 @@ var ts;
}
}
function emitTypePredicate(type) {
- writeTextOfNode(currentSourceFile, type.parameterName);
+ writeTextOfNode(currentText, type.parameterName);
write(" is ");
emitType(type.type);
}
@@ -23461,20 +23762,23 @@ var ts;
}
}
function emitSourceFile(node) {
- currentSourceFile = node;
+ currentText = node.text;
+ currentLineMap = ts.getLineStarts(node);
+ currentIdentifiers = node.identifiers;
+ isCurrentFileExternalModule = ts.isExternalModule(node);
enclosingDeclaration = node;
- ts.emitDetachedComments(currentSourceFile, writer, ts.writeCommentRange, node, newLine, true);
+ ts.emitDetachedComments(currentText, currentLineMap, writer, ts.writeCommentRange, node, newLine, true);
emitLines(node.statements);
}
function getExportDefaultTempVariableName() {
var baseName = "_default";
- if (!ts.hasProperty(currentSourceFile.identifiers, baseName)) {
+ if (!ts.hasProperty(currentIdentifiers, baseName)) {
return baseName;
}
var count = 0;
while (true) {
var name_18 = baseName + "_" + (++count);
- if (!ts.hasProperty(currentSourceFile.identifiers, name_18)) {
+ if (!ts.hasProperty(currentIdentifiers, name_18)) {
return name_18;
}
}
@@ -23482,7 +23786,7 @@ var ts;
function emitExportAssignment(node) {
if (node.expression.kind === 69) {
write(node.isExportEquals ? "export = " : "export default ");
- writeTextOfNode(currentSourceFile, node.expression);
+ writeTextOfNode(currentText, node.expression);
}
else {
var tempVarName = getExportDefaultTempVariableName();
@@ -23517,7 +23821,7 @@ var ts;
writeModuleElement(node);
}
else if (node.kind === 221 ||
- (node.parent.kind === 248 && ts.isExternalModule(currentSourceFile))) {
+ (node.parent.kind === 248 && isCurrentFileExternalModule)) {
var isVisible;
if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== 248) {
asynchronousSubModuleDeclarationEmitInfo.push({
@@ -23569,14 +23873,14 @@ var ts;
}
}
function emitModuleElementDeclarationFlags(node) {
- if (node.parent === currentSourceFile) {
+ if (node.parent.kind === 248) {
if (node.flags & 2) {
write("export ");
}
if (node.flags & 512) {
write("default ");
}
- else if (node.kind !== 215) {
+ else if (node.kind !== 215 && !noDeclare) {
write("declare ");
}
}
@@ -23601,7 +23905,7 @@ var ts;
write("export ");
}
write("import ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
write(" = ");
if (ts.isInternalModuleImportEqualsDeclaration(node)) {
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError);
@@ -23609,7 +23913,7 @@ var ts;
}
else {
write("require(");
- writeTextOfNode(currentSourceFile, ts.getExternalModuleImportEqualsDeclarationExpression(node));
+ writeTextOfNode(currentText, ts.getExternalModuleImportEqualsDeclarationExpression(node));
write(");");
}
writer.writeLine();
@@ -23643,7 +23947,7 @@ var ts;
if (node.importClause) {
var currentWriterPos = writer.getTextPos();
if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
- writeTextOfNode(currentSourceFile, node.importClause.name);
+ writeTextOfNode(currentText, node.importClause.name);
}
if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
if (currentWriterPos !== writer.getTextPos()) {
@@ -23651,7 +23955,7 @@ var ts;
}
if (node.importClause.namedBindings.kind === 224) {
write("* as ");
- writeTextOfNode(currentSourceFile, node.importClause.namedBindings.name);
+ writeTextOfNode(currentText, node.importClause.namedBindings.name);
}
else {
write("{ ");
@@ -23661,16 +23965,28 @@ var ts;
}
write(" from ");
}
- writeTextOfNode(currentSourceFile, node.moduleSpecifier);
+ emitExternalModuleSpecifier(node.moduleSpecifier);
write(";");
writer.writeLine();
}
+ function emitExternalModuleSpecifier(moduleSpecifier) {
+ if (moduleSpecifier.kind === 9 && (!root) && (compilerOptions.out || compilerOptions.outFile)) {
+ var moduleName = ts.getExternalModuleNameFromDeclaration(host, resolver, moduleSpecifier.parent);
+ if (moduleName) {
+ write("\"");
+ write(moduleName);
+ write("\"");
+ return;
+ }
+ }
+ writeTextOfNode(currentText, moduleSpecifier);
+ }
function emitImportOrExportSpecifier(node) {
if (node.propertyName) {
- writeTextOfNode(currentSourceFile, node.propertyName);
+ writeTextOfNode(currentText, node.propertyName);
write(" as ");
}
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
function emitExportSpecifier(node) {
emitImportOrExportSpecifier(node);
@@ -23690,7 +24006,7 @@ var ts;
}
if (node.moduleSpecifier) {
write(" from ");
- writeTextOfNode(currentSourceFile, node.moduleSpecifier);
+ emitExternalModuleSpecifier(node.moduleSpecifier);
}
write(";");
writer.writeLine();
@@ -23704,11 +24020,11 @@ var ts;
else {
write("module ");
}
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
while (node.body.kind !== 219) {
node = node.body;
write(".");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
@@ -23727,7 +24043,7 @@ var ts;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("type ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
emitTypeParameters(node.typeParameters);
write(" = ");
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
@@ -23749,7 +24065,7 @@ var ts;
write("const ");
}
write("enum ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
write(" {");
writeLine();
increaseIndent();
@@ -23760,7 +24076,7 @@ var ts;
}
function emitEnumMemberDeclaration(node) {
emitJsDocComments(node);
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var enumMemberValue = resolver.getConstantValue(node);
if (enumMemberValue !== undefined) {
write(" = ");
@@ -23777,7 +24093,7 @@ var ts;
increaseIndent();
emitJsDocComments(node);
decreaseIndent();
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (node.constraint && !isPrivateMethodTypeParameter(node)) {
write(" extends ");
if (node.parent.kind === 152 ||
@@ -23887,7 +24203,7 @@ var ts;
write("abstract ");
}
write("class ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitTypeParameters(node.typeParameters);
@@ -23910,7 +24226,7 @@ var ts;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("interface ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitTypeParameters(node.typeParameters);
@@ -23940,7 +24256,7 @@ var ts;
emitBindingPattern(node.name);
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if ((node.kind === 141 || node.kind === 140) && ts.hasQuestionToken(node)) {
write("?");
}
@@ -24014,7 +24330,7 @@ var ts;
emitBindingPattern(bindingElement.name);
}
else {
- writeTextOfNode(currentSourceFile, bindingElement.name);
+ writeTextOfNode(currentText, bindingElement.name);
writeTypeOfDeclaration(bindingElement, undefined, getBindingElementTypeVisibilityError);
}
}
@@ -24055,7 +24371,7 @@ var ts;
emitJsDocComments(accessors.getAccessor);
emitJsDocComments(accessors.setAccessor);
emitClassMemberDeclarationFlags(node);
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (!(node.flags & 16)) {
accessorWithTypeAnnotation = node;
var type = getTypeAnnotationFromAccessor(node);
@@ -24136,13 +24452,13 @@ var ts;
}
if (node.kind === 213) {
write("function ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
else if (node.kind === 144) {
write("constructor");
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (ts.hasQuestionToken(node)) {
write("?");
}
@@ -24255,7 +24571,7 @@ var ts;
emitBindingPattern(node.name);
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
if (resolver.isOptionalParameter(node)) {
write("?");
@@ -24354,7 +24670,7 @@ var ts;
}
else if (bindingElement.kind === 163) {
if (bindingElement.propertyName) {
- writeTextOfNode(currentSourceFile, bindingElement.propertyName);
+ writeTextOfNode(currentText, bindingElement.propertyName);
write(": ");
}
if (bindingElement.name) {
@@ -24366,7 +24682,7 @@ var ts;
if (bindingElement.dotDotDotToken) {
write("...");
}
- writeTextOfNode(currentSourceFile, bindingElement.name);
+ writeTextOfNode(currentText, bindingElement.name);
}
}
}
@@ -24449,6 +24765,18 @@ var ts;
return ts.isExternalModule(sourceFile) || ts.isDeclarationFile(sourceFile);
}
ts.isExternalModuleOrDeclarationFile = isExternalModuleOrDeclarationFile;
+ function getResolvedExternalModuleName(host, file) {
+ return file.moduleName || ts.getExternalModuleNameFromPath(host, file.fileName);
+ }
+ ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
+ function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
+ var file = resolver.getExternalModuleFileFromDeclaration(declaration);
+ if (!file || ts.isDeclarationFile(file)) {
+ return undefined;
+ }
+ return getResolvedExternalModuleName(host, file);
+ }
+ ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
var entities = {
"quot": 0x0022,
"amp": 0x0026,
@@ -24718,15 +25046,19 @@ var ts;
var newLine = host.getNewLine();
var jsxDesugaring = host.getCompilerOptions().jsx !== 1;
var shouldEmitJsx = function (s) { return (s.languageVariant === 1 && !jsxDesugaring); };
+ var outFile = compilerOptions.outFile || compilerOptions.out;
+ var emitJavaScript = createFileEmitter();
if (targetSourceFile === undefined) {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
- var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
- emitFile(jsFilePath, sourceFile);
- }
- });
- if (compilerOptions.outFile || compilerOptions.out) {
- emitFile(compilerOptions.outFile || compilerOptions.out);
+ if (outFile) {
+ emitFile(outFile);
+ }
+ else {
+ ts.forEach(host.getSourceFiles(), function (sourceFile) {
+ if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
+ var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
+ emitFile(jsFilePath, sourceFile);
+ }
+ });
}
}
else {
@@ -24734,8 +25066,8 @@ var ts;
var jsFilePath = ts.getOwnEmitOutputFilePath(targetSourceFile, host, shouldEmitJsx(targetSourceFile) ? ".jsx" : ".js");
emitFile(jsFilePath, targetSourceFile);
}
- else if (!ts.isDeclarationFile(targetSourceFile) && (compilerOptions.outFile || compilerOptions.out)) {
- emitFile(compilerOptions.outFile || compilerOptions.out);
+ else if (!ts.isDeclarationFile(targetSourceFile) && outFile) {
+ emitFile(outFile);
}
}
diagnostics = ts.sortAndDeduplicateDiagnostics(diagnostics);
@@ -24785,20 +25117,26 @@ var ts;
}
}
}
- function emitJavaScript(jsFilePath, root) {
+ function createFileEmitter() {
var writer = ts.createTextWriter(newLine);
var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent;
var currentSourceFile;
+ var currentText;
+ var currentLineMap;
+ var currentFileIdentifiers;
+ var renamedDependencies;
+ var isEs6Module;
+ var isCurrentFileExternalModule;
var exportFunctionForFile;
- var generatedNameSet = {};
- var nodeToGeneratedName = [];
+ var generatedNameSet;
+ var nodeToGeneratedName;
var computedPropertyNamesToGeneratedNames;
var convertedLoopState;
- var extendsEmitted = false;
- var decorateEmitted = false;
- var paramEmitted = false;
- var awaiterEmitted = false;
- var tempFlags = 0;
+ var extendsEmitted;
+ var decorateEmitted;
+ var paramEmitted;
+ var awaiterEmitted;
+ var tempFlags;
var tempVariables;
var tempParameters;
var externalImports;
@@ -24815,6 +25153,7 @@ var ts;
var scopeEmitStart = function (scopeDeclaration, scopeName) { };
var scopeEmitEnd = function () { };
var sourceMapData;
+ var root;
var emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos) { } : emitLeadingCommentsOfPositionWorker;
var moduleEmitDelegates = (_a = {},
_a[5] = emitES6Module,
@@ -24824,30 +25163,75 @@ var ts;
_a[1] = emitCommonJSModule,
_a
);
- if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
- initializeEmitterWithSourceMaps();
- }
- if (root) {
- emitSourceFile(root);
- }
- else {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!isExternalModuleOrDeclarationFile(sourceFile)) {
- emitSourceFile(sourceFile);
+ var bundleEmitDelegates = (_b = {},
+ _b[5] = function () { },
+ _b[2] = emitAMDModule,
+ _b[4] = emitSystemModule,
+ _b[3] = function () { },
+ _b[1] = function () { },
+ _b
+ );
+ return doEmit;
+ function doEmit(jsFilePath, rootFile) {
+ writer.reset();
+ currentSourceFile = undefined;
+ currentText = undefined;
+ currentLineMap = undefined;
+ exportFunctionForFile = undefined;
+ generatedNameSet = {};
+ nodeToGeneratedName = [];
+ computedPropertyNamesToGeneratedNames = undefined;
+ convertedLoopState = undefined;
+ extendsEmitted = false;
+ decorateEmitted = false;
+ paramEmitted = false;
+ awaiterEmitted = false;
+ tempFlags = 0;
+ tempVariables = undefined;
+ tempParameters = undefined;
+ externalImports = undefined;
+ exportSpecifiers = undefined;
+ exportEquals = undefined;
+ hasExportStars = undefined;
+ detachedCommentsInfo = undefined;
+ sourceMapData = undefined;
+ isEs6Module = false;
+ renamedDependencies = undefined;
+ isCurrentFileExternalModule = false;
+ root = rootFile;
+ if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
+ initializeEmitterWithSourceMaps(jsFilePath, root);
+ }
+ if (root) {
+ emitSourceFile(root);
+ }
+ else {
+ if (modulekind) {
+ ts.forEach(host.getSourceFiles(), emitEmitHelpers);
}
- });
+ ts.forEach(host.getSourceFiles(), function (sourceFile) {
+ if ((!isExternalModuleOrDeclarationFile(sourceFile)) || (modulekind && ts.isExternalModule(sourceFile))) {
+ emitSourceFile(sourceFile);
+ }
+ });
+ }
+ writeLine();
+ writeEmittedFiles(writer.getText(), jsFilePath, compilerOptions.emitBOM);
}
- writeLine();
- writeEmittedFiles(writer.getText(), compilerOptions.emitBOM);
- return;
function emitSourceFile(sourceFile) {
currentSourceFile = sourceFile;
+ currentText = sourceFile.text;
+ currentLineMap = ts.getLineStarts(sourceFile);
exportFunctionForFile = undefined;
+ isEs6Module = sourceFile.symbol && sourceFile.symbol.exports && !!sourceFile.symbol.exports["___esModule"];
+ renamedDependencies = sourceFile.renamedDependencies;
+ currentFileIdentifiers = sourceFile.identifiers;
+ isCurrentFileExternalModule = ts.isExternalModule(sourceFile);
emit(sourceFile);
}
function isUniqueName(name) {
return !resolver.hasGlobalName(name) &&
- !ts.hasProperty(currentSourceFile.identifiers, name) &&
+ !ts.hasProperty(currentFileIdentifiers, name) &&
!ts.hasProperty(generatedNameSet, name);
}
function makeTempVariableName(flags) {
@@ -24920,7 +25304,7 @@ var ts;
var id = ts.getNodeId(node);
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = ts.unescapeIdentifier(generateNameForNode(node)));
}
- function initializeEmitterWithSourceMaps() {
+ function initializeEmitterWithSourceMaps(jsFilePath, root) {
var sourceMapDir;
var sourceMapSourceIndex = -1;
var sourceMapNameIndexMap = {};
@@ -24989,7 +25373,7 @@ var ts;
}
}
function recordSourceMapSpan(pos) {
- var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSourceFile, pos);
+ var sourceLinePos = ts.computeLineAndCharacterOfPosition(currentLineMap, pos);
sourceLinePos.line++;
sourceLinePos.character++;
var emittedLine = writer.getLine();
@@ -25017,13 +25401,13 @@ var ts;
}
}
function recordEmitNodeStartSpan(node) {
- recordSourceMapSpan(ts.skipTrivia(currentSourceFile.text, node.pos));
+ recordSourceMapSpan(ts.skipTrivia(currentText, node.pos));
}
function recordEmitNodeEndSpan(node) {
recordSourceMapSpan(node.end);
}
function writeTextWithSpanRecord(tokenKind, startPos, emitFn) {
- var tokenStartPos = ts.skipTrivia(currentSourceFile.text, startPos);
+ var tokenStartPos = ts.skipTrivia(currentText, startPos);
recordSourceMapSpan(tokenStartPos);
var tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
recordSourceMapSpan(tokenEndPos);
@@ -25093,9 +25477,9 @@ var ts;
sourceMapNameIndices.pop();
}
;
- function writeCommentRangeWithMap(curentSourceFile, writer, comment, newLine) {
+ function writeCommentRangeWithMap(currentText, currentLineMap, writer, comment, newLine) {
recordSourceMapSpan(comment.pos);
- ts.writeCommentRange(currentSourceFile, writer, comment, newLine);
+ ts.writeCommentRange(currentText, currentLineMap, writer, comment, newLine);
recordSourceMapSpan(comment.end);
}
function serializeSourceMapContents(version, file, sourceRoot, sources, names, mappings, sourcesContent) {
@@ -25125,7 +25509,7 @@ var ts;
return output;
}
}
- function writeJavaScriptAndSourceMapFile(emitOutput, writeByteOrderMark) {
+ function writeJavaScriptAndSourceMapFile(emitOutput, jsFilePath, writeByteOrderMark) {
encodeLastRecordedSourceMapSpan();
var sourceMapText = serializeSourceMapContents(3, sourceMapData.sourceMapFile, sourceMapData.sourceMapSourceRoot, sourceMapData.sourceMapSources, sourceMapData.sourceMapNames, sourceMapData.sourceMapMappings, sourceMapData.sourceMapSourcesContent);
sourceMapDataList.push(sourceMapData);
@@ -25138,7 +25522,7 @@ var ts;
ts.writeFile(host, diagnostics, sourceMapData.sourceMapFilePath, sourceMapText, false);
sourceMapUrl = "//# sourceMappingURL=" + sourceMapData.jsSourceMappingURL;
}
- writeJavaScriptFile(emitOutput + sourceMapUrl, writeByteOrderMark);
+ writeJavaScriptFile(emitOutput + sourceMapUrl, jsFilePath, writeByteOrderMark);
}
var sourceMapJsFile = ts.getBaseFileName(ts.normalizeSlashes(jsFilePath));
sourceMapData = {
@@ -25201,7 +25585,7 @@ var ts;
scopeEmitEnd = recordScopeNameEnd;
writeComment = writeCommentRangeWithMap;
}
- function writeJavaScriptFile(emitOutput, writeByteOrderMark) {
+ function writeJavaScriptFile(emitOutput, jsFilePath, writeByteOrderMark) {
ts.writeFile(host, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
}
function createTempVariable(flags) {
@@ -25371,7 +25755,7 @@ var ts;
return getQuotedEscapedLiteralText("\"", node.text, "\"");
}
if (node.parent) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+ return ts.getTextOfNodeFromSourceText(currentText, node);
}
switch (node.kind) {
case 9:
@@ -25393,7 +25777,7 @@ var ts;
return leftQuote + ts.escapeNonAsciiCharacters(ts.escapeString(text)) + rightQuote;
}
function emitDownlevelRawTemplateLiteral(node) {
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+ var text = ts.getTextOfNodeFromSourceText(currentText, node);
var isLast = node.kind === 11 || node.kind === 14;
text = text.substring(1, text.length - (isLast ? 1 : 2));
text = text.replace(/\r\n?/g, "\n");
@@ -25723,7 +26107,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
write("\"");
}
@@ -25819,7 +26203,7 @@ var ts;
else if (declaration.kind === 226) {
write(getGeneratedNameForNode(declaration.parent.parent.parent));
var name_23 = declaration.propertyName || declaration.name;
- var identifier = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, name_23);
+ var identifier = ts.getTextOfNodeFromSourceText(currentText, name_23);
if (languageVersion === 0 && identifier === "default") {
write("[\"default\"]");
}
@@ -25843,7 +26227,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
}
function isNameOfNestedRedeclaration(node) {
@@ -25880,7 +26264,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
}
function emitThis(node) {
@@ -26247,8 +26631,8 @@ var ts;
return container && container.kind !== 248;
}
function emitShorthandPropertyAssignment(node) {
- writeTextOfNode(currentSourceFile, node.name);
- if (languageVersion < 2 || isNamespaceExportReference(node.name)) {
+ writeTextOfNode(currentText, node.name);
+ if (modulekind !== 5 || isNamespaceExportReference(node.name)) {
write(": ");
emit(node.name);
}
@@ -26298,10 +26682,10 @@ var ts;
}
emit(node.expression);
var indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken);
- var shouldEmitSpace;
+ var shouldEmitSpace = false;
if (!indentedBeforeDot) {
if (node.expression.kind === 8) {
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node.expression);
+ var text = ts.getTextOfNodeFromSourceText(currentText, node.expression);
shouldEmitSpace = text.indexOf(ts.tokenToString(21)) < 0;
}
else {
@@ -27307,16 +27691,16 @@ var ts;
emitToken(16, node.clauses.end);
}
function nodeStartPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node1.pos)) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node1.pos)) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
}
function nodeEndPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, node2.end);
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, node2.end);
}
function nodeEndIsOnSameLineAsNodeStart(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
}
function emitCaseOrDefaultClause(node) {
if (node.kind === 241) {
@@ -27421,7 +27805,7 @@ var ts;
if (node.parent.kind === 248) {
ts.Debug.assert(!!(node.flags & 512) || node.kind === 227);
if (modulekind === 1 || modulekind === 2 || modulekind === 3) {
- if (!currentSourceFile.symbol.exports["___esModule"]) {
+ if (!isEs6Module) {
if (languageVersion === 1) {
write("Object.defineProperty(exports, \"__esModule\", { value: true });");
writeLine();
@@ -27584,12 +27968,18 @@ var ts;
return node;
}
function createPropertyAccessForDestructuringProperty(object, propName) {
- var syntheticName = ts.createSynthesizedNode(propName.kind);
- syntheticName.text = propName.text;
- if (syntheticName.kind !== 69) {
- return createElementAccessExpression(object, syntheticName);
+ var index;
+ var nameIsComputed = propName.kind === 136;
+ if (nameIsComputed) {
+ index = ensureIdentifier(propName.expression, false);
+ }
+ else {
+ index = ts.createSynthesizedNode(propName.kind);
+ index.text = propName.text;
}
- return createPropertyAccessExpression(object, syntheticName);
+ return !nameIsComputed && index.kind === 69
+ ? createPropertyAccessExpression(object, index)
+ : createElementAccessExpression(object, index);
}
function createSliceCall(value, sliceIndex) {
var call = ts.createSynthesizedNode(168);
@@ -28003,7 +28393,6 @@ var ts;
var promiseConstructor = ts.getEntityNameFromTypeNode(node.type);
var isArrowFunction = node.kind === 174;
var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 4096) !== 0;
- var args;
if (!isArrowFunction) {
write(" {");
increaseIndent();
@@ -29177,8 +29566,8 @@ var ts;
}
}
function tryRenameExternalModule(moduleName) {
- if (currentSourceFile.renamedDependencies && ts.hasProperty(currentSourceFile.renamedDependencies, moduleName.text)) {
- return "\"" + currentSourceFile.renamedDependencies[moduleName.text] + "\"";
+ if (renamedDependencies && ts.hasProperty(renamedDependencies, moduleName.text)) {
+ return "\"" + renamedDependencies[moduleName.text] + "\"";
}
return undefined;
}
@@ -29318,7 +29707,7 @@ var ts;
return;
}
if (resolver.isReferencedAliasDeclaration(node) ||
- (!ts.isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
+ (!isCurrentFileExternalModule && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
emitLeadingComments(node);
emitStart(node);
var variableDeclarationIsHoisted = shouldHoistVariable(node, true);
@@ -29530,7 +29919,7 @@ var ts;
function getLocalNameForExternalImport(node) {
var namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, namespaceDeclaration.name);
+ return ts.getTextOfNodeFromSourceText(currentText, namespaceDeclaration.name);
}
if (node.kind === 222 && node.importClause) {
return getGeneratedNameForNode(node);
@@ -29803,7 +30192,7 @@ var ts;
ts.getEnclosingBlockScopeContainer(node).kind === 248;
}
function isCurrentFileSystemExternalModule() {
- return modulekind === 4 && ts.isExternalModule(currentSourceFile);
+ return modulekind === 4 && isCurrentFileExternalModule;
}
function emitSystemModuleBody(node, dependencyGroups, startIndex) {
emitVariableDeclarationsForImports();
@@ -29916,15 +30305,19 @@ var ts;
writeLine();
write("}");
}
- function emitSystemModule(node) {
+ function writeModuleName(node, emitRelativePathAsModuleName) {
+ var moduleName = node.moduleName;
+ if (moduleName || (emitRelativePathAsModuleName && (moduleName = getResolvedExternalModuleName(host, node)))) {
+ write("\"" + moduleName + "\", ");
+ }
+ }
+ function emitSystemModule(node, emitRelativePathAsModuleName) {
collectExternalModuleInfo(node);
ts.Debug.assert(!exportFunctionForFile);
exportFunctionForFile = makeUniqueName("exports");
writeLine();
write("System.register(");
- if (node.moduleName) {
- write("\"" + node.moduleName + "\", ");
- }
+ writeModuleName(node, emitRelativePathAsModuleName);
write("[");
var groupIndices = {};
var dependencyGroups = [];
@@ -29942,6 +30335,12 @@ var ts;
if (i !== 0) {
write(", ");
}
+ if (emitRelativePathAsModuleName) {
+ var name_29 = getExternalModuleNameFromDeclaration(host, resolver, externalImports[i]);
+ if (name_29) {
+ text = "\"" + name_29 + "\"";
+ }
+ }
write(text);
}
write("], function(" + exportFunctionForFile + ") {");
@@ -29955,7 +30354,7 @@ var ts;
writeLine();
write("});");
}
- function getAMDDependencyNames(node, includeNonAmdDependencies) {
+ function getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
var aliasedModuleNames = [];
var unaliasedModuleNames = [];
var importAliasNames = [];
@@ -29972,6 +30371,12 @@ var ts;
for (var _c = 0, externalImports_4 = externalImports; _c < externalImports_4.length; _c++) {
var importNode = externalImports_4[_c];
var externalModuleName = getExternalModuleNameText(importNode);
+ if (emitRelativePathAsModuleName) {
+ var name_30 = getExternalModuleNameFromDeclaration(host, resolver, importNode);
+ if (name_30) {
+ externalModuleName = "\"" + name_30 + "\"";
+ }
+ }
var importAliasName = getLocalNameForExternalImport(importNode);
if (includeNonAmdDependencies && importAliasName) {
aliasedModuleNames.push(externalModuleName);
@@ -29983,8 +30388,8 @@ var ts;
}
return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
}
- function emitAMDDependencies(node, includeNonAmdDependencies) {
- var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies);
+ function emitAMDDependencies(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
+ var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName);
emitAMDDependencyList(dependencyNames);
write(", ");
emitAMDFactoryHeader(dependencyNames);
@@ -30011,15 +30416,13 @@ var ts;
}
write(") {");
}
- function emitAMDModule(node) {
+ function emitAMDModule(node, emitRelativePathAsModuleName) {
emitEmitHelpers(node);
collectExternalModuleInfo(node);
writeLine();
write("define(");
- if (node.moduleName) {
- write("\"" + node.moduleName + "\", ");
- }
- emitAMDDependencies(node, true);
+ writeModuleName(node, emitRelativePathAsModuleName);
+ emitAMDDependencies(node, true, emitRelativePathAsModuleName);
increaseIndent();
var startIndex = emitDirectivePrologues(node.statements, true);
emitExportStarHelper();
@@ -30225,8 +30628,13 @@ var ts;
emitShebang();
emitDetachedCommentsAndUpdateCommentsInfo(node);
if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
- var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[1];
- emitModule(node);
+ if (root || (!ts.isExternalModule(node) && compilerOptions.isolatedModules)) {
+ var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[1];
+ emitModule(node);
+ }
+ else {
+ bundleEmitDelegates[modulekind](node, true);
+ }
}
else {
var startIndex = emitDirectivePrologues(node.statements, false);
@@ -30470,7 +30878,7 @@ var ts;
return detachedCommentsInfo !== undefined && ts.lastOrUndefined(detachedCommentsInfo).nodePos === pos;
}
function getLeadingCommentsWithoutDetachedComments() {
- var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
+ var leadingComments = ts.getLeadingCommentRanges(currentText, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
if (detachedCommentsInfo.length - 1) {
detachedCommentsInfo.pop();
}
@@ -30480,10 +30888,10 @@ var ts;
return leadingComments;
}
function isTripleSlashComment(comment) {
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 47 &&
+ if (currentText.charCodeAt(comment.pos + 1) === 47 &&
comment.pos + 2 < comment.end &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 47) {
- var textSubStr = currentSourceFile.text.substring(comment.pos, comment.end);
+ currentText.charCodeAt(comment.pos + 2) === 47) {
+ var textSubStr = currentText.substring(comment.pos, comment.end);
return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ?
true : false;
@@ -30497,7 +30905,7 @@ var ts;
return getLeadingCommentsWithoutDetachedComments();
}
else {
- return ts.getLeadingCommentRangesOfNode(node, currentSourceFile);
+ return ts.getLeadingCommentRangesOfNodeFromText(node, currentText);
}
}
}
@@ -30505,7 +30913,7 @@ var ts;
function getTrailingCommentsToEmit(node) {
if (node.parent) {
if (node.parent.kind === 248 || node.end !== node.parent.end) {
- return ts.getTrailingCommentRanges(currentSourceFile.text, node.end);
+ return ts.getTrailingCommentRanges(currentText, node.end);
}
}
}
@@ -30528,22 +30936,22 @@ var ts;
leadingComments = ts.filter(getLeadingCommentsToEmit(node), isTripleSlashComment);
}
}
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
- ts.emitComments(currentSourceFile, writer, leadingComments, true, newLine, writeComment);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments);
+ ts.emitComments(currentText, currentLineMap, writer, leadingComments, true, newLine, writeComment);
}
function emitTrailingComments(node) {
if (compilerOptions.removeComments) {
return;
}
var trailingComments = getTrailingCommentsToEmit(node);
- ts.emitComments(currentSourceFile, writer, trailingComments, false, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, trailingComments, false, newLine, writeComment);
}
function emitTrailingCommentsOfPosition(pos) {
if (compilerOptions.removeComments) {
return;
}
- var trailingComments = ts.getTrailingCommentRanges(currentSourceFile.text, pos);
- ts.emitComments(currentSourceFile, writer, trailingComments, true, newLine, writeComment);
+ var trailingComments = ts.getTrailingCommentRanges(currentText, pos);
+ ts.emitComments(currentText, currentLineMap, writer, trailingComments, true, newLine, writeComment);
}
function emitLeadingCommentsOfPositionWorker(pos) {
if (compilerOptions.removeComments) {
@@ -30554,13 +30962,13 @@ var ts;
leadingComments = getLeadingCommentsWithoutDetachedComments();
}
else {
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, pos);
+ leadingComments = ts.getLeadingCommentRanges(currentText, pos);
}
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, { pos: pos, end: pos }, leadingComments);
- ts.emitComments(currentSourceFile, writer, leadingComments, true, newLine, writeComment);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments);
+ ts.emitComments(currentText, currentLineMap, writer, leadingComments, true, newLine, writeComment);
}
function emitDetachedCommentsAndUpdateCommentsInfo(node) {
- var currentDetachedCommentInfo = ts.emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, compilerOptions.removeComments);
+ var currentDetachedCommentInfo = ts.emitDetachedComments(currentText, currentLineMap, writer, writeComment, node, newLine, compilerOptions.removeComments);
if (currentDetachedCommentInfo) {
if (detachedCommentsInfo) {
detachedCommentsInfo.push(currentDetachedCommentInfo);
@@ -30571,12 +30979,12 @@ var ts;
}
}
function emitShebang() {
- var shebang = ts.getShebang(currentSourceFile.text);
+ var shebang = ts.getShebang(currentText);
if (shebang) {
write(shebang);
}
}
- var _a;
+ var _a, _b;
}
function emitFile(jsFilePath, sourceFile) {
emitJavaScript(jsFilePath, sourceFile);
@@ -30632,11 +31040,11 @@ var ts;
if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
var failedLookupLocations = [];
var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
- var resolvedFileName = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ var resolvedFileName = loadNodeModuleFromFile(ts.supportedJsExtensions, candidate, failedLookupLocations, host);
if (resolvedFileName) {
return { resolvedModule: { resolvedFileName: resolvedFileName }, failedLookupLocations: failedLookupLocations };
}
- resolvedFileName = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ resolvedFileName = loadNodeModuleFromDirectory(ts.supportedJsExtensions, candidate, failedLookupLocations, host);
return resolvedFileName
? { resolvedModule: { resolvedFileName: resolvedFileName }, failedLookupLocations: failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations: failedLookupLocations };
@@ -30646,8 +31054,8 @@ var ts;
}
}
ts.nodeModuleNameResolver = nodeModuleNameResolver;
- function loadNodeModuleFromFile(candidate, failedLookupLocation, host) {
- return ts.forEach(ts.moduleFileExtensions, tryLoad);
+ function loadNodeModuleFromFile(extensions, candidate, failedLookupLocation, host) {
+ return ts.forEach(extensions, tryLoad);
function tryLoad(ext) {
var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
if (host.fileExists(fileName)) {
@@ -30659,7 +31067,7 @@ var ts;
}
}
}
- function loadNodeModuleFromDirectory(candidate, failedLookupLocation, host) {
+ function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, host) {
var packageJsonPath = ts.combinePaths(candidate, "package.json");
if (host.fileExists(packageJsonPath)) {
var jsonContent;
@@ -30671,7 +31079,7 @@ var ts;
jsonContent = { typings: undefined };
}
if (jsonContent.typings) {
- var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
+ var result = loadNodeModuleFromFile(extensions, ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
if (result) {
return result;
}
@@ -30680,7 +31088,7 @@ var ts;
else {
failedLookupLocation.push(packageJsonPath);
}
- return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), failedLookupLocation, host);
+ return loadNodeModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocation, host);
}
function loadModuleFromNodeModules(moduleName, directory, host) {
var failedLookupLocations = [];
@@ -30690,11 +31098,11 @@ var ts;
if (baseName !== "node_modules") {
var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName));
- var result = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ var result = loadNodeModuleFromFile(ts.supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations: failedLookupLocations };
}
- result = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ result = loadNodeModuleFromDirectory(ts.supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations: failedLookupLocations };
}
@@ -30719,9 +31127,10 @@ var ts;
var searchName;
var failedLookupLocations = [];
var referencedSourceFile;
+ var extensions = compilerOptions.allowNonTsExtensions ? ts.supportedJsExtensions : ts.supportedExtensions;
while (true) {
searchName = ts.normalizePath(ts.combinePaths(searchPath, moduleName));
- referencedSourceFile = ts.forEach(ts.supportedExtensions, function (extension) {
+ referencedSourceFile = ts.forEach(extensions, function (extension) {
if (extension === ".tsx" && !compilerOptions.jsx) {
return undefined;
}
@@ -30749,10 +31158,8 @@ var ts;
ts.classicNameResolver = classicNameResolver;
ts.defaultInitCompilerOptions = {
module: 1,
- target: 0,
+ target: 1,
noImplicitAny: false,
- outDir: "built",
- rootDir: ".",
sourceMap: false
};
function createCompilerHost(options, setParentNodes) {
@@ -31110,35 +31517,47 @@ var ts;
if (file.imports) {
return;
}
+ var isJavaScriptFile = ts.isSourceFileJavaScript(file);
var imports;
for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
var node = _a[_i];
- collect(node, true);
+ collect(node, true, false);
}
file.imports = imports || emptyArray;
- function collect(node, allowRelativeModuleNames) {
- switch (node.kind) {
- case 222:
- case 221:
- case 228:
- var moduleNameExpr = ts.getExternalModuleName(node);
- if (!moduleNameExpr || moduleNameExpr.kind !== 9) {
+ return;
+ function collect(node, allowRelativeModuleNames, collectOnlyRequireCalls) {
+ if (!collectOnlyRequireCalls) {
+ switch (node.kind) {
+ case 222:
+ case 221:
+ case 228:
+ var moduleNameExpr = ts.getExternalModuleName(node);
+ if (!moduleNameExpr || moduleNameExpr.kind !== 9) {
+ break;
+ }
+ if (!moduleNameExpr.text) {
+ break;
+ }
+ if (allowRelativeModuleNames || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
+ (imports || (imports = [])).push(moduleNameExpr);
+ }
break;
- }
- if (!moduleNameExpr.text) {
+ case 218:
+ if (node.name.kind === 9 && (node.flags & 4 || ts.isDeclarationFile(file))) {
+ ts.forEachChild(node.body, function (node) {
+ collect(node, false, collectOnlyRequireCalls);
+ });
+ }
break;
- }
- if (allowRelativeModuleNames || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
- (imports || (imports = [])).push(moduleNameExpr);
- }
- break;
- case 218:
- if (node.name.kind === 9 && (node.flags & 4 || ts.isDeclarationFile(file))) {
- ts.forEachChild(node.body, function (node) {
- collect(node, false);
- });
- }
- break;
+ }
+ }
+ if (isJavaScriptFile) {
+ if (ts.isRequireCall(node)) {
+ (imports || (imports = [])).push(node.arguments[0]);
+ }
+ else {
+ ts.forEachChild(node, function (node) { return collect(node, allowRelativeModuleNames, true); });
+ }
}
}
}
@@ -31225,7 +31644,6 @@ var ts;
}
processImportedModules(file, basePath);
if (isDefaultLib) {
- file.isDefaultLib = true;
files.unshift(file);
}
else {
@@ -31298,6 +31716,9 @@ var ts;
commonPathComponents.length = sourcePathComponents.length;
}
});
+ if (!commonPathComponents) {
+ return currentDirectory;
+ }
return ts.getNormalizedPathFromPathComponents(commonPathComponents);
}
function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
@@ -31380,10 +31801,12 @@ var ts;
if (options.module === 5 && languageVersion < 2) {
programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower));
}
+ if (outFile && options.module && !(options.module === 2 || options.module === 4)) {
+ programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile"));
+ }
if (options.outDir ||
options.sourceRoot ||
- (options.mapRoot &&
- (!outFile || firstExternalModuleSourceFile !== undefined))) {
+ options.mapRoot) {
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
}
@@ -31862,20 +32285,20 @@ var ts;
var exclude = json["exclude"] instanceof Array ? ts.map(json["exclude"], ts.normalizeSlashes) : undefined;
var sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
for (var i = 0; i < sysFiles.length; i++) {
- var name_29 = sysFiles[i];
- if (ts.fileExtensionIs(name_29, ".d.ts")) {
- var baseName = name_29.substr(0, name_29.length - ".d.ts".length);
+ var name_31 = sysFiles[i];
+ if (ts.fileExtensionIs(name_31, ".d.ts")) {
+ var baseName = name_31.substr(0, name_31.length - ".d.ts".length);
if (!ts.contains(sysFiles, baseName + ".tsx") && !ts.contains(sysFiles, baseName + ".ts")) {
- fileNames.push(name_29);
+ fileNames.push(name_31);
}
}
- else if (ts.fileExtensionIs(name_29, ".ts")) {
- if (!ts.contains(sysFiles, name_29 + "x")) {
- fileNames.push(name_29);
+ else if (ts.fileExtensionIs(name_31, ".ts")) {
+ if (!ts.contains(sysFiles, name_31 + "x")) {
+ fileNames.push(name_31);
}
}
else {
- fileNames.push(name_29);
+ fileNames.push(name_31);
}
}
}
@@ -31994,14 +32417,15 @@ var ts;
var diagnostic = ts.createCompilerDiagnostic.apply(undefined, arguments);
return diagnostic.messageText;
}
+ function getRelativeFileName(fileName, host) {
+ return host ? ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : fileName;
+ }
function reportDiagnosticSimply(diagnostic, host) {
var output = "";
if (diagnostic.file) {
var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character;
- var relativeFileName = host
- ? ts.convertToRelativePath(diagnostic.file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); })
- : diagnostic.file.fileName;
- output += diagnostic.file.fileName + "(" + (line + 1) + "," + (character + 1) + "): ";
+ var relativeFileName = getRelativeFileName(diagnostic.file.fileName, host);
+ output += relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): ";
}
var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase();
output += category + " TS" + diagnostic.code + ": " + ts.flattenDiagnosticMessageText(diagnostic.messageText, ts.sys.newLine) + ts.sys.newLine;
@@ -32030,6 +32454,7 @@ var ts;
var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character;
var _b = ts.getLineAndCharacterOfPosition(file, start + length_3), lastLine = _b.line, lastLineChar = _b.character;
var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line;
+ var relativeFileName = getRelativeFileName(file.fileName, host);
var hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
var gutterWidth = (lastLine + 1 + "").length;
if (hasMoreThanFiveLines) {
@@ -32065,7 +32490,7 @@ var ts;
output += ts.sys.newLine;
}
output += ts.sys.newLine;
- output += file.fileName + "(" + (firstLine + 1) + "," + (firstLineChar + 1) + "): ";
+ output += relativeFileName + "(" + (firstLine + 1) + "," + (firstLineChar + 1) + "): ";
}
var categoryColor = categoryFormatMap[diagnostic.category];
var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase();
@@ -32191,8 +32616,19 @@ var ts;
return;
}
}
+ if (!cachedConfigFileText) {
+ var error = ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, configFileName);
+ reportDiagnostics([error], undefined);
+ ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped);
+ return;
+ }
var result = ts.parseConfigFileTextToJson(configFileName, cachedConfigFileText);
var configObject = result.config;
+ if (!configObject) {
+ reportDiagnostics([result.error], undefined);
+ ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped);
+ return;
+ }
var configParseResult = ts.parseJsonConfigFileContent(configObject, ts.sys, ts.getDirectoryPath(configFileName));
if (configParseResult.errors.length > 0) {
reportDiagnostics(configParseResult.errors, undefined);
@@ -32455,10 +32891,10 @@ var ts;
function serializeCompilerOptions(options) {
var result = {};
var optionsNameMap = ts.getOptionNameMap().optionNameMap;
- for (var name_30 in options) {
- if (ts.hasProperty(options, name_30)) {
- var value = options[name_30];
- switch (name_30) {
+ for (var name_32 in options) {
+ if (ts.hasProperty(options, name_32)) {
+ var value = options[name_32];
+ switch (name_32) {
case "init":
case "watch":
case "version":
@@ -32466,17 +32902,17 @@ var ts;
case "project":
break;
default:
- var optionDefinition = optionsNameMap[name_30.toLowerCase()];
+ var optionDefinition = optionsNameMap[name_32.toLowerCase()];
if (optionDefinition) {
if (typeof optionDefinition.type === "string") {
- result[name_30] = value;
+ result[name_32] = value;
}
else {
var typeMap = optionDefinition.type;
for (var key in typeMap) {
if (ts.hasProperty(typeMap, key)) {
if (typeMap[key] === value)
- result[name_30] = key;
+ result[name_32] = key;
}
}
}
diff --git a/lib/tsserver.js b/lib/tsserver.js
index 2893dab82ef3c..9f0c167408090 100644
--- a/lib/tsserver.js
+++ b/lib/tsserver.js
@@ -665,7 +665,7 @@ var ts;
}
ts.fileExtensionIs = fileExtensionIs;
ts.supportedExtensions = [".ts", ".tsx", ".d.ts"];
- ts.moduleFileExtensions = ts.supportedExtensions;
+ ts.supportedJsExtensions = ts.supportedExtensions.concat(".js", ".jsx");
function isSupportedSourceFileName(fileName) {
if (!fileName) {
return false;
@@ -716,17 +716,16 @@ var ts;
}
function Signature(checker) {
}
+ function Node(kind, pos, end) {
+ this.kind = kind;
+ this.pos = pos;
+ this.end = end;
+ this.flags = 0;
+ this.parent = undefined;
+ }
ts.objectAllocator = {
- getNodeConstructor: function (kind) {
- function Node(pos, end) {
- this.pos = pos;
- this.end = end;
- this.flags = 0;
- this.parent = undefined;
- }
- Node.prototype = { kind: kind };
- return Node;
- },
+ getNodeConstructor: function () { return Node; },
+ getSourceFileConstructor: function () { return Node; },
getSymbolConstructor: function () { return Symbol; },
getTypeConstructor: function () { return Type; },
getSignatureConstructor: function () { return Signature; }
@@ -1003,7 +1002,16 @@ var ts;
if (writeByteOrderMark) {
data = "\uFEFF" + data;
}
- _fs.writeFileSync(fileName, data, "utf8");
+ var fd;
+ try {
+ fd = _fs.openSync(fileName, "w");
+ _fs.writeSync(fd, data, undefined, "utf8");
+ }
+ finally {
+ if (fd !== undefined) {
+ _fs.closeSync(fd);
+ }
+ }
}
function getCanonicalPath(path) {
return useCaseSensitiveFileNames ? path.toLowerCase() : path;
@@ -1688,6 +1696,7 @@ var ts;
Disallow_inconsistently_cased_references_to_the_same_file: { code: 6078, category: ts.DiagnosticCategory.Message, key: "Disallow_inconsistently_cased_references_to_the_same_file_6078", message: "Disallow inconsistently-cased references to the same file." },
Specify_JSX_code_generation_Colon_preserve_or_react: { code: 6080, category: ts.DiagnosticCategory.Message, key: "Specify_JSX_code_generation_Colon_preserve_or_react_6080", message: "Specify JSX code generation: 'preserve' or 'react'" },
Argument_for_jsx_must_be_preserve_or_react: { code: 6081, category: ts.DiagnosticCategory.Message, key: "Argument_for_jsx_must_be_preserve_or_react_6081", message: "Argument for '--jsx' must be 'preserve' or 'react'." },
+ Only_amd_and_system_modules_are_supported_alongside_0: { code: 6082, category: ts.DiagnosticCategory.Error, key: "Only_amd_and_system_modules_are_supported_alongside_0_6082", message: "Only 'amd' and 'system' modules are supported alongside --{0}." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." },
@@ -2148,7 +2157,7 @@ var ts;
function getCommentRanges(text, pos, trailing) {
var result;
var collecting = trailing || pos === 0;
- while (true) {
+ while (pos < text.length) {
var ch = text.charCodeAt(pos);
switch (ch) {
case 13:
@@ -2217,6 +2226,7 @@ var ts;
}
return result;
}
+ return result;
}
function getLeadingCommentRanges(text, pos) {
return getCommentRanges(text, pos, false);
@@ -2312,7 +2322,7 @@ var ts;
error(ts.Diagnostics.Digit_expected);
}
}
- return +(text.substring(start, end));
+ return "" + +(text.substring(start, end));
}
function scanOctalDigits() {
var start = pos;
@@ -2704,7 +2714,7 @@ var ts;
return pos++, token = 36;
case 46:
if (isDigit(text.charCodeAt(pos + 1))) {
- tokenValue = "" + scanNumber();
+ tokenValue = scanNumber();
return token = 8;
}
if (text.charCodeAt(pos + 1) === 46 && text.charCodeAt(pos + 2) === 46) {
@@ -2801,7 +2811,7 @@ var ts;
case 55:
case 56:
case 57:
- tokenValue = "" + scanNumber();
+ tokenValue = scanNumber();
return token = 8;
case 58:
return pos++, token = 54;
@@ -3879,6 +3889,10 @@ var ts;
return file.externalModuleIndicator !== undefined;
}
ts.isExternalModule = isExternalModule;
+ function isExternalOrCommonJsModule(file) {
+ return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
+ }
+ ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
function isDeclarationFile(file) {
return (file.flags & 4096) !== 0;
}
@@ -3925,18 +3939,26 @@ var ts;
return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
}
ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
+ function getLeadingCommentRangesOfNodeFromText(node, text) {
+ return ts.getLeadingCommentRanges(text, node.pos);
+ }
+ ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText;
function getJsDocComments(node, sourceFileOfNode) {
+ return getJsDocCommentsFromText(node, sourceFileOfNode.text);
+ }
+ ts.getJsDocComments = getJsDocComments;
+ function getJsDocCommentsFromText(node, text) {
var commentRanges = (node.kind === 138 || node.kind === 137) ?
- ts.concatenate(ts.getTrailingCommentRanges(sourceFileOfNode.text, node.pos), ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) :
- getLeadingCommentRangesOfNode(node, sourceFileOfNode);
+ ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
+ getLeadingCommentRangesOfNodeFromText(node, text);
return ts.filter(commentRanges, isJsDocComment);
function isJsDocComment(comment) {
- return sourceFileOfNode.text.charCodeAt(comment.pos + 1) === 42 &&
- sourceFileOfNode.text.charCodeAt(comment.pos + 2) === 42 &&
- sourceFileOfNode.text.charCodeAt(comment.pos + 3) !== 47;
+ return text.charCodeAt(comment.pos + 1) === 42 &&
+ text.charCodeAt(comment.pos + 2) === 42 &&
+ text.charCodeAt(comment.pos + 3) !== 47;
}
}
- ts.getJsDocComments = getJsDocComments;
+ ts.getJsDocCommentsFromText = getJsDocCommentsFromText;
ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/;
ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/;
function isTypeNode(node) {
@@ -4465,6 +4487,41 @@ var ts;
return node.kind === 221 && node.moduleReference.kind !== 232;
}
ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
+ function isSourceFileJavaScript(file) {
+ return isInJavaScriptFile(file);
+ }
+ ts.isSourceFileJavaScript = isSourceFileJavaScript;
+ function isInJavaScriptFile(node) {
+ return node && !!(node.parserContextFlags & 32);
+ }
+ ts.isInJavaScriptFile = isInJavaScriptFile;
+ function isRequireCall(expression) {
+ return expression.kind === 168 &&
+ expression.expression.kind === 69 &&
+ expression.expression.text === "require" &&
+ expression.arguments.length === 1 &&
+ expression.arguments[0].kind === 9;
+ }
+ ts.isRequireCall = isRequireCall;
+ function isExportsPropertyAssignment(expression) {
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === 181) &&
+ (expression.operatorToken.kind === 56) &&
+ (expression.left.kind === 166) &&
+ (expression.left.expression.kind === 69) &&
+ ((expression.left.expression).text === "exports");
+ }
+ ts.isExportsPropertyAssignment = isExportsPropertyAssignment;
+ function isModuleExportsAssignment(expression) {
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === 181) &&
+ (expression.operatorToken.kind === 56) &&
+ (expression.left.kind === 166) &&
+ (expression.left.expression.kind === 69) &&
+ ((expression.left.expression).text === "module") &&
+ (expression.left.name.text === "exports");
+ }
+ ts.isModuleExportsAssignment = isModuleExportsAssignment;
function getExternalModuleName(node) {
if (node.kind === 222) {
return node.moduleSpecifier;
@@ -4776,8 +4833,8 @@ var ts;
function getFileReferenceFromReferencePath(comment, commentRange) {
var simpleReferenceRegEx = /^\/\/\/\s*/gim;
- if (simpleReferenceRegEx.exec(comment)) {
- if (isNoDefaultLibRegEx.exec(comment)) {
+ if (simpleReferenceRegEx.test(comment)) {
+ if (isNoDefaultLibRegEx.test(comment)) {
return {
isNoDefaultLib: true
};
@@ -4819,12 +4876,20 @@ var ts;
return isFunctionLike(node) && (node.flags & 256) !== 0 && !isAccessor(node);
}
ts.isAsyncFunctionLike = isAsyncFunctionLike;
+ function isStringOrNumericLiteral(kind) {
+ return kind === 9 || kind === 8;
+ }
+ ts.isStringOrNumericLiteral = isStringOrNumericLiteral;
function hasDynamicName(declaration) {
- return declaration.name &&
- declaration.name.kind === 136 &&
- !isWellKnownSymbolSyntactically(declaration.name.expression);
+ return declaration.name && isDynamicName(declaration.name);
}
ts.hasDynamicName = hasDynamicName;
+ function isDynamicName(name) {
+ return name.kind === 136 &&
+ !isStringOrNumericLiteral(name.expression.kind) &&
+ !isWellKnownSymbolSyntactically(name.expression);
+ }
+ ts.isDynamicName = isDynamicName;
function isWellKnownSymbolSyntactically(node) {
return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
}
@@ -5045,11 +5110,11 @@ var ts;
}
ts.getIndentSize = getIndentSize;
function createTextWriter(newLine) {
- var output = "";
- var indent = 0;
- var lineStart = true;
- var lineCount = 0;
- var linePos = 0;
+ var output;
+ var indent;
+ var lineStart;
+ var lineCount;
+ var linePos;
function write(s) {
if (s && s.length) {
if (lineStart) {
@@ -5059,6 +5124,13 @@ var ts;
output += s;
}
}
+ function reset() {
+ output = "";
+ indent = 0;
+ lineStart = true;
+ lineCount = 0;
+ linePos = 0;
+ }
function rawWrite(s) {
if (s !== undefined) {
if (lineStart) {
@@ -5085,9 +5157,10 @@ var ts;
lineStart = true;
}
}
- function writeTextOfNode(sourceFile, node) {
- write(getSourceTextOfNodeFromSourceFile(sourceFile, node));
+ function writeTextOfNode(text, node) {
+ write(getTextOfNodeFromSourceText(text, node));
}
+ reset();
return {
write: write,
rawWrite: rawWrite,
@@ -5100,10 +5173,17 @@ var ts;
getTextPos: function () { return output.length; },
getLine: function () { return lineCount + 1; },
getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; },
- getText: function () { return output; }
+ getText: function () { return output; },
+ reset: reset
};
}
ts.createTextWriter = createTextWriter;
+ function getExternalModuleNameFromPath(host, fileName) {
+ var dir = host.getCurrentDirectory();
+ var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, fileName, dir, function (f) { return host.getCanonicalFileName(f); }, false);
+ return ts.removeFileExtension(relativePath);
+ }
+ ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
function getOwnEmitOutputFilePath(sourceFile, host, extension) {
var compilerOptions = host.getCompilerOptions();
var emitOutputFilePathWithoutExtension;
@@ -5132,6 +5212,10 @@ var ts;
return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line;
}
ts.getLineOfLocalPosition = getLineOfLocalPosition;
+ function getLineOfLocalPositionFromLineMap(lineMap, pos) {
+ return ts.computeLineAndCharacterOfPosition(lineMap, pos).line;
+ }
+ ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
function getFirstConstructorWithBody(node) {
return ts.forEach(node.members, function (member) {
if (member.kind === 144 && nodeIsPresent(member.body)) {
@@ -5202,21 +5286,21 @@ var ts;
};
}
ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
- function emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments) {
+ function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
- getLineOfLocalPosition(currentSourceFile, node.pos) !== getLineOfLocalPosition(currentSourceFile, leadingComments[0].pos)) {
+ getLineOfLocalPositionFromLineMap(lineMap, node.pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
writer.writeLine();
}
}
ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
- function emitComments(currentSourceFile, writer, comments, trailingSeparator, newLine, writeComment) {
+ function emitComments(text, lineMap, writer, comments, trailingSeparator, newLine, writeComment) {
var emitLeadingSpace = !trailingSeparator;
ts.forEach(comments, function (comment) {
if (emitLeadingSpace) {
writer.write(" ");
emitLeadingSpace = false;
}
- writeComment(currentSourceFile, writer, comment, newLine);
+ writeComment(text, lineMap, writer, comment, newLine);
if (comment.hasTrailingNewLine) {
writer.writeLine();
}
@@ -5229,16 +5313,16 @@ var ts;
});
}
ts.emitComments = emitComments;
- function emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, removeComments) {
+ function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
var leadingComments;
var currentDetachedCommentInfo;
if (removeComments) {
if (node.pos === 0) {
- leadingComments = ts.filter(ts.getLeadingCommentRanges(currentSourceFile.text, node.pos), isPinnedComment);
+ leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment);
}
}
else {
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
+ leadingComments = ts.getLeadingCommentRanges(text, node.pos);
}
if (leadingComments) {
var detachedComments = [];
@@ -5246,8 +5330,8 @@ var ts;
for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
var comment = leadingComments_1[_i];
if (lastComment) {
- var lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastComment.end);
- var commentLine = getLineOfLocalPosition(currentSourceFile, comment.pos);
+ var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
+ var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
if (commentLine >= lastCommentLine + 2) {
break;
}
@@ -5256,37 +5340,37 @@ var ts;
lastComment = comment;
}
if (detachedComments.length) {
- var lastCommentLine = getLineOfLocalPosition(currentSourceFile, ts.lastOrUndefined(detachedComments).end);
- var nodeLine = getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node.pos));
+ var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.lastOrUndefined(detachedComments).end);
+ var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
if (nodeLine >= lastCommentLine + 2) {
- emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
- emitComments(currentSourceFile, writer, detachedComments, true, newLine, writeComment);
+ emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
+ emitComments(text, lineMap, writer, detachedComments, true, newLine, writeComment);
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end };
}
}
}
return currentDetachedCommentInfo;
function isPinnedComment(comment) {
- return currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 33;
+ return text.charCodeAt(comment.pos + 1) === 42 &&
+ text.charCodeAt(comment.pos + 2) === 33;
}
}
ts.emitDetachedComments = emitDetachedComments;
- function writeCommentRange(currentSourceFile, writer, comment, newLine) {
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 42) {
- var firstCommentLineAndCharacter = ts.getLineAndCharacterOfPosition(currentSourceFile, comment.pos);
- var lineCount = ts.getLineStarts(currentSourceFile).length;
+ function writeCommentRange(text, lineMap, writer, comment, newLine) {
+ if (text.charCodeAt(comment.pos + 1) === 42) {
+ var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, comment.pos);
+ var lineCount = lineMap.length;
var firstCommentLineIndent;
for (var pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
var nextLineStart = (currentLine + 1) === lineCount
- ? currentSourceFile.text.length + 1
- : getStartPositionOfLine(currentLine + 1, currentSourceFile);
+ ? text.length + 1
+ : lineMap[currentLine + 1];
if (pos !== comment.pos) {
if (firstCommentLineIndent === undefined) {
- firstCommentLineIndent = calculateIndent(getStartPositionOfLine(firstCommentLineAndCharacter.line, currentSourceFile), comment.pos);
+ firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], comment.pos);
}
var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
- var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(pos, nextLineStart);
+ var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
if (spacesToEmit > 0) {
var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
@@ -5300,40 +5384,40 @@ var ts;
writer.rawWrite("");
}
}
- writeTrimmedCurrentLine(pos, nextLineStart);
+ writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart);
pos = nextLineStart;
}
}
else {
- writer.write(currentSourceFile.text.substring(comment.pos, comment.end));
- }
- function writeTrimmedCurrentLine(pos, nextLineStart) {
- var end = Math.min(comment.end, nextLineStart - 1);
- var currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, "");
- if (currentLineText) {
- writer.write(currentLineText);
- if (end !== comment.end) {
- writer.writeLine();
- }
- }
- else {
- writer.writeLiteral(newLine);
+ writer.write(text.substring(comment.pos, comment.end));
+ }
+ }
+ ts.writeCommentRange = writeCommentRange;
+ function writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart) {
+ var end = Math.min(comment.end, nextLineStart - 1);
+ var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
+ if (currentLineText) {
+ writer.write(currentLineText);
+ if (end !== comment.end) {
+ writer.writeLine();
}
}
- function calculateIndent(pos, end) {
- var currentLineIndent = 0;
- for (; pos < end && ts.isWhiteSpace(currentSourceFile.text.charCodeAt(pos)); pos++) {
- if (currentSourceFile.text.charCodeAt(pos) === 9) {
- currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
- }
- else {
- currentLineIndent++;
- }
+ else {
+ writer.writeLiteral(newLine);
+ }
+ }
+ function calculateIndent(text, pos, end) {
+ var currentLineIndent = 0;
+ for (; pos < end && ts.isWhiteSpace(text.charCodeAt(pos)); pos++) {
+ if (text.charCodeAt(pos) === 9) {
+ currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
+ }
+ else {
+ currentLineIndent++;
}
- return currentLineIndent;
}
+ return currentLineIndent;
}
- ts.writeCommentRange = writeCommentRange;
function modifierToFlag(token) {
switch (token) {
case 113: return 64;
@@ -5427,14 +5511,14 @@ var ts;
return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 512) ? symbol.valueDeclaration.localSymbol : undefined;
}
ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
- function isJavaScript(fileName) {
- return ts.fileExtensionIs(fileName, ".js");
+ function hasJavaScriptFileExtension(fileName) {
+ return ts.fileExtensionIs(fileName, ".js") || ts.fileExtensionIs(fileName, ".jsx");
}
- ts.isJavaScript = isJavaScript;
- function isTsx(fileName) {
- return ts.fileExtensionIs(fileName, ".tsx");
+ ts.hasJavaScriptFileExtension = hasJavaScriptFileExtension;
+ function allowsJsxExpressions(fileName) {
+ return ts.fileExtensionIs(fileName, ".tsx") || ts.fileExtensionIs(fileName, ".jsx");
}
- ts.isTsx = isTsx;
+ ts.allowsJsxExpressions = allowsJsxExpressions;
function getExpandedCharCodes(input) {
var output = [];
var length = input.length;
@@ -5644,14 +5728,16 @@ var ts;
})(ts || (ts = {}));
var ts;
(function (ts) {
- var nodeConstructors = new Array(272);
ts.parseTime = 0;
- function getNodeConstructor(kind) {
- return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind));
- }
- ts.getNodeConstructor = getNodeConstructor;
+ var NodeConstructor;
+ var SourceFileConstructor;
function createNode(kind, pos, end) {
- return new (getNodeConstructor(kind))(pos, end);
+ if (kind === 248) {
+ return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
+ }
+ else {
+ return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
+ }
}
ts.createNode = createNode;
function visitNode(cbNode, node) {
@@ -6050,6 +6136,8 @@ var ts;
(function (Parser) {
var scanner = ts.createScanner(2, true);
var disallowInAndDecoratorContext = 1 | 4;
+ var NodeConstructor;
+ var SourceFileConstructor;
var sourceFile;
var parseDiagnostics;
var syntaxCursor;
@@ -6062,13 +6150,16 @@ var ts;
var contextFlags;
var parseErrorBeforeNextFinishedNode = false;
function parseSourceFile(fileName, _sourceText, languageVersion, _syntaxCursor, setParentNodes) {
- initializeState(fileName, _sourceText, languageVersion, _syntaxCursor);
+ var isJavaScriptFile = ts.hasJavaScriptFileExtension(fileName) || _sourceText.lastIndexOf("// @language=javascript", 0) === 0;
+ initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor);
var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes);
clearState();
return result;
}
Parser.parseSourceFile = parseSourceFile;
- function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor) {
+ function initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor) {
+ NodeConstructor = ts.objectAllocator.getNodeConstructor();
+ SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
sourceText = _sourceText;
syntaxCursor = _syntaxCursor;
parseDiagnostics = [];
@@ -6076,12 +6167,12 @@ var ts;
identifiers = {};
identifierCount = 0;
nodeCount = 0;
- contextFlags = ts.isJavaScript(fileName) ? 32 : 0;
+ contextFlags = isJavaScriptFile ? 32 : 0;
parseErrorBeforeNextFinishedNode = false;
scanner.setText(sourceText);
scanner.setOnError(scanError);
scanner.setScriptTarget(languageVersion);
- scanner.setLanguageVariant(ts.isTsx(fileName) ? 1 : 0);
+ scanner.setLanguageVariant(ts.allowsJsxExpressions(fileName) ? 1 : 0);
}
function clearState() {
scanner.setText("");
@@ -6094,6 +6185,9 @@ var ts;
}
function parseSourceFileWorker(fileName, languageVersion, setParentNodes) {
sourceFile = createSourceFile(fileName, languageVersion);
+ if (contextFlags & 32) {
+ sourceFile.parserContextFlags = 32;
+ }
token = nextToken();
processReferenceComments(sourceFile);
sourceFile.statements = parseList(0, parseStatement);
@@ -6107,7 +6201,7 @@ var ts;
if (setParentNodes) {
fixupParentReferences(sourceFile);
}
- if (ts.isJavaScript(fileName)) {
+ if (ts.isSourceFileJavaScript(sourceFile)) {
addJSDocComments();
}
return sourceFile;
@@ -6153,15 +6247,14 @@ var ts;
}
Parser.fixupParentReferences = fixupParentReferences;
function createSourceFile(fileName, languageVersion) {
- var sourceFile = createNode(248, 0);
- sourceFile.pos = 0;
- sourceFile.end = sourceText.length;
+ var sourceFile = new SourceFileConstructor(248, 0, sourceText.length);
+ nodeCount++;
sourceFile.text = sourceText;
sourceFile.bindDiagnostics = [];
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = ts.normalizePath(fileName);
sourceFile.flags = ts.fileExtensionIs(sourceFile.fileName, ".d.ts") ? 4096 : 0;
- sourceFile.languageVariant = ts.isTsx(sourceFile.fileName) ? 1 : 0;
+ sourceFile.languageVariant = ts.allowsJsxExpressions(sourceFile.fileName) ? 1 : 0;
return sourceFile;
}
function setContextFlag(val, flag) {
@@ -6383,7 +6476,7 @@ var ts;
if (!(pos >= 0)) {
pos = scanner.getStartPos();
}
- return new (nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)))(pos, pos);
+ return new NodeConstructor(kind, pos, pos);
}
function finishNode(node, end) {
node.end = end === undefined ? scanner.getStartPos() : end;
@@ -6521,7 +6614,7 @@ var ts;
case 12:
return token === 19 || token === 37 || isLiteralPropertyName();
case 9:
- return isLiteralPropertyName();
+ return token === 19 || isLiteralPropertyName();
case 7:
if (token === 15) {
return lookAhead(isValidHeritageClauseObjectLiteral);
@@ -7042,9 +7135,7 @@ var ts;
}
function parseParameterType() {
if (parseOptional(54)) {
- return token === 9
- ? parseLiteralNode(true)
- : parseType();
+ return parseType();
}
return undefined;
}
@@ -7301,6 +7392,8 @@ var ts;
case 131:
var node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReferenceOrTypePredicate();
+ case 9:
+ return parseLiteralNode(true);
case 103:
case 97:
return parseTokenNode();
@@ -7330,6 +7423,7 @@ var ts;
case 19:
case 25:
case 92:
+ case 9:
return true;
case 17:
return lookAhead(isStartOfParenthesizedOrFunctionType);
@@ -7843,7 +7937,6 @@ var ts;
var unaryOperator = token;
var simpleUnaryExpression = parseSimpleUnaryExpression();
if (token === 38) {
- var diagnostic;
var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
if (simpleUnaryExpression.kind === 171) {
parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
@@ -9507,7 +9600,7 @@ var ts;
}
JSDocParser.isJSDocType = isJSDocType;
function parseJSDocTypeExpressionForTests(content, start, length) {
- initializeState("file.js", content, 2, undefined);
+ initializeState("file.js", content, 2, true, undefined);
var jsDocTypeExpression = parseJSDocTypeExpression(start, length);
var diagnostics = parseDiagnostics;
clearState();
@@ -9758,7 +9851,7 @@ var ts;
}
}
function parseIsolatedJSDocComment(content, start, length) {
- initializeState("file.js", content, 2, undefined);
+ initializeState("file.js", content, 2, true, undefined);
var jsDocComment = parseJSDocComment(undefined, start, length);
var diagnostics = parseDiagnostics;
clearState();
@@ -10394,6 +10487,9 @@ var ts;
}
if (node.name.kind === 136) {
var nameExpression = node.name.expression;
+ if (ts.isStringOrNumericLiteral(nameExpression.kind)) {
+ return nameExpression.text;
+ }
ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
return ts.getPropertyNameForKnownSymbolName(nameExpression.name.text);
}
@@ -10414,6 +10510,8 @@ var ts;
return "__export";
case 227:
return node.isExportEquals ? "export=" : "default";
+ case 181:
+ return "export=";
case 213:
case 214:
return node.flags & 512 ? "default" : undefined;
@@ -11033,6 +11131,14 @@ var ts;
case 69:
return checkStrictModeIdentifier(node);
case 181:
+ if (ts.isInJavaScriptFile(node)) {
+ if (ts.isExportsPropertyAssignment(node)) {
+ bindExportsPropertyAssignment(node);
+ }
+ else if (ts.isModuleExportsAssignment(node)) {
+ bindModuleExportsAssignment(node);
+ }
+ }
return checkStrictModeBinaryExpression(node);
case 244:
return checkStrictModeCatchClause(node);
@@ -11092,6 +11198,11 @@ var ts;
checkStrictModeFunctionName(node);
var bindingName = node.name ? node.name.text : "__function";
return bindAnonymousDeclaration(node, 16, bindingName);
+ case 168:
+ if (ts.isInJavaScriptFile(node)) {
+ bindCallExpression(node);
+ }
+ break;
case 186:
case 214:
return bindClassLikeDeclaration(node);
@@ -11121,14 +11232,18 @@ var ts;
function bindSourceFileIfExternalModule() {
setExportContextFlag(file);
if (ts.isExternalModule(file)) {
- bindAnonymousDeclaration(file, 512, "\"" + ts.removeFileExtension(file.fileName) + "\"");
+ bindSourceFileAsExternalModule();
}
}
+ function bindSourceFileAsExternalModule() {
+ bindAnonymousDeclaration(file, 512, "\"" + ts.removeFileExtension(file.fileName) + "\"");
+ }
function bindExportAssignment(node) {
+ var boundExpression = node.kind === 227 ? node.expression : node.right;
if (!container.symbol || !container.symbol.exports) {
bindAnonymousDeclaration(node, 8388608, getDeclarationName(node));
}
- else if (node.expression.kind === 69) {
+ else if (boundExpression.kind === 69) {
declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608);
}
else {
@@ -11148,6 +11263,25 @@ var ts;
declareSymbolAndAddToSymbolTable(node, 8388608, 8388608);
}
}
+ function setCommonJsModuleIndicator(node) {
+ if (!file.commonJsModuleIndicator) {
+ file.commonJsModuleIndicator = node;
+ bindSourceFileAsExternalModule();
+ }
+ }
+ function bindExportsPropertyAssignment(node) {
+ setCommonJsModuleIndicator(node);
+ declareSymbol(file.symbol.exports, file.symbol, node.left, 4 | 7340032, 0);
+ }
+ function bindModuleExportsAssignment(node) {
+ setCommonJsModuleIndicator(node);
+ bindExportAssignment(node);
+ }
+ function bindCallExpression(node) {
+ if (!file.commonJsModuleIndicator && ts.isRequireCall(node)) {
+ setCommonJsModuleIndicator(node);
+ }
+ }
function bindClassLikeDeclaration(node) {
if (node.kind === 214) {
bindBlockScopedDeclaration(node, 32, 899519);
@@ -11268,7 +11402,7 @@ var ts;
function checkUnreachable(node) {
switch (currentReachabilityState) {
case 4:
- var reportError = ts.isStatement(node) ||
+ var reportError = (ts.isStatement(node) && node.kind !== 194) ||
node.kind === 214 ||
(node.kind === 218 && shouldReportErrorOnModuleDeclaration(node)) ||
(node.kind === 217 && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
@@ -11364,7 +11498,7 @@ var ts;
symbolToString: symbolToString,
getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
getRootSymbols: getRootSymbols,
- getContextualType: getContextualType,
+ getContextualType: getApparentTypeOfContextualType,
getFullyQualifiedName: getFullyQualifiedName,
getResolvedSignature: getResolvedSignature,
getConstantValue: getConstantValue,
@@ -11620,7 +11754,7 @@ var ts;
return ts.getAncestor(node, 248);
}
function isGlobalSourceFile(node) {
- return node.kind === 248 && !ts.isExternalModule(node);
+ return node.kind === 248 && !ts.isExternalOrCommonJsModule(node);
}
function getSymbol(symbols, name, meaning) {
if (meaning && ts.hasProperty(symbols, name)) {
@@ -11706,23 +11840,24 @@ var ts;
}
switch (location.kind) {
case 248:
- if (!ts.isExternalModule(location))
+ if (!ts.isExternalOrCommonJsModule(location))
break;
case 218:
var moduleExports = getSymbolOfNode(location).exports;
if (location.kind === 248 ||
(location.kind === 218 && location.name.kind === 9)) {
+ if (result = moduleExports["default"]) {
+ var localSymbol = ts.getLocalSymbolForExportDefault(result);
+ if (localSymbol && (result.flags & meaning) && localSymbol.name === name) {
+ break loop;
+ }
+ result = undefined;
+ }
if (ts.hasProperty(moduleExports, name) &&
moduleExports[name].flags === 8388608 &&
ts.getDeclarationOfKind(moduleExports[name], 230)) {
break;
}
- result = moduleExports["default"];
- var localSymbol = ts.getLocalSymbolForExportDefault(result);
- if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
- break loop;
- }
- result = undefined;
}
if (result = getSymbol(moduleExports, name, meaning & 8914931)) {
break loop;
@@ -12080,6 +12215,9 @@ var ts;
if (moduleName === undefined) {
return;
}
+ if (moduleName.indexOf("!") >= 0) {
+ moduleName = moduleName.substr(0, moduleName.indexOf("!"));
+ }
var isRelative = ts.isExternalModuleNameRelative(moduleName);
if (!isRelative) {
var symbol = getSymbol(globals, "\"" + moduleName + "\"", 512);
@@ -12250,7 +12388,7 @@ var ts;
}
switch (location_1.kind) {
case 248:
- if (!ts.isExternalModule(location_1)) {
+ if (!ts.isExternalOrCommonJsModule(location_1)) {
break;
}
case 218:
@@ -12377,7 +12515,7 @@ var ts;
}
function hasExternalModuleSymbol(declaration) {
return (declaration.kind === 218 && declaration.name.kind === 9) ||
- (declaration.kind === 248 && ts.isExternalModule(declaration));
+ (declaration.kind === 248 && ts.isExternalOrCommonJsModule(declaration));
}
function hasVisibleDeclarations(symbol) {
var aliasesToMakeVisible;
@@ -12575,7 +12713,7 @@ var ts;
writeAnonymousType(type, flags);
}
else if (type.flags & 256) {
- writer.writeStringLiteral(type.text);
+ writer.writeStringLiteral("\"" + ts.escapeString(type.text) + "\"");
}
else {
writePunctuation(writer, 15);
@@ -12939,7 +13077,7 @@ var ts;
}
}
else if (node.kind === 248) {
- return ts.isExternalModule(node) ? node : undefined;
+ return ts.isExternalOrCommonJsModule(node) ? node : undefined;
}
}
ts.Debug.fail("getContainingModule cant reach here");
@@ -13144,6 +13282,23 @@ var ts;
var symbol = getSymbolOfNode(node);
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
}
+ function getTextOfPropertyName(name) {
+ switch (name.kind) {
+ case 69:
+ return name.text;
+ case 9:
+ case 8:
+ return name.text;
+ case 136:
+ if (ts.isStringOrNumericLiteral(name.expression.kind)) {
+ return name.expression.text;
+ }
+ }
+ return undefined;
+ }
+ function isComputedNonLiteralName(name) {
+ return name.kind === 136 && !ts.isStringOrNumericLiteral(name.expression.kind);
+ }
function getTypeForBindingElement(declaration) {
var pattern = declaration.parent;
var parentType = getTypeForBindingElementParent(pattern.parent);
@@ -13159,8 +13314,12 @@ var ts;
var type;
if (pattern.kind === 161) {
var name_11 = declaration.propertyName || declaration.name;
- type = getTypeOfPropertyOfType(parentType, name_11.text) ||
- isNumericLiteralName(name_11.text) && getIndexTypeOfType(parentType, 1) ||
+ if (isComputedNonLiteralName(name_11)) {
+ return anyType;
+ }
+ var text = getTextOfPropertyName(name_11);
+ type = getTypeOfPropertyOfType(parentType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1) ||
getIndexTypeOfType(parentType, 0);
if (!type) {
error(name_11, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_11));
@@ -13238,10 +13397,16 @@ var ts;
}
function getTypeFromObjectBindingPattern(pattern, includePatternInType) {
var members = {};
+ var hasComputedProperties = false;
ts.forEach(pattern.elements, function (e) {
- var flags = 4 | 67108864 | (e.initializer ? 536870912 : 0);
var name = e.propertyName || e.name;
- var symbol = createSymbol(flags, name.text);
+ if (isComputedNonLiteralName(name)) {
+ hasComputedProperties = true;
+ return;
+ }
+ var text = getTextOfPropertyName(name);
+ var flags = 4 | 67108864 | (e.initializer ? 536870912 : 0);
+ var symbol = createSymbol(flags, text);
symbol.type = getTypeFromBindingElement(e, includePatternInType);
symbol.bindingElement = e;
members[symbol.name] = symbol;
@@ -13250,6 +13415,9 @@ var ts;
if (includePatternInType) {
result.pattern = pattern;
}
+ if (hasComputedProperties) {
+ result.flags |= 67108864;
+ }
return result;
}
function getTypeFromArrayBindingPattern(pattern, includePatternInType) {
@@ -13300,6 +13468,12 @@ var ts;
if (declaration.kind === 227) {
return links.type = checkExpression(declaration.expression);
}
+ if (declaration.kind === 181) {
+ return links.type = checkExpression(declaration.right);
+ }
+ if (declaration.kind === 166) {
+ return checkExpressionCached(declaration.parent.right);
+ }
if (!pushTypeResolution(symbol, 0)) {
return unknownType;
}
@@ -13549,17 +13723,19 @@ var ts;
}
function resolveBaseTypesOfClass(type) {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
- var baseContructorType = getBaseConstructorTypeOfClass(type);
- if (!(baseContructorType.flags & 80896)) {
+ var baseConstructorType = getBaseConstructorTypeOfClass(type);
+ if (!(baseConstructorType.flags & 80896)) {
return;
}
var baseTypeNode = getBaseTypeNodeOfClass(type);
var baseType;
- if (baseContructorType.symbol && baseContructorType.symbol.flags & 32) {
- baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseContructorType.symbol);
+ var originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
+ if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 &&
+ areAllOuterTypeParametersApplied(originalBaseType)) {
+ baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
}
else {
- var constructors = getInstantiatedConstructorsForTypeArguments(baseContructorType, baseTypeNode.typeArguments);
+ var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments);
if (!constructors.length) {
error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
return;
@@ -13584,6 +13760,15 @@ var ts;
type.resolvedBaseTypes.push(baseType);
}
}
+ function areAllOuterTypeParametersApplied(type) {
+ var outerTypeParameters = type.outerTypeParameters;
+ if (outerTypeParameters) {
+ var last = outerTypeParameters.length - 1;
+ var typeArguments = type.typeArguments;
+ return outerTypeParameters[last].symbol !== typeArguments[last].symbol;
+ }
+ return true;
+ }
function resolveBaseTypesOfInterface(type) {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
@@ -13655,7 +13840,7 @@ var ts;
type.typeArguments = type.typeParameters;
type.thisType = createType(512 | 33554432);
type.thisType.symbol = symbol;
- type.thisType.constraint = getTypeWithThisArgument(type);
+ type.thisType.constraint = type;
}
}
return links.declaredType;
@@ -14130,14 +14315,19 @@ var ts;
type = getApparentType(type);
return type.flags & 49152 ? getPropertiesOfUnionOrIntersectionType(type) : getPropertiesOfObjectType(type);
}
+ function getApparentTypeOfTypeParameter(type) {
+ if (!type.resolvedApparentType) {
+ var constraintType = getConstraintOfTypeParameter(type);
+ while (constraintType && constraintType.flags & 512) {
+ constraintType = getConstraintOfTypeParameter(constraintType);
+ }
+ type.resolvedApparentType = getTypeWithThisArgument(constraintType || emptyObjectType, type);
+ }
+ return type.resolvedApparentType;
+ }
function getApparentType(type) {
if (type.flags & 512) {
- do {
- type = getConstraintOfTypeParameter(type);
- } while (type && type.flags & 512);
- if (!type) {
- type = emptyObjectType;
- }
+ type = getApparentTypeOfTypeParameter(type);
}
if (type.flags & 258) {
type = globalStringType;
@@ -14290,7 +14480,7 @@ var ts;
if (node.initializer) {
var signatureDeclaration = node.parent;
var signature = getSignatureFromDeclaration(signatureDeclaration);
- var parameterIndex = signatureDeclaration.parameters.indexOf(node);
+ var parameterIndex = ts.indexOf(signatureDeclaration.parameters, node);
ts.Debug.assert(parameterIndex >= 0);
return parameterIndex >= signature.minArgumentCount;
}
@@ -14385,6 +14575,16 @@ var ts;
}
return result;
}
+ function resolveExternalModuleTypeByLiteral(name) {
+ var moduleSym = resolveExternalModuleName(name, name);
+ if (moduleSym) {
+ var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
+ if (resolvedModuleSymbol) {
+ return getTypeOfSymbol(resolvedModuleSymbol);
+ }
+ }
+ return anyType;
+ }
function getReturnTypeOfSignature(signature) {
if (!signature.resolvedReturnType) {
if (!pushTypeResolution(signature, 3)) {
@@ -14846,11 +15046,12 @@ var ts;
return links.resolvedType;
}
function getStringLiteralType(node) {
- if (ts.hasProperty(stringLiteralTypes, node.text)) {
- return stringLiteralTypes[node.text];
+ var text = node.text;
+ if (ts.hasProperty(stringLiteralTypes, text)) {
+ return stringLiteralTypes[text];
}
- var type = stringLiteralTypes[node.text] = createType(256);
- type.text = ts.getTextOfNode(node);
+ var type = stringLiteralTypes[text] = createType(256);
+ type.text = text;
return type;
}
function getTypeFromStringLiteral(node) {
@@ -15319,7 +15520,7 @@ var ts;
return false;
}
function hasExcessProperties(source, target, reportErrors) {
- if (someConstituentTypeHasKind(target, 80896)) {
+ if (!(target.flags & 67108864) && someConstituentTypeHasKind(target, 80896)) {
for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
var prop = _a[_i];
if (!isKnownProperty(target, prop.name)) {
@@ -15409,9 +15610,6 @@ var ts;
return result;
}
function typeParameterIdenticalTo(source, target) {
- if (source.symbol.name !== target.symbol.name) {
- return 0;
- }
if (source.constraint === target.constraint) {
return -1;
}
@@ -15856,18 +16054,24 @@ var ts;
}
return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
}
+ function isMatchingSignature(source, target, partialMatch) {
+ if (source.parameters.length === target.parameters.length &&
+ source.minArgumentCount === target.minArgumentCount &&
+ source.hasRestParameter === target.hasRestParameter) {
+ return true;
+ }
+ if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (source.hasRestParameter && !target.hasRestParameter ||
+ source.hasRestParameter === target.hasRestParameter && source.parameters.length >= target.parameters.length)) {
+ return true;
+ }
+ return false;
+ }
function compareSignatures(source, target, partialMatch, ignoreReturnTypes, compareTypes) {
if (source === target) {
return -1;
}
- if (source.parameters.length !== target.parameters.length ||
- source.minArgumentCount !== target.minArgumentCount ||
- source.hasRestParameter !== target.hasRestParameter) {
- if (!partialMatch ||
- source.parameters.length < target.parameters.length && !source.hasRestParameter ||
- source.minArgumentCount > target.minArgumentCount) {
- return 0;
- }
+ if (!(isMatchingSignature(source, target, partialMatch))) {
+ return 0;
}
var result = -1;
if (source.typeParameters && target.typeParameters) {
@@ -15952,6 +16156,9 @@ var ts;
function isTupleLikeType(type) {
return !!getPropertyOfType(type, "0");
}
+ function isStringLiteralType(type) {
+ return type.flags & 256;
+ }
function isTupleType(type) {
return !!(type.flags & 8192);
}
@@ -16543,7 +16750,7 @@ var ts;
}
}
function narrowTypeByInstanceof(type, expr, assumeTrue) {
- if (isTypeAny(type) || !assumeTrue || expr.left.kind !== 69 || getResolvedSymbol(expr.left) !== symbol) {
+ if (isTypeAny(type) || expr.left.kind !== 69 || getResolvedSymbol(expr.left) !== symbol) {
return type;
}
var rightType = checkExpression(expr.right);
@@ -16571,6 +16778,12 @@ var ts;
}
}
if (targetType) {
+ if (!assumeTrue) {
+ if (type.flags & 16384) {
+ return getUnionType(ts.filter(type.types, function (t) { return !isTypeSubtypeOf(t, targetType); }));
+ }
+ return type;
+ }
return getNarrowedType(type, targetType);
}
return type;
@@ -16982,6 +17195,9 @@ var ts;
function getIndexTypeOfContextualType(type, kind) {
return applyToContextualType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); });
}
+ function contextualTypeIsStringLiteralType(type) {
+ return !!(type.flags & 16384 ? ts.forEach(type.types, isStringLiteralType) : isStringLiteralType(type));
+ }
function contextualTypeIsTupleLikeType(type) {
return !!(type.flags & 16384 ? ts.forEach(type.types, isTupleLikeType) : isTupleLikeType(type));
}
@@ -16997,7 +17213,7 @@ var ts;
}
function getContextualTypeForObjectLiteralElement(element) {
var objectLiteral = element.parent;
- var type = getContextualType(objectLiteral);
+ var type = getApparentTypeOfContextualType(objectLiteral);
if (type) {
if (!ts.hasDynamicName(element)) {
var symbolName = getSymbolOfNode(element).name;
@@ -17013,7 +17229,7 @@ var ts;
}
function getContextualTypeForElementExpression(node) {
var arrayLiteral = node.parent;
- var type = getContextualType(arrayLiteral);
+ var type = getApparentTypeOfContextualType(arrayLiteral);
if (type) {
var index = ts.indexOf(arrayLiteral.elements, node);
return getTypeOfPropertyOfContextualType(type, "" + index)
@@ -17042,11 +17258,11 @@ var ts;
}
return undefined;
}
- function getContextualType(node) {
- var type = getContextualTypeWorker(node);
+ function getApparentTypeOfContextualType(node) {
+ var type = getContextualType(node);
return type && getApparentType(type);
}
- function getContextualTypeWorker(node) {
+ function getContextualType(node) {
if (isInsideWithStatementBody(node)) {
return undefined;
}
@@ -17112,7 +17328,7 @@ var ts;
ts.Debug.assert(node.kind !== 143 || ts.isObjectLiteralMethod(node));
var type = ts.isObjectLiteralMethod(node)
? getContextualTypeForObjectLiteralMethod(node)
- : getContextualType(node);
+ : getApparentTypeOfContextualType(node);
if (!type) {
return undefined;
}
@@ -17195,7 +17411,7 @@ var ts;
type.pattern = node;
return type;
}
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
var pattern = contextualType.pattern;
if (pattern && (pattern.kind === 162 || pattern.kind === 164)) {
@@ -17250,10 +17466,11 @@ var ts;
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
var propertiesTable = {};
var propertiesArray = [];
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
var contextualTypeHasPattern = contextualType && contextualType.pattern &&
(contextualType.pattern.kind === 161 || contextualType.pattern.kind === 165);
var typeFlags = 0;
+ var patternWithComputedProperties = false;
for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
var memberDecl = _a[_i];
var member = memberDecl.symbol;
@@ -17279,8 +17496,11 @@ var ts;
if (isOptional) {
prop.flags |= 536870912;
}
+ if (ts.hasDynamicName(memberDecl)) {
+ patternWithComputedProperties = true;
+ }
}
- else if (contextualTypeHasPattern) {
+ else if (contextualTypeHasPattern && !(contextualType.flags & 67108864)) {
var impliedProp = getPropertyOfType(contextualType, member.name);
if (impliedProp) {
prop.flags |= impliedProp.flags & 536870912;
@@ -17323,7 +17543,7 @@ var ts;
var numberIndexType = getIndexType(1);
var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576;
- result.flags |= 524288 | 4194304 | freshObjectLiteralFlag | (typeFlags & 14680064);
+ result.flags |= 524288 | 4194304 | freshObjectLiteralFlag | (typeFlags & 14680064) | (patternWithComputedProperties ? 67108864 : 0);
if (inDestructuringPattern) {
result.pattern = node;
}
@@ -18538,6 +18758,9 @@ var ts;
return anyType;
}
}
+ if (ts.isInJavaScriptFile(node) && ts.isRequireCall(node)) {
+ return resolveExternalModuleTypeByLiteral(node.arguments[0]);
+ }
return getReturnTypeOfSignature(signature);
}
function checkTaggedTemplateExpression(node) {
@@ -18548,7 +18771,9 @@ var ts;
var targetType = getTypeFromTypeNode(node.type);
if (produceDiagnostics && targetType !== unknownType) {
var widenedType = getWidenedType(exprType);
- if (!(isTypeAssignableTo(targetType, widenedType))) {
+ var bothAreStringLike = someConstituentTypeHasKind(targetType, 258) &&
+ someConstituentTypeHasKind(widenedType, 258);
+ if (!bothAreStringLike && !(isTypeAssignableTo(targetType, widenedType))) {
checkTypeAssignableTo(exprType, targetType, node, ts.Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
}
}
@@ -18987,17 +19212,24 @@ var ts;
var p = properties_3[_i];
if (p.kind === 245 || p.kind === 246) {
var name_14 = p.name;
+ if (name_14.kind === 136) {
+ checkComputedPropertyName(name_14);
+ }
+ if (isComputedNonLiteralName(name_14)) {
+ continue;
+ }
+ var text = getTextOfPropertyName(name_14);
var type = isTypeAny(sourceType)
? sourceType
- : getTypeOfPropertyOfType(sourceType, name_14.text) ||
- isNumericLiteralName(name_14.text) && getIndexTypeOfType(sourceType, 1) ||
+ : getTypeOfPropertyOfType(sourceType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(sourceType, 1) ||
getIndexTypeOfType(sourceType, 0);
if (type) {
if (p.kind === 246) {
checkDestructuringAssignment(p, type);
}
else {
- checkDestructuringAssignment(p.initializer || name_14, type);
+ checkDestructuringAssignment(p.initializer, type);
}
}
else {
@@ -19175,6 +19407,9 @@ var ts;
case 31:
case 32:
case 33:
+ if (someConstituentTypeHasKind(leftType, 258) && someConstituentTypeHasKind(rightType, 258)) {
+ return booleanType;
+ }
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
reportOperatorError();
}
@@ -19282,6 +19517,13 @@ var ts;
var type2 = checkExpression(node.whenFalse, contextualMapper);
return getUnionType([type1, type2]);
}
+ function checkStringLiteralExpression(node) {
+ var contextualType = getContextualType(node);
+ if (contextualType && contextualTypeIsStringLiteralType(contextualType)) {
+ return getStringLiteralType(node);
+ }
+ return stringType;
+ }
function checkTemplateExpression(node) {
ts.forEach(node.templateSpans, function (templateSpan) {
checkExpression(templateSpan.expression);
@@ -19320,7 +19562,7 @@ var ts;
if (isInferentialContext(contextualMapper)) {
var signature = getSingleCallSignature(type);
if (signature && signature.typeParameters) {
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
if (contextualType) {
var contextualSignature = getSingleCallSignature(contextualType);
if (contextualSignature && !contextualSignature.typeParameters) {
@@ -19372,6 +19614,7 @@ var ts;
case 183:
return checkTemplateExpression(node);
case 9:
+ return checkStringLiteralExpression(node);
case 11:
return stringType;
case 10:
@@ -20433,7 +20676,7 @@ var ts;
return;
}
var parent = getDeclarationContainer(node);
- if (parent.kind === 248 && ts.isExternalModule(parent)) {
+ if (parent.kind === 248 && ts.isExternalOrCommonJsModule(parent)) {
error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
}
}
@@ -20504,6 +20747,11 @@ var ts;
checkExpressionCached(node.initializer);
}
}
+ if (node.kind === 163) {
+ if (node.propertyName && node.propertyName.kind === 136) {
+ checkComputedPropertyName(node.propertyName);
+ }
+ }
if (ts.isBindingPattern(node.name)) {
ts.forEach(node.name.elements, checkSourceElement);
}
@@ -20862,6 +21110,7 @@ var ts;
var firstDefaultClause;
var hasDuplicateDefaultClause = false;
var expressionType = checkExpression(node.expression);
+ var expressionTypeIsStringLike = someConstituentTypeHasKind(expressionType, 258);
ts.forEach(node.caseBlock.clauses, function (clause) {
if (clause.kind === 242 && !hasDuplicateDefaultClause) {
if (firstDefaultClause === undefined) {
@@ -20878,6 +21127,9 @@ var ts;
if (produceDiagnostics && clause.kind === 241) {
var caseClause = clause;
var caseType = checkExpression(caseClause.expression);
+ if (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, 258)) {
+ return;
+ }
if (!isTypeAssignableTo(expressionType, caseType)) {
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, undefined);
}
@@ -21285,11 +21537,14 @@ var ts;
var enumIsConst = ts.isConst(node);
for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
var member = _a[_i];
- if (member.name.kind === 136) {
+ if (isComputedNonLiteralName(member.name)) {
error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
- else if (isNumericLiteralName(member.name.text)) {
- error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ else {
+ var text = getTextOfPropertyName(member.name);
+ if (isNumericLiteralName(text)) {
+ error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ }
}
var previousEnumMemberIsNonConstant = autoValue === undefined;
var initializer = member.initializer;
@@ -21987,8 +22242,10 @@ var ts;
function checkSourceFileWorker(node) {
var links = getNodeLinks(node);
if (!(links.flags & 1)) {
- if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) {
- return;
+ if (compilerOptions.skipDefaultLibCheck) {
+ if (node.hasNoDefaultLib) {
+ return;
+ }
}
checkGrammarSourceFile(node);
emitExtends = false;
@@ -21997,7 +22254,7 @@ var ts;
potentialThisCollisions.length = 0;
ts.forEach(node.statements, checkSourceElement);
checkFunctionAndClassExpressionBodies(node);
- if (ts.isExternalModule(node)) {
+ if (ts.isExternalOrCommonJsModule(node)) {
checkExternalModuleExports(node);
}
if (potentialThisCollisions.length) {
@@ -22075,7 +22332,7 @@ var ts;
}
switch (location.kind) {
case 248:
- if (!ts.isExternalModule(location)) {
+ if (!ts.isExternalOrCommonJsModule(location)) {
break;
}
case 218:
@@ -22634,15 +22891,24 @@ var ts;
getReferencedValueDeclaration: getReferencedValueDeclaration,
getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
isOptionalParameter: isOptionalParameter,
- isArgumentsLocalBinding: isArgumentsLocalBinding
+ isArgumentsLocalBinding: isArgumentsLocalBinding,
+ getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration
};
}
+ function getExternalModuleFileFromDeclaration(declaration) {
+ var specifier = ts.getExternalModuleName(declaration);
+ var moduleSymbol = getSymbolAtLocation(specifier);
+ if (!moduleSymbol) {
+ return undefined;
+ }
+ return ts.getDeclarationOfKind(moduleSymbol, 248);
+ }
function initializeTypeChecker() {
ts.forEach(host.getSourceFiles(), function (file) {
ts.bindSourceFile(file, compilerOptions);
});
ts.forEach(host.getSourceFiles(), function (file) {
- if (!ts.isExternalModule(file)) {
+ if (!ts.isExternalOrCommonJsModule(file)) {
mergeSymbolTable(globals, file.locals);
}
});
@@ -23319,7 +23585,7 @@ var ts;
}
}
function checkGrammarForNonSymbolComputedProperty(node, message) {
- if (node.kind === 136 && !ts.isWellKnownSymbolSyntactically(node.expression)) {
+ if (ts.isDynamicName(node)) {
return grammarErrorOnNode(node, message);
}
}
@@ -23633,11 +23899,15 @@ var ts;
var writeTextOfNode;
var writer = createAndSetNewTextWriterWithSymbolWriter();
var enclosingDeclaration;
- var currentSourceFile;
+ var currentText;
+ var currentLineMap;
+ var currentIdentifiers;
+ var isCurrentFileExternalModule;
var reportedDeclarationError = false;
var errorNameNode;
var emitJsDocComments = compilerOptions.removeComments ? function (declaration) { } : writeJsDocComments;
var emit = compilerOptions.stripInternal ? stripInternal : emitNode;
+ var noDeclare = !root;
var moduleElementDeclarationEmitInfo = [];
var asynchronousSubModuleDeclarationEmitInfo;
var referencePathsOutput = "";
@@ -23673,21 +23943,53 @@ var ts;
}
else {
var emittedReferencedFiles = [];
+ var prevModuleElementDeclarationEmitInfo = [];
ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
+ if (!ts.isDeclarationFile(sourceFile)) {
if (!compilerOptions.noResolve) {
ts.forEach(sourceFile.referencedFiles, function (fileReference) {
var referencedFile = ts.tryResolveScriptReference(host, sourceFile, fileReference);
- if (referencedFile && (ts.isExternalModuleOrDeclarationFile(referencedFile) &&
+ if (referencedFile && (ts.isDeclarationFile(referencedFile) &&
!ts.contains(emittedReferencedFiles, referencedFile))) {
writeReferencePath(referencedFile);
emittedReferencedFiles.push(referencedFile);
}
});
}
+ }
+ if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
+ noDeclare = false;
+ emitSourceFile(sourceFile);
+ }
+ else if (ts.isExternalModule(sourceFile)) {
+ noDeclare = true;
+ write("declare module \"" + ts.getResolvedExternalModuleName(host, sourceFile) + "\" {");
+ writeLine();
+ increaseIndent();
emitSourceFile(sourceFile);
+ decreaseIndent();
+ write("}");
+ writeLine();
+ if (moduleElementDeclarationEmitInfo.length) {
+ var oldWriter = writer;
+ ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) {
+ if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
+ ts.Debug.assert(aliasEmitInfo.node.kind === 222);
+ createAndSetNewTextWriterWithSymbolWriter();
+ ts.Debug.assert(aliasEmitInfo.indent === 1);
+ increaseIndent();
+ writeImportDeclaration(aliasEmitInfo.node);
+ aliasEmitInfo.asynchronousOutput = writer.getText();
+ decreaseIndent();
+ }
+ });
+ setWriter(oldWriter);
+ }
+ prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
+ moduleElementDeclarationEmitInfo = [];
}
});
+ moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo);
}
return {
reportedDeclarationError: reportedDeclarationError,
@@ -23696,13 +23998,12 @@ var ts;
referencePathsOutput: referencePathsOutput
};
function hasInternalAnnotation(range) {
- var text = currentSourceFile.text;
- var comment = text.substring(range.pos, range.end);
+ var comment = currentText.substring(range.pos, range.end);
return comment.indexOf("@internal") >= 0;
}
function stripInternal(node) {
if (node) {
- var leadingCommentRanges = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
+ var leadingCommentRanges = ts.getLeadingCommentRanges(currentText, node.pos);
if (ts.forEach(leadingCommentRanges, hasInternalAnnotation)) {
return;
}
@@ -23783,7 +24084,7 @@ var ts;
var errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
if (errorInfo) {
if (errorInfo.typeName) {
- diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
+ diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNodeFromSourceText(currentText, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
}
else {
diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
@@ -23847,9 +24148,9 @@ var ts;
}
function writeJsDocComments(declaration) {
if (declaration) {
- var jsDocComments = ts.getJsDocComments(declaration, currentSourceFile);
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, declaration, jsDocComments);
- ts.emitComments(currentSourceFile, writer, jsDocComments, true, newLine, ts.writeCommentRange);
+ var jsDocComments = ts.getJsDocCommentsFromText(declaration, currentText);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
+ ts.emitComments(currentText, currentLineMap, writer, jsDocComments, true, newLine, ts.writeCommentRange);
}
}
function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type, getSymbolAccessibilityDiagnostic) {
@@ -23866,7 +24167,7 @@ var ts;
case 103:
case 97:
case 9:
- return writeTextOfNode(currentSourceFile, type);
+ return writeTextOfNode(currentText, type);
case 188:
return emitExpressionWithTypeArguments(type);
case 151:
@@ -23897,14 +24198,14 @@ var ts;
}
function writeEntityName(entityName) {
if (entityName.kind === 69) {
- writeTextOfNode(currentSourceFile, entityName);
+ writeTextOfNode(currentText, entityName);
}
else {
var left = entityName.kind === 135 ? entityName.left : entityName.expression;
var right = entityName.kind === 135 ? entityName.right : entityName.name;
writeEntityName(left);
write(".");
- writeTextOfNode(currentSourceFile, right);
+ writeTextOfNode(currentText, right);
}
}
function emitEntityName(entityName) {
@@ -23932,7 +24233,7 @@ var ts;
}
}
function emitTypePredicate(type) {
- writeTextOfNode(currentSourceFile, type.parameterName);
+ writeTextOfNode(currentText, type.parameterName);
write(" is ");
emitType(type.type);
}
@@ -23972,20 +24273,23 @@ var ts;
}
}
function emitSourceFile(node) {
- currentSourceFile = node;
+ currentText = node.text;
+ currentLineMap = ts.getLineStarts(node);
+ currentIdentifiers = node.identifiers;
+ isCurrentFileExternalModule = ts.isExternalModule(node);
enclosingDeclaration = node;
- ts.emitDetachedComments(currentSourceFile, writer, ts.writeCommentRange, node, newLine, true);
+ ts.emitDetachedComments(currentText, currentLineMap, writer, ts.writeCommentRange, node, newLine, true);
emitLines(node.statements);
}
function getExportDefaultTempVariableName() {
var baseName = "_default";
- if (!ts.hasProperty(currentSourceFile.identifiers, baseName)) {
+ if (!ts.hasProperty(currentIdentifiers, baseName)) {
return baseName;
}
var count = 0;
while (true) {
var name_19 = baseName + "_" + (++count);
- if (!ts.hasProperty(currentSourceFile.identifiers, name_19)) {
+ if (!ts.hasProperty(currentIdentifiers, name_19)) {
return name_19;
}
}
@@ -23993,7 +24297,7 @@ var ts;
function emitExportAssignment(node) {
if (node.expression.kind === 69) {
write(node.isExportEquals ? "export = " : "export default ");
- writeTextOfNode(currentSourceFile, node.expression);
+ writeTextOfNode(currentText, node.expression);
}
else {
var tempVarName = getExportDefaultTempVariableName();
@@ -24028,7 +24332,7 @@ var ts;
writeModuleElement(node);
}
else if (node.kind === 221 ||
- (node.parent.kind === 248 && ts.isExternalModule(currentSourceFile))) {
+ (node.parent.kind === 248 && isCurrentFileExternalModule)) {
var isVisible;
if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== 248) {
asynchronousSubModuleDeclarationEmitInfo.push({
@@ -24080,14 +24384,14 @@ var ts;
}
}
function emitModuleElementDeclarationFlags(node) {
- if (node.parent === currentSourceFile) {
+ if (node.parent.kind === 248) {
if (node.flags & 2) {
write("export ");
}
if (node.flags & 512) {
write("default ");
}
- else if (node.kind !== 215) {
+ else if (node.kind !== 215 && !noDeclare) {
write("declare ");
}
}
@@ -24112,7 +24416,7 @@ var ts;
write("export ");
}
write("import ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
write(" = ");
if (ts.isInternalModuleImportEqualsDeclaration(node)) {
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError);
@@ -24120,7 +24424,7 @@ var ts;
}
else {
write("require(");
- writeTextOfNode(currentSourceFile, ts.getExternalModuleImportEqualsDeclarationExpression(node));
+ writeTextOfNode(currentText, ts.getExternalModuleImportEqualsDeclarationExpression(node));
write(");");
}
writer.writeLine();
@@ -24154,7 +24458,7 @@ var ts;
if (node.importClause) {
var currentWriterPos = writer.getTextPos();
if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
- writeTextOfNode(currentSourceFile, node.importClause.name);
+ writeTextOfNode(currentText, node.importClause.name);
}
if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
if (currentWriterPos !== writer.getTextPos()) {
@@ -24162,7 +24466,7 @@ var ts;
}
if (node.importClause.namedBindings.kind === 224) {
write("* as ");
- writeTextOfNode(currentSourceFile, node.importClause.namedBindings.name);
+ writeTextOfNode(currentText, node.importClause.namedBindings.name);
}
else {
write("{ ");
@@ -24172,16 +24476,28 @@ var ts;
}
write(" from ");
}
- writeTextOfNode(currentSourceFile, node.moduleSpecifier);
+ emitExternalModuleSpecifier(node.moduleSpecifier);
write(";");
writer.writeLine();
}
+ function emitExternalModuleSpecifier(moduleSpecifier) {
+ if (moduleSpecifier.kind === 9 && (!root) && (compilerOptions.out || compilerOptions.outFile)) {
+ var moduleName = ts.getExternalModuleNameFromDeclaration(host, resolver, moduleSpecifier.parent);
+ if (moduleName) {
+ write("\"");
+ write(moduleName);
+ write("\"");
+ return;
+ }
+ }
+ writeTextOfNode(currentText, moduleSpecifier);
+ }
function emitImportOrExportSpecifier(node) {
if (node.propertyName) {
- writeTextOfNode(currentSourceFile, node.propertyName);
+ writeTextOfNode(currentText, node.propertyName);
write(" as ");
}
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
function emitExportSpecifier(node) {
emitImportOrExportSpecifier(node);
@@ -24201,7 +24517,7 @@ var ts;
}
if (node.moduleSpecifier) {
write(" from ");
- writeTextOfNode(currentSourceFile, node.moduleSpecifier);
+ emitExternalModuleSpecifier(node.moduleSpecifier);
}
write(";");
writer.writeLine();
@@ -24215,11 +24531,11 @@ var ts;
else {
write("module ");
}
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
while (node.body.kind !== 219) {
node = node.body;
write(".");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
@@ -24238,7 +24554,7 @@ var ts;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("type ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
emitTypeParameters(node.typeParameters);
write(" = ");
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
@@ -24260,7 +24576,7 @@ var ts;
write("const ");
}
write("enum ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
write(" {");
writeLine();
increaseIndent();
@@ -24271,7 +24587,7 @@ var ts;
}
function emitEnumMemberDeclaration(node) {
emitJsDocComments(node);
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var enumMemberValue = resolver.getConstantValue(node);
if (enumMemberValue !== undefined) {
write(" = ");
@@ -24288,7 +24604,7 @@ var ts;
increaseIndent();
emitJsDocComments(node);
decreaseIndent();
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (node.constraint && !isPrivateMethodTypeParameter(node)) {
write(" extends ");
if (node.parent.kind === 152 ||
@@ -24398,7 +24714,7 @@ var ts;
write("abstract ");
}
write("class ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitTypeParameters(node.typeParameters);
@@ -24421,7 +24737,7 @@ var ts;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("interface ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitTypeParameters(node.typeParameters);
@@ -24451,7 +24767,7 @@ var ts;
emitBindingPattern(node.name);
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if ((node.kind === 141 || node.kind === 140) && ts.hasQuestionToken(node)) {
write("?");
}
@@ -24525,7 +24841,7 @@ var ts;
emitBindingPattern(bindingElement.name);
}
else {
- writeTextOfNode(currentSourceFile, bindingElement.name);
+ writeTextOfNode(currentText, bindingElement.name);
writeTypeOfDeclaration(bindingElement, undefined, getBindingElementTypeVisibilityError);
}
}
@@ -24566,7 +24882,7 @@ var ts;
emitJsDocComments(accessors.getAccessor);
emitJsDocComments(accessors.setAccessor);
emitClassMemberDeclarationFlags(node);
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (!(node.flags & 16)) {
accessorWithTypeAnnotation = node;
var type = getTypeAnnotationFromAccessor(node);
@@ -24647,13 +24963,13 @@ var ts;
}
if (node.kind === 213) {
write("function ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
else if (node.kind === 144) {
write("constructor");
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (ts.hasQuestionToken(node)) {
write("?");
}
@@ -24766,7 +25082,7 @@ var ts;
emitBindingPattern(node.name);
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
if (resolver.isOptionalParameter(node)) {
write("?");
@@ -24865,7 +25181,7 @@ var ts;
}
else if (bindingElement.kind === 163) {
if (bindingElement.propertyName) {
- writeTextOfNode(currentSourceFile, bindingElement.propertyName);
+ writeTextOfNode(currentText, bindingElement.propertyName);
write(": ");
}
if (bindingElement.name) {
@@ -24877,7 +25193,7 @@ var ts;
if (bindingElement.dotDotDotToken) {
write("...");
}
- writeTextOfNode(currentSourceFile, bindingElement.name);
+ writeTextOfNode(currentText, bindingElement.name);
}
}
}
@@ -24960,6 +25276,18 @@ var ts;
return ts.isExternalModule(sourceFile) || ts.isDeclarationFile(sourceFile);
}
ts.isExternalModuleOrDeclarationFile = isExternalModuleOrDeclarationFile;
+ function getResolvedExternalModuleName(host, file) {
+ return file.moduleName || ts.getExternalModuleNameFromPath(host, file.fileName);
+ }
+ ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
+ function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
+ var file = resolver.getExternalModuleFileFromDeclaration(declaration);
+ if (!file || ts.isDeclarationFile(file)) {
+ return undefined;
+ }
+ return getResolvedExternalModuleName(host, file);
+ }
+ ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
var entities = {
"quot": 0x0022,
"amp": 0x0026,
@@ -25229,15 +25557,19 @@ var ts;
var newLine = host.getNewLine();
var jsxDesugaring = host.getCompilerOptions().jsx !== 1;
var shouldEmitJsx = function (s) { return (s.languageVariant === 1 && !jsxDesugaring); };
+ var outFile = compilerOptions.outFile || compilerOptions.out;
+ var emitJavaScript = createFileEmitter();
if (targetSourceFile === undefined) {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
- var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
- emitFile(jsFilePath, sourceFile);
- }
- });
- if (compilerOptions.outFile || compilerOptions.out) {
- emitFile(compilerOptions.outFile || compilerOptions.out);
+ if (outFile) {
+ emitFile(outFile);
+ }
+ else {
+ ts.forEach(host.getSourceFiles(), function (sourceFile) {
+ if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
+ var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
+ emitFile(jsFilePath, sourceFile);
+ }
+ });
}
}
else {
@@ -25245,8 +25577,8 @@ var ts;
var jsFilePath = ts.getOwnEmitOutputFilePath(targetSourceFile, host, shouldEmitJsx(targetSourceFile) ? ".jsx" : ".js");
emitFile(jsFilePath, targetSourceFile);
}
- else if (!ts.isDeclarationFile(targetSourceFile) && (compilerOptions.outFile || compilerOptions.out)) {
- emitFile(compilerOptions.outFile || compilerOptions.out);
+ else if (!ts.isDeclarationFile(targetSourceFile) && outFile) {
+ emitFile(outFile);
}
}
diagnostics = ts.sortAndDeduplicateDiagnostics(diagnostics);
@@ -25296,20 +25628,26 @@ var ts;
}
}
}
- function emitJavaScript(jsFilePath, root) {
+ function createFileEmitter() {
var writer = ts.createTextWriter(newLine);
var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent;
var currentSourceFile;
+ var currentText;
+ var currentLineMap;
+ var currentFileIdentifiers;
+ var renamedDependencies;
+ var isEs6Module;
+ var isCurrentFileExternalModule;
var exportFunctionForFile;
- var generatedNameSet = {};
- var nodeToGeneratedName = [];
+ var generatedNameSet;
+ var nodeToGeneratedName;
var computedPropertyNamesToGeneratedNames;
var convertedLoopState;
- var extendsEmitted = false;
- var decorateEmitted = false;
- var paramEmitted = false;
- var awaiterEmitted = false;
- var tempFlags = 0;
+ var extendsEmitted;
+ var decorateEmitted;
+ var paramEmitted;
+ var awaiterEmitted;
+ var tempFlags;
var tempVariables;
var tempParameters;
var externalImports;
@@ -25326,6 +25664,7 @@ var ts;
var scopeEmitStart = function (scopeDeclaration, scopeName) { };
var scopeEmitEnd = function () { };
var sourceMapData;
+ var root;
var emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos) { } : emitLeadingCommentsOfPositionWorker;
var moduleEmitDelegates = (_a = {},
_a[5] = emitES6Module,
@@ -25335,30 +25674,75 @@ var ts;
_a[1] = emitCommonJSModule,
_a
);
- if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
- initializeEmitterWithSourceMaps();
- }
- if (root) {
- emitSourceFile(root);
- }
- else {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!isExternalModuleOrDeclarationFile(sourceFile)) {
- emitSourceFile(sourceFile);
+ var bundleEmitDelegates = (_b = {},
+ _b[5] = function () { },
+ _b[2] = emitAMDModule,
+ _b[4] = emitSystemModule,
+ _b[3] = function () { },
+ _b[1] = function () { },
+ _b
+ );
+ return doEmit;
+ function doEmit(jsFilePath, rootFile) {
+ writer.reset();
+ currentSourceFile = undefined;
+ currentText = undefined;
+ currentLineMap = undefined;
+ exportFunctionForFile = undefined;
+ generatedNameSet = {};
+ nodeToGeneratedName = [];
+ computedPropertyNamesToGeneratedNames = undefined;
+ convertedLoopState = undefined;
+ extendsEmitted = false;
+ decorateEmitted = false;
+ paramEmitted = false;
+ awaiterEmitted = false;
+ tempFlags = 0;
+ tempVariables = undefined;
+ tempParameters = undefined;
+ externalImports = undefined;
+ exportSpecifiers = undefined;
+ exportEquals = undefined;
+ hasExportStars = undefined;
+ detachedCommentsInfo = undefined;
+ sourceMapData = undefined;
+ isEs6Module = false;
+ renamedDependencies = undefined;
+ isCurrentFileExternalModule = false;
+ root = rootFile;
+ if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
+ initializeEmitterWithSourceMaps(jsFilePath, root);
+ }
+ if (root) {
+ emitSourceFile(root);
+ }
+ else {
+ if (modulekind) {
+ ts.forEach(host.getSourceFiles(), emitEmitHelpers);
}
- });
+ ts.forEach(host.getSourceFiles(), function (sourceFile) {
+ if ((!isExternalModuleOrDeclarationFile(sourceFile)) || (modulekind && ts.isExternalModule(sourceFile))) {
+ emitSourceFile(sourceFile);
+ }
+ });
+ }
+ writeLine();
+ writeEmittedFiles(writer.getText(), jsFilePath, compilerOptions.emitBOM);
}
- writeLine();
- writeEmittedFiles(writer.getText(), compilerOptions.emitBOM);
- return;
function emitSourceFile(sourceFile) {
currentSourceFile = sourceFile;
+ currentText = sourceFile.text;
+ currentLineMap = ts.getLineStarts(sourceFile);
exportFunctionForFile = undefined;
+ isEs6Module = sourceFile.symbol && sourceFile.symbol.exports && !!sourceFile.symbol.exports["___esModule"];
+ renamedDependencies = sourceFile.renamedDependencies;
+ currentFileIdentifiers = sourceFile.identifiers;
+ isCurrentFileExternalModule = ts.isExternalModule(sourceFile);
emit(sourceFile);
}
function isUniqueName(name) {
return !resolver.hasGlobalName(name) &&
- !ts.hasProperty(currentSourceFile.identifiers, name) &&
+ !ts.hasProperty(currentFileIdentifiers, name) &&
!ts.hasProperty(generatedNameSet, name);
}
function makeTempVariableName(flags) {
@@ -25431,7 +25815,7 @@ var ts;
var id = ts.getNodeId(node);
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = ts.unescapeIdentifier(generateNameForNode(node)));
}
- function initializeEmitterWithSourceMaps() {
+ function initializeEmitterWithSourceMaps(jsFilePath, root) {
var sourceMapDir;
var sourceMapSourceIndex = -1;
var sourceMapNameIndexMap = {};
@@ -25500,7 +25884,7 @@ var ts;
}
}
function recordSourceMapSpan(pos) {
- var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSourceFile, pos);
+ var sourceLinePos = ts.computeLineAndCharacterOfPosition(currentLineMap, pos);
sourceLinePos.line++;
sourceLinePos.character++;
var emittedLine = writer.getLine();
@@ -25528,13 +25912,13 @@ var ts;
}
}
function recordEmitNodeStartSpan(node) {
- recordSourceMapSpan(ts.skipTrivia(currentSourceFile.text, node.pos));
+ recordSourceMapSpan(ts.skipTrivia(currentText, node.pos));
}
function recordEmitNodeEndSpan(node) {
recordSourceMapSpan(node.end);
}
function writeTextWithSpanRecord(tokenKind, startPos, emitFn) {
- var tokenStartPos = ts.skipTrivia(currentSourceFile.text, startPos);
+ var tokenStartPos = ts.skipTrivia(currentText, startPos);
recordSourceMapSpan(tokenStartPos);
var tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
recordSourceMapSpan(tokenEndPos);
@@ -25604,9 +25988,9 @@ var ts;
sourceMapNameIndices.pop();
}
;
- function writeCommentRangeWithMap(curentSourceFile, writer, comment, newLine) {
+ function writeCommentRangeWithMap(currentText, currentLineMap, writer, comment, newLine) {
recordSourceMapSpan(comment.pos);
- ts.writeCommentRange(currentSourceFile, writer, comment, newLine);
+ ts.writeCommentRange(currentText, currentLineMap, writer, comment, newLine);
recordSourceMapSpan(comment.end);
}
function serializeSourceMapContents(version, file, sourceRoot, sources, names, mappings, sourcesContent) {
@@ -25636,7 +26020,7 @@ var ts;
return output;
}
}
- function writeJavaScriptAndSourceMapFile(emitOutput, writeByteOrderMark) {
+ function writeJavaScriptAndSourceMapFile(emitOutput, jsFilePath, writeByteOrderMark) {
encodeLastRecordedSourceMapSpan();
var sourceMapText = serializeSourceMapContents(3, sourceMapData.sourceMapFile, sourceMapData.sourceMapSourceRoot, sourceMapData.sourceMapSources, sourceMapData.sourceMapNames, sourceMapData.sourceMapMappings, sourceMapData.sourceMapSourcesContent);
sourceMapDataList.push(sourceMapData);
@@ -25649,7 +26033,7 @@ var ts;
ts.writeFile(host, diagnostics, sourceMapData.sourceMapFilePath, sourceMapText, false);
sourceMapUrl = "//# sourceMappingURL=" + sourceMapData.jsSourceMappingURL;
}
- writeJavaScriptFile(emitOutput + sourceMapUrl, writeByteOrderMark);
+ writeJavaScriptFile(emitOutput + sourceMapUrl, jsFilePath, writeByteOrderMark);
}
var sourceMapJsFile = ts.getBaseFileName(ts.normalizeSlashes(jsFilePath));
sourceMapData = {
@@ -25712,7 +26096,7 @@ var ts;
scopeEmitEnd = recordScopeNameEnd;
writeComment = writeCommentRangeWithMap;
}
- function writeJavaScriptFile(emitOutput, writeByteOrderMark) {
+ function writeJavaScriptFile(emitOutput, jsFilePath, writeByteOrderMark) {
ts.writeFile(host, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
}
function createTempVariable(flags) {
@@ -25882,7 +26266,7 @@ var ts;
return getQuotedEscapedLiteralText("\"", node.text, "\"");
}
if (node.parent) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+ return ts.getTextOfNodeFromSourceText(currentText, node);
}
switch (node.kind) {
case 9:
@@ -25904,7 +26288,7 @@ var ts;
return leftQuote + ts.escapeNonAsciiCharacters(ts.escapeString(text)) + rightQuote;
}
function emitDownlevelRawTemplateLiteral(node) {
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+ var text = ts.getTextOfNodeFromSourceText(currentText, node);
var isLast = node.kind === 11 || node.kind === 14;
text = text.substring(1, text.length - (isLast ? 1 : 2));
text = text.replace(/\r\n?/g, "\n");
@@ -26234,7 +26618,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
write("\"");
}
@@ -26330,7 +26714,7 @@ var ts;
else if (declaration.kind === 226) {
write(getGeneratedNameForNode(declaration.parent.parent.parent));
var name_24 = declaration.propertyName || declaration.name;
- var identifier = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, name_24);
+ var identifier = ts.getTextOfNodeFromSourceText(currentText, name_24);
if (languageVersion === 0 && identifier === "default") {
write("[\"default\"]");
}
@@ -26354,7 +26738,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
}
function isNameOfNestedRedeclaration(node) {
@@ -26391,7 +26775,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
}
function emitThis(node) {
@@ -26758,8 +27142,8 @@ var ts;
return container && container.kind !== 248;
}
function emitShorthandPropertyAssignment(node) {
- writeTextOfNode(currentSourceFile, node.name);
- if (languageVersion < 2 || isNamespaceExportReference(node.name)) {
+ writeTextOfNode(currentText, node.name);
+ if (modulekind !== 5 || isNamespaceExportReference(node.name)) {
write(": ");
emit(node.name);
}
@@ -26809,10 +27193,10 @@ var ts;
}
emit(node.expression);
var indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken);
- var shouldEmitSpace;
+ var shouldEmitSpace = false;
if (!indentedBeforeDot) {
if (node.expression.kind === 8) {
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node.expression);
+ var text = ts.getTextOfNodeFromSourceText(currentText, node.expression);
shouldEmitSpace = text.indexOf(ts.tokenToString(21)) < 0;
}
else {
@@ -27818,16 +28202,16 @@ var ts;
emitToken(16, node.clauses.end);
}
function nodeStartPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node1.pos)) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node1.pos)) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
}
function nodeEndPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, node2.end);
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, node2.end);
}
function nodeEndIsOnSameLineAsNodeStart(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
}
function emitCaseOrDefaultClause(node) {
if (node.kind === 241) {
@@ -27932,7 +28316,7 @@ var ts;
if (node.parent.kind === 248) {
ts.Debug.assert(!!(node.flags & 512) || node.kind === 227);
if (modulekind === 1 || modulekind === 2 || modulekind === 3) {
- if (!currentSourceFile.symbol.exports["___esModule"]) {
+ if (!isEs6Module) {
if (languageVersion === 1) {
write("Object.defineProperty(exports, \"__esModule\", { value: true });");
writeLine();
@@ -28095,12 +28479,18 @@ var ts;
return node;
}
function createPropertyAccessForDestructuringProperty(object, propName) {
- var syntheticName = ts.createSynthesizedNode(propName.kind);
- syntheticName.text = propName.text;
- if (syntheticName.kind !== 69) {
- return createElementAccessExpression(object, syntheticName);
+ var index;
+ var nameIsComputed = propName.kind === 136;
+ if (nameIsComputed) {
+ index = ensureIdentifier(propName.expression, false);
}
- return createPropertyAccessExpression(object, syntheticName);
+ else {
+ index = ts.createSynthesizedNode(propName.kind);
+ index.text = propName.text;
+ }
+ return !nameIsComputed && index.kind === 69
+ ? createPropertyAccessExpression(object, index)
+ : createElementAccessExpression(object, index);
}
function createSliceCall(value, sliceIndex) {
var call = ts.createSynthesizedNode(168);
@@ -28514,7 +28904,6 @@ var ts;
var promiseConstructor = ts.getEntityNameFromTypeNode(node.type);
var isArrowFunction = node.kind === 174;
var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 4096) !== 0;
- var args;
if (!isArrowFunction) {
write(" {");
increaseIndent();
@@ -29688,8 +30077,8 @@ var ts;
}
}
function tryRenameExternalModule(moduleName) {
- if (currentSourceFile.renamedDependencies && ts.hasProperty(currentSourceFile.renamedDependencies, moduleName.text)) {
- return "\"" + currentSourceFile.renamedDependencies[moduleName.text] + "\"";
+ if (renamedDependencies && ts.hasProperty(renamedDependencies, moduleName.text)) {
+ return "\"" + renamedDependencies[moduleName.text] + "\"";
}
return undefined;
}
@@ -29829,7 +30218,7 @@ var ts;
return;
}
if (resolver.isReferencedAliasDeclaration(node) ||
- (!ts.isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
+ (!isCurrentFileExternalModule && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
emitLeadingComments(node);
emitStart(node);
var variableDeclarationIsHoisted = shouldHoistVariable(node, true);
@@ -30041,7 +30430,7 @@ var ts;
function getLocalNameForExternalImport(node) {
var namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, namespaceDeclaration.name);
+ return ts.getTextOfNodeFromSourceText(currentText, namespaceDeclaration.name);
}
if (node.kind === 222 && node.importClause) {
return getGeneratedNameForNode(node);
@@ -30314,7 +30703,7 @@ var ts;
ts.getEnclosingBlockScopeContainer(node).kind === 248;
}
function isCurrentFileSystemExternalModule() {
- return modulekind === 4 && ts.isExternalModule(currentSourceFile);
+ return modulekind === 4 && isCurrentFileExternalModule;
}
function emitSystemModuleBody(node, dependencyGroups, startIndex) {
emitVariableDeclarationsForImports();
@@ -30427,15 +30816,19 @@ var ts;
writeLine();
write("}");
}
- function emitSystemModule(node) {
+ function writeModuleName(node, emitRelativePathAsModuleName) {
+ var moduleName = node.moduleName;
+ if (moduleName || (emitRelativePathAsModuleName && (moduleName = getResolvedExternalModuleName(host, node)))) {
+ write("\"" + moduleName + "\", ");
+ }
+ }
+ function emitSystemModule(node, emitRelativePathAsModuleName) {
collectExternalModuleInfo(node);
ts.Debug.assert(!exportFunctionForFile);
exportFunctionForFile = makeUniqueName("exports");
writeLine();
write("System.register(");
- if (node.moduleName) {
- write("\"" + node.moduleName + "\", ");
- }
+ writeModuleName(node, emitRelativePathAsModuleName);
write("[");
var groupIndices = {};
var dependencyGroups = [];
@@ -30453,6 +30846,12 @@ var ts;
if (i !== 0) {
write(", ");
}
+ if (emitRelativePathAsModuleName) {
+ var name_30 = getExternalModuleNameFromDeclaration(host, resolver, externalImports[i]);
+ if (name_30) {
+ text = "\"" + name_30 + "\"";
+ }
+ }
write(text);
}
write("], function(" + exportFunctionForFile + ") {");
@@ -30466,7 +30865,7 @@ var ts;
writeLine();
write("});");
}
- function getAMDDependencyNames(node, includeNonAmdDependencies) {
+ function getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
var aliasedModuleNames = [];
var unaliasedModuleNames = [];
var importAliasNames = [];
@@ -30483,6 +30882,12 @@ var ts;
for (var _c = 0, externalImports_4 = externalImports; _c < externalImports_4.length; _c++) {
var importNode = externalImports_4[_c];
var externalModuleName = getExternalModuleNameText(importNode);
+ if (emitRelativePathAsModuleName) {
+ var name_31 = getExternalModuleNameFromDeclaration(host, resolver, importNode);
+ if (name_31) {
+ externalModuleName = "\"" + name_31 + "\"";
+ }
+ }
var importAliasName = getLocalNameForExternalImport(importNode);
if (includeNonAmdDependencies && importAliasName) {
aliasedModuleNames.push(externalModuleName);
@@ -30494,8 +30899,8 @@ var ts;
}
return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
}
- function emitAMDDependencies(node, includeNonAmdDependencies) {
- var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies);
+ function emitAMDDependencies(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
+ var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName);
emitAMDDependencyList(dependencyNames);
write(", ");
emitAMDFactoryHeader(dependencyNames);
@@ -30522,15 +30927,13 @@ var ts;
}
write(") {");
}
- function emitAMDModule(node) {
+ function emitAMDModule(node, emitRelativePathAsModuleName) {
emitEmitHelpers(node);
collectExternalModuleInfo(node);
writeLine();
write("define(");
- if (node.moduleName) {
- write("\"" + node.moduleName + "\", ");
- }
- emitAMDDependencies(node, true);
+ writeModuleName(node, emitRelativePathAsModuleName);
+ emitAMDDependencies(node, true, emitRelativePathAsModuleName);
increaseIndent();
var startIndex = emitDirectivePrologues(node.statements, true);
emitExportStarHelper();
@@ -30736,8 +31139,13 @@ var ts;
emitShebang();
emitDetachedCommentsAndUpdateCommentsInfo(node);
if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
- var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[1];
- emitModule(node);
+ if (root || (!ts.isExternalModule(node) && compilerOptions.isolatedModules)) {
+ var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[1];
+ emitModule(node);
+ }
+ else {
+ bundleEmitDelegates[modulekind](node, true);
+ }
}
else {
var startIndex = emitDirectivePrologues(node.statements, false);
@@ -30981,7 +31389,7 @@ var ts;
return detachedCommentsInfo !== undefined && ts.lastOrUndefined(detachedCommentsInfo).nodePos === pos;
}
function getLeadingCommentsWithoutDetachedComments() {
- var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
+ var leadingComments = ts.getLeadingCommentRanges(currentText, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
if (detachedCommentsInfo.length - 1) {
detachedCommentsInfo.pop();
}
@@ -30991,10 +31399,10 @@ var ts;
return leadingComments;
}
function isTripleSlashComment(comment) {
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 47 &&
+ if (currentText.charCodeAt(comment.pos + 1) === 47 &&
comment.pos + 2 < comment.end &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 47) {
- var textSubStr = currentSourceFile.text.substring(comment.pos, comment.end);
+ currentText.charCodeAt(comment.pos + 2) === 47) {
+ var textSubStr = currentText.substring(comment.pos, comment.end);
return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ?
true : false;
@@ -31008,7 +31416,7 @@ var ts;
return getLeadingCommentsWithoutDetachedComments();
}
else {
- return ts.getLeadingCommentRangesOfNode(node, currentSourceFile);
+ return ts.getLeadingCommentRangesOfNodeFromText(node, currentText);
}
}
}
@@ -31016,7 +31424,7 @@ var ts;
function getTrailingCommentsToEmit(node) {
if (node.parent) {
if (node.parent.kind === 248 || node.end !== node.parent.end) {
- return ts.getTrailingCommentRanges(currentSourceFile.text, node.end);
+ return ts.getTrailingCommentRanges(currentText, node.end);
}
}
}
@@ -31039,22 +31447,22 @@ var ts;
leadingComments = ts.filter(getLeadingCommentsToEmit(node), isTripleSlashComment);
}
}
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
- ts.emitComments(currentSourceFile, writer, leadingComments, true, newLine, writeComment);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments);
+ ts.emitComments(currentText, currentLineMap, writer, leadingComments, true, newLine, writeComment);
}
function emitTrailingComments(node) {
if (compilerOptions.removeComments) {
return;
}
var trailingComments = getTrailingCommentsToEmit(node);
- ts.emitComments(currentSourceFile, writer, trailingComments, false, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, trailingComments, false, newLine, writeComment);
}
function emitTrailingCommentsOfPosition(pos) {
if (compilerOptions.removeComments) {
return;
}
- var trailingComments = ts.getTrailingCommentRanges(currentSourceFile.text, pos);
- ts.emitComments(currentSourceFile, writer, trailingComments, true, newLine, writeComment);
+ var trailingComments = ts.getTrailingCommentRanges(currentText, pos);
+ ts.emitComments(currentText, currentLineMap, writer, trailingComments, true, newLine, writeComment);
}
function emitLeadingCommentsOfPositionWorker(pos) {
if (compilerOptions.removeComments) {
@@ -31065,13 +31473,13 @@ var ts;
leadingComments = getLeadingCommentsWithoutDetachedComments();
}
else {
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, pos);
+ leadingComments = ts.getLeadingCommentRanges(currentText, pos);
}
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, { pos: pos, end: pos }, leadingComments);
- ts.emitComments(currentSourceFile, writer, leadingComments, true, newLine, writeComment);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments);
+ ts.emitComments(currentText, currentLineMap, writer, leadingComments, true, newLine, writeComment);
}
function emitDetachedCommentsAndUpdateCommentsInfo(node) {
- var currentDetachedCommentInfo = ts.emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, compilerOptions.removeComments);
+ var currentDetachedCommentInfo = ts.emitDetachedComments(currentText, currentLineMap, writer, writeComment, node, newLine, compilerOptions.removeComments);
if (currentDetachedCommentInfo) {
if (detachedCommentsInfo) {
detachedCommentsInfo.push(currentDetachedCommentInfo);
@@ -31082,12 +31490,12 @@ var ts;
}
}
function emitShebang() {
- var shebang = ts.getShebang(currentSourceFile.text);
+ var shebang = ts.getShebang(currentText);
if (shebang) {
write(shebang);
}
}
- var _a;
+ var _a, _b;
}
function emitFile(jsFilePath, sourceFile) {
emitJavaScript(jsFilePath, sourceFile);
@@ -31143,11 +31551,11 @@ var ts;
if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
var failedLookupLocations = [];
var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
- var resolvedFileName = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ var resolvedFileName = loadNodeModuleFromFile(ts.supportedJsExtensions, candidate, failedLookupLocations, host);
if (resolvedFileName) {
return { resolvedModule: { resolvedFileName: resolvedFileName }, failedLookupLocations: failedLookupLocations };
}
- resolvedFileName = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ resolvedFileName = loadNodeModuleFromDirectory(ts.supportedJsExtensions, candidate, failedLookupLocations, host);
return resolvedFileName
? { resolvedModule: { resolvedFileName: resolvedFileName }, failedLookupLocations: failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations: failedLookupLocations };
@@ -31157,8 +31565,8 @@ var ts;
}
}
ts.nodeModuleNameResolver = nodeModuleNameResolver;
- function loadNodeModuleFromFile(candidate, failedLookupLocation, host) {
- return ts.forEach(ts.moduleFileExtensions, tryLoad);
+ function loadNodeModuleFromFile(extensions, candidate, failedLookupLocation, host) {
+ return ts.forEach(extensions, tryLoad);
function tryLoad(ext) {
var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
if (host.fileExists(fileName)) {
@@ -31170,7 +31578,7 @@ var ts;
}
}
}
- function loadNodeModuleFromDirectory(candidate, failedLookupLocation, host) {
+ function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, host) {
var packageJsonPath = ts.combinePaths(candidate, "package.json");
if (host.fileExists(packageJsonPath)) {
var jsonContent;
@@ -31182,7 +31590,7 @@ var ts;
jsonContent = { typings: undefined };
}
if (jsonContent.typings) {
- var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
+ var result = loadNodeModuleFromFile(extensions, ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
if (result) {
return result;
}
@@ -31191,7 +31599,7 @@ var ts;
else {
failedLookupLocation.push(packageJsonPath);
}
- return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), failedLookupLocation, host);
+ return loadNodeModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocation, host);
}
function loadModuleFromNodeModules(moduleName, directory, host) {
var failedLookupLocations = [];
@@ -31201,11 +31609,11 @@ var ts;
if (baseName !== "node_modules") {
var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName));
- var result = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ var result = loadNodeModuleFromFile(ts.supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations: failedLookupLocations };
}
- result = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ result = loadNodeModuleFromDirectory(ts.supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations: failedLookupLocations };
}
@@ -31230,9 +31638,10 @@ var ts;
var searchName;
var failedLookupLocations = [];
var referencedSourceFile;
+ var extensions = compilerOptions.allowNonTsExtensions ? ts.supportedJsExtensions : ts.supportedExtensions;
while (true) {
searchName = ts.normalizePath(ts.combinePaths(searchPath, moduleName));
- referencedSourceFile = ts.forEach(ts.supportedExtensions, function (extension) {
+ referencedSourceFile = ts.forEach(extensions, function (extension) {
if (extension === ".tsx" && !compilerOptions.jsx) {
return undefined;
}
@@ -31260,10 +31669,8 @@ var ts;
ts.classicNameResolver = classicNameResolver;
ts.defaultInitCompilerOptions = {
module: 1,
- target: 0,
+ target: 1,
noImplicitAny: false,
- outDir: "built",
- rootDir: ".",
sourceMap: false
};
function createCompilerHost(options, setParentNodes) {
@@ -31621,35 +32028,47 @@ var ts;
if (file.imports) {
return;
}
+ var isJavaScriptFile = ts.isSourceFileJavaScript(file);
var imports;
for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
var node = _a[_i];
- collect(node, true);
+ collect(node, true, false);
}
file.imports = imports || emptyArray;
- function collect(node, allowRelativeModuleNames) {
- switch (node.kind) {
- case 222:
- case 221:
- case 228:
- var moduleNameExpr = ts.getExternalModuleName(node);
- if (!moduleNameExpr || moduleNameExpr.kind !== 9) {
+ return;
+ function collect(node, allowRelativeModuleNames, collectOnlyRequireCalls) {
+ if (!collectOnlyRequireCalls) {
+ switch (node.kind) {
+ case 222:
+ case 221:
+ case 228:
+ var moduleNameExpr = ts.getExternalModuleName(node);
+ if (!moduleNameExpr || moduleNameExpr.kind !== 9) {
+ break;
+ }
+ if (!moduleNameExpr.text) {
+ break;
+ }
+ if (allowRelativeModuleNames || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
+ (imports || (imports = [])).push(moduleNameExpr);
+ }
break;
- }
- if (!moduleNameExpr.text) {
+ case 218:
+ if (node.name.kind === 9 && (node.flags & 4 || ts.isDeclarationFile(file))) {
+ ts.forEachChild(node.body, function (node) {
+ collect(node, false, collectOnlyRequireCalls);
+ });
+ }
break;
- }
- if (allowRelativeModuleNames || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
- (imports || (imports = [])).push(moduleNameExpr);
- }
- break;
- case 218:
- if (node.name.kind === 9 && (node.flags & 4 || ts.isDeclarationFile(file))) {
- ts.forEachChild(node.body, function (node) {
- collect(node, false);
- });
- }
- break;
+ }
+ }
+ if (isJavaScriptFile) {
+ if (ts.isRequireCall(node)) {
+ (imports || (imports = [])).push(node.arguments[0]);
+ }
+ else {
+ ts.forEachChild(node, function (node) { return collect(node, allowRelativeModuleNames, true); });
+ }
}
}
}
@@ -31736,7 +32155,6 @@ var ts;
}
processImportedModules(file, basePath);
if (isDefaultLib) {
- file.isDefaultLib = true;
files.unshift(file);
}
else {
@@ -31809,6 +32227,9 @@ var ts;
commonPathComponents.length = sourcePathComponents.length;
}
});
+ if (!commonPathComponents) {
+ return currentDirectory;
+ }
return ts.getNormalizedPathFromPathComponents(commonPathComponents);
}
function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
@@ -31891,10 +32312,12 @@ var ts;
if (options.module === 5 && languageVersion < 2) {
programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower));
}
+ if (outFile && options.module && !(options.module === 2 || options.module === 4)) {
+ programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile"));
+ }
if (options.outDir ||
options.sourceRoot ||
- (options.mapRoot &&
- (!outFile || firstExternalModuleSourceFile !== undefined))) {
+ options.mapRoot) {
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
}
@@ -32448,10 +32871,10 @@ var ts;
ts.forEach(program.getSourceFiles(), function (sourceFile) {
cancellationToken.throwIfCancellationRequested();
var nameToDeclarations = sourceFile.getNamedDeclarations();
- for (var name_30 in nameToDeclarations) {
- var declarations = ts.getProperty(nameToDeclarations, name_30);
+ for (var name_32 in nameToDeclarations) {
+ var declarations = ts.getProperty(nameToDeclarations, name_32);
if (declarations) {
- var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_30);
+ var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_32);
if (!matches) {
continue;
}
@@ -32462,14 +32885,14 @@ var ts;
if (!containers) {
return undefined;
}
- matches = patternMatcher.getMatches(containers, name_30);
+ matches = patternMatcher.getMatches(containers, name_32);
if (!matches) {
continue;
}
}
var fileName = sourceFile.fileName;
var matchKind = bestMatchKind(matches);
- rawItems.push({ name: name_30, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration });
+ rawItems.push({ name: name_32, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration });
}
}
}
@@ -32797,9 +33220,9 @@ var ts;
case 211:
case 163:
var variableDeclarationNode;
- var name_31;
+ var name_33;
if (node.kind === 163) {
- name_31 = node.name;
+ name_33 = node.name;
variableDeclarationNode = node;
while (variableDeclarationNode && variableDeclarationNode.kind !== 211) {
variableDeclarationNode = variableDeclarationNode.parent;
@@ -32809,16 +33232,16 @@ var ts;
else {
ts.Debug.assert(!ts.isBindingPattern(node.name));
variableDeclarationNode = node;
- name_31 = node.name;
+ name_33 = node.name;
}
if (ts.isConst(variableDeclarationNode)) {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.constElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.constElement);
}
else if (ts.isLet(variableDeclarationNode)) {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.letElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.letElement);
}
else {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.variableElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.variableElement);
}
case 144:
return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement);
@@ -33425,7 +33848,7 @@ var ts;
var resolvedSignature = typeChecker.getResolvedSignature(call, candidates);
cancellationToken.throwIfCancellationRequested();
if (!candidates.length) {
- if (ts.isJavaScript(sourceFile.fileName)) {
+ if (ts.isSourceFileJavaScript(sourceFile)) {
return createJavaScriptSignatureHelpItems(argumentInfo);
}
return undefined;
@@ -34941,9 +35364,9 @@ var ts;
}
Rules.prototype.getRuleName = function (rule) {
var o = this;
- for (var name_32 in o) {
- if (o[name_32] === rule) {
- return name_32;
+ for (var name_34 in o) {
+ if (o[name_34] === rule) {
+ return name_34;
}
}
throw new Error("Unknown rule");
@@ -35318,7 +35741,7 @@ var ts;
function TokenRangeAccess(from, to, except) {
this.tokens = [];
for (var token = from; token <= to; token++) {
- if (except.indexOf(token) < 0) {
+ if (ts.indexOf(except, token) < 0) {
this.tokens.push(token);
}
}
@@ -36706,13 +37129,18 @@ var ts;
];
var jsDocCompletionEntries;
function createNode(kind, pos, end, flags, parent) {
- var node = new (ts.getNodeConstructor(kind))(pos, end);
+ var node = new NodeObject(kind, pos, end);
node.flags = flags;
node.parent = parent;
return node;
}
var NodeObject = (function () {
- function NodeObject() {
+ function NodeObject(kind, pos, end) {
+ this.kind = kind;
+ this.pos = pos;
+ this.end = end;
+ this.flags = 0;
+ this.parent = undefined;
}
NodeObject.prototype.getSourceFile = function () {
return ts.getSourceFileOfNode(this);
@@ -37151,8 +37579,8 @@ var ts;
})();
var SourceFileObject = (function (_super) {
__extends(SourceFileObject, _super);
- function SourceFileObject() {
- _super.apply(this, arguments);
+ function SourceFileObject(kind, pos, end) {
+ _super.call(this, kind, pos, end);
}
SourceFileObject.prototype.update = function (newText, textChangeRange) {
return ts.updateSourceFile(this, newText, textChangeRange);
@@ -37421,6 +37849,9 @@ var ts;
ClassificationTypeNames.typeAliasName = "type alias name";
ClassificationTypeNames.parameterName = "parameter name";
ClassificationTypeNames.docCommentTagName = "doc comment tag name";
+ ClassificationTypeNames.jsxOpenTagName = "jsx open tag name";
+ ClassificationTypeNames.jsxCloseTagName = "jsx close tag name";
+ ClassificationTypeNames.jsxSelfClosingTagName = "jsx self closing tag name";
return ClassificationTypeNames;
})();
ts.ClassificationTypeNames = ClassificationTypeNames;
@@ -37740,8 +38171,9 @@ var ts;
};
}
ts.createDocumentRegistry = createDocumentRegistry;
- function preProcessFile(sourceText, readImportFiles) {
+ function preProcessFile(sourceText, readImportFiles, detectJavaScriptImports) {
if (readImportFiles === void 0) { readImportFiles = true; }
+ if (detectJavaScriptImports === void 0) { detectJavaScriptImports = false; }
var referencedFiles = [];
var importedFiles = [];
var ambientExternalModules;
@@ -37775,62 +38207,70 @@ var ts;
end: pos + importPath.length
});
}
- function processImport() {
- scanner.setText(sourceText);
- var token = scanner.scan();
- while (token !== 1) {
- if (token === 122) {
+ function tryConsumeDeclare() {
+ var token = scanner.getToken();
+ if (token === 122) {
+ token = scanner.scan();
+ if (token === 125) {
token = scanner.scan();
- if (token === 125) {
- token = scanner.scan();
- if (token === 9) {
- recordAmbientExternalModule();
- continue;
- }
+ if (token === 9) {
+ recordAmbientExternalModule();
}
}
- else if (token === 89) {
- token = scanner.scan();
- if (token === 9) {
- recordModuleName();
- continue;
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeImport() {
+ var token = scanner.getToken();
+ if (token === 89) {
+ token = scanner.scan();
+ if (token === 9) {
+ recordModuleName();
+ return true;
+ }
+ else {
+ if (token === 69 || ts.isKeyword(token)) {
+ token = scanner.scan();
+ if (token === 133) {
+ token = scanner.scan();
+ if (token === 9) {
+ recordModuleName();
+ return true;
+ }
+ }
+ else if (token === 56) {
+ if (tryConsumeRequireCall(true)) {
+ return true;
+ }
+ }
+ else if (token === 24) {
+ token = scanner.scan();
+ }
+ else {
+ return true;
+ }
}
- else {
- if (token === 69 || ts.isKeyword(token)) {
+ if (token === 15) {
+ token = scanner.scan();
+ while (token !== 16 && token !== 1) {
+ token = scanner.scan();
+ }
+ if (token === 16) {
token = scanner.scan();
if (token === 133) {
token = scanner.scan();
if (token === 9) {
recordModuleName();
- continue;
}
}
- else if (token === 56) {
- token = scanner.scan();
- if (token === 127) {
- token = scanner.scan();
- if (token === 17) {
- token = scanner.scan();
- if (token === 9) {
- recordModuleName();
- continue;
- }
- }
- }
- }
- else if (token === 24) {
- token = scanner.scan();
- }
- else {
- continue;
- }
}
- if (token === 15) {
+ }
+ else if (token === 37) {
+ token = scanner.scan();
+ if (token === 116) {
token = scanner.scan();
- while (token !== 16) {
- token = scanner.scan();
- }
- if (token === 16) {
+ if (token === 69 || ts.isKeyword(token)) {
token = scanner.scan();
if (token === 133) {
token = scanner.scan();
@@ -37840,41 +38280,22 @@ var ts;
}
}
}
- else if (token === 37) {
- token = scanner.scan();
- if (token === 116) {
- token = scanner.scan();
- if (token === 69 || ts.isKeyword(token)) {
- token = scanner.scan();
- if (token === 133) {
- token = scanner.scan();
- if (token === 9) {
- recordModuleName();
- }
- }
- }
- }
- }
}
}
- else if (token === 82) {
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeExport() {
+ var token = scanner.getToken();
+ if (token === 82) {
+ token = scanner.scan();
+ if (token === 15) {
token = scanner.scan();
- if (token === 15) {
+ while (token !== 16 && token !== 1) {
token = scanner.scan();
- while (token !== 16) {
- token = scanner.scan();
- }
- if (token === 16) {
- token = scanner.scan();
- if (token === 133) {
- token = scanner.scan();
- if (token === 9) {
- recordModuleName();
- }
- }
- }
}
- else if (token === 37) {
+ if (token === 16) {
token = scanner.scan();
if (token === 133) {
token = scanner.scan();
@@ -37883,31 +38304,99 @@ var ts;
}
}
}
- else if (token === 89) {
+ }
+ else if (token === 37) {
+ token = scanner.scan();
+ if (token === 133) {
token = scanner.scan();
- if (token === 69 || ts.isKeyword(token)) {
- token = scanner.scan();
- if (token === 56) {
- token = scanner.scan();
- if (token === 127) {
- token = scanner.scan();
- if (token === 17) {
- token = scanner.scan();
- if (token === 9) {
- recordModuleName();
- }
- }
- }
+ if (token === 9) {
+ recordModuleName();
+ }
+ }
+ }
+ else if (token === 89) {
+ token = scanner.scan();
+ if (token === 69 || ts.isKeyword(token)) {
+ token = scanner.scan();
+ if (token === 56) {
+ if (tryConsumeRequireCall(true)) {
+ return true;
}
}
}
}
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeRequireCall(skipCurrentToken) {
+ var token = skipCurrentToken ? scanner.scan() : scanner.getToken();
+ if (token === 127) {
+ token = scanner.scan();
+ if (token === 17) {
+ token = scanner.scan();
+ if (token === 9) {
+ recordModuleName();
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeDefine() {
+ var token = scanner.getToken();
+ if (token === 69 && scanner.getTokenValue() === "define") {
+ token = scanner.scan();
+ if (token !== 17) {
+ return true;
+ }
+ token = scanner.scan();
+ if (token === 9) {
+ token = scanner.scan();
+ if (token === 24) {
+ token = scanner.scan();
+ }
+ else {
+ return true;
+ }
+ }
+ if (token !== 19) {
+ return true;
+ }
token = scanner.scan();
+ var i = 0;
+ while (token !== 20 && token !== 1) {
+ if (token === 9) {
+ recordModuleName();
+ i++;
+ }
+ token = scanner.scan();
+ }
+ return true;
+ }
+ return false;
+ }
+ function processImports() {
+ scanner.setText(sourceText);
+ scanner.scan();
+ while (true) {
+ if (scanner.getToken() === 1) {
+ break;
+ }
+ if (tryConsumeDeclare() ||
+ tryConsumeImport() ||
+ tryConsumeExport() ||
+ (detectJavaScriptImports && (tryConsumeRequireCall(false) || tryConsumeDefine()))) {
+ continue;
+ }
+ else {
+ scanner.scan();
+ }
}
scanner.setText(undefined);
}
if (readImportFiles) {
- processImport();
+ processImports();
}
processTripleSlashDirectives();
return { referencedFiles: referencedFiles, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientExternalModules };
@@ -38250,7 +38739,7 @@ var ts;
function getSemanticDiagnostics(fileName) {
synchronizeHostData();
var targetSourceFile = getValidSourceFile(fileName);
- if (ts.isJavaScript(fileName)) {
+ if (ts.isSourceFileJavaScript(targetSourceFile)) {
return getJavaScriptSemanticDiagnostics(targetSourceFile);
}
var semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
@@ -38442,7 +38931,7 @@ var ts;
var typeChecker = program.getTypeChecker();
var syntacticStart = new Date().getTime();
var sourceFile = getValidSourceFile(fileName);
- var isJavaScriptFile = ts.isJavaScript(fileName);
+ var isJavaScriptFile = ts.isSourceFileJavaScript(sourceFile);
var isJsDocTagName = false;
var start = new Date().getTime();
var currentToken = ts.getTokenAtPosition(sourceFile, position);
@@ -38953,8 +39442,8 @@ var ts;
if (element.getStart() <= position && position <= element.getEnd()) {
continue;
}
- var name_33 = element.propertyName || element.name;
- exisingImportsOrExports[name_33.text] = true;
+ var name_35 = element.propertyName || element.name;
+ exisingImportsOrExports[name_35.text] = true;
}
if (ts.isEmpty(exisingImportsOrExports)) {
return exportsOfModule;
@@ -38978,7 +39467,9 @@ var ts;
}
var existingName = void 0;
if (m.kind === 163 && m.propertyName) {
- existingName = m.propertyName.text;
+ if (m.propertyName.kind === 69) {
+ existingName = m.propertyName.text;
+ }
}
else {
existingName = m.name.text;
@@ -39008,44 +39499,41 @@ var ts;
return undefined;
}
var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName;
- var entries;
if (isJsDocTagName) {
return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() };
}
- if (isRightOfDot && ts.isJavaScript(fileName)) {
- entries = getCompletionEntriesFromSymbols(symbols);
- ts.addRange(entries, getJavaScriptCompletionEntries());
+ var sourceFile = getValidSourceFile(fileName);
+ var entries = [];
+ if (isRightOfDot && ts.isSourceFileJavaScript(sourceFile)) {
+ var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries);
+ ts.addRange(entries, getJavaScriptCompletionEntries(sourceFile, uniqueNames));
}
else {
if (!symbols || symbols.length === 0) {
return undefined;
}
- entries = getCompletionEntriesFromSymbols(symbols);
+ getCompletionEntriesFromSymbols(symbols, entries);
}
if (!isMemberCompletion && !isJsDocTagName) {
ts.addRange(entries, keywordCompletions);
}
return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
- function getJavaScriptCompletionEntries() {
+ function getJavaScriptCompletionEntries(sourceFile, uniqueNames) {
var entries = [];
- var allNames = {};
var target = program.getCompilerOptions().target;
- for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
- var sourceFile = _a[_i];
- var nameTable = getNameTable(sourceFile);
- for (var name_34 in nameTable) {
- if (!allNames[name_34]) {
- allNames[name_34] = name_34;
- var displayName = getCompletionEntryDisplayName(name_34, target, true);
- if (displayName) {
- var entry = {
- name: displayName,
- kind: ScriptElementKind.warning,
- kindModifiers: "",
- sortText: "1"
- };
- entries.push(entry);
- }
+ var nameTable = getNameTable(sourceFile);
+ for (var name_36 in nameTable) {
+ if (!uniqueNames[name_36]) {
+ uniqueNames[name_36] = name_36;
+ var displayName = getCompletionEntryDisplayName(name_36, target, true);
+ if (displayName) {
+ var entry = {
+ name: displayName,
+ kind: ScriptElementKind.warning,
+ kindModifiers: "",
+ sortText: "1"
+ };
+ entries.push(entry);
}
}
}
@@ -39073,25 +39561,24 @@ var ts;
sortText: "0"
};
}
- function getCompletionEntriesFromSymbols(symbols) {
+ function getCompletionEntriesFromSymbols(symbols, entries) {
var start = new Date().getTime();
- var entries = [];
+ var uniqueNames = {};
if (symbols) {
- var nameToSymbol = {};
for (var _i = 0, symbols_3 = symbols; _i < symbols_3.length; _i++) {
var symbol = symbols_3[_i];
var entry = createCompletionEntry(symbol, location);
if (entry) {
var id = ts.escapeIdentifier(entry.name);
- if (!ts.lookUp(nameToSymbol, id)) {
+ if (!ts.lookUp(uniqueNames, id)) {
entries.push(entry);
- nameToSymbol[id] = symbol;
+ uniqueNames[id] = id;
}
}
}
}
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
- return entries;
+ return uniqueNames;
}
}
function getCompletionEntryDetails(fileName, position, entryName) {
@@ -39272,16 +39759,16 @@ var ts;
case ScriptElementKind.letElement:
case ScriptElementKind.parameterElement:
case ScriptElementKind.localVariableElement:
- displayParts.push(ts.punctuationPart(54));
+ displayParts.push(ts.punctuationPart(ts.SyntaxKind.ColonToken));
displayParts.push(ts.spacePart());
if (useConstructSignatures) {
- displayParts.push(ts.keywordPart(92));
+ displayParts.push(ts.keywordPart(ts.SyntaxKind.NewKeyword));
displayParts.push(ts.spacePart());
}
- if (!(type.flags & 65536)) {
- ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, undefined, 1));
+ if (!(type.flags & ts.TypeFlags.Anonymous)) {
+ ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, undefined, ts.SymbolFormatFlags.WriteTypeParametersOrArguments));
}
- addSignatureDisplayParts(signature, allSignatures, 8);
+ addSignatureDisplayParts(signature, allSignatures, ts.TypeFormatFlags.WriteArrowStyleSignature);
break;
default:
addSignatureDisplayParts(signature, allSignatures);
@@ -40728,17 +41215,17 @@ var ts;
if (isNameOfPropertyAssignment(node)) {
var objectLiteral = node.parent.parent;
var contextualType = typeChecker.getContextualType(objectLiteral);
- var name_35 = node.text;
+ var name_37 = node.text;
if (contextualType) {
if (contextualType.flags & 16384) {
- var unionProperty = contextualType.getProperty(name_35);
+ var unionProperty = contextualType.getProperty(name_37);
if (unionProperty) {
return [unionProperty];
}
else {
var result_4 = [];
ts.forEach(contextualType.types, function (t) {
- var symbol = t.getProperty(name_35);
+ var symbol = t.getProperty(name_37);
if (symbol) {
result_4.push(symbol);
}
@@ -40747,7 +41234,7 @@ var ts;
}
}
else {
- var symbol_1 = contextualType.getProperty(name_35);
+ var symbol_1 = contextualType.getProperty(name_37);
if (symbol_1) {
return [symbol_1];
}
@@ -41105,6 +41592,9 @@ var ts;
case 16: return ClassificationTypeNames.typeAliasName;
case 17: return ClassificationTypeNames.parameterName;
case 18: return ClassificationTypeNames.docCommentTagName;
+ case 19: return ClassificationTypeNames.jsxOpenTagName;
+ case 20: return ClassificationTypeNames.jsxCloseTagName;
+ case 21: return ClassificationTypeNames.jsxSelfClosingTagName;
}
}
function convertClassifications(classifications) {
@@ -41344,6 +41834,21 @@ var ts;
return 17;
}
return;
+ case 235:
+ if (token.parent.tagName === token) {
+ return 19;
+ }
+ return;
+ case 237:
+ if (token.parent.tagName === token) {
+ return 20;
+ }
+ return;
+ case 234:
+ if (token.parent.tagName === token) {
+ return 21;
+ }
+ return;
}
}
return 2;
@@ -42053,18 +42558,8 @@ var ts;
ts.getDefaultLibFilePath = getDefaultLibFilePath;
function initializeServices() {
ts.objectAllocator = {
- getNodeConstructor: function (kind) {
- function Node(pos, end) {
- this.pos = pos;
- this.end = end;
- this.flags = 0;
- this.parent = undefined;
- }
- var proto = kind === 248 ? new SourceFileObject() : new NodeObject();
- proto.kind = kind;
- Node.prototype = proto;
- return Node;
- },
+ getNodeConstructor: function () { return NodeObject; },
+ getSourceFileConstructor: function () { return SourceFileObject; },
getSymbolConstructor: function () { return SymbolObject; },
getTypeConstructor: function () { return TypeObject; },
getSignatureConstructor: function () { return SignatureObject; }
@@ -42959,8 +43454,8 @@ var ts;
};
Session.prototype.getDiagnosticsForProject = function (delay, fileName) {
var _this = this;
- var _a = this.getProjectInfo(fileName, true), configFileName = _a.configFileName, fileNamesInProject = _a.fileNames;
- fileNamesInProject = fileNamesInProject.filter(function (value, index, array) { return value.indexOf("lib.d.ts") < 0; });
+ var _a = this.getProjectInfo(fileName, true), configFileName = _a.configFileName, fileNames = _a.fileNames;
+ var fileNamesInProject = fileNames.filter(function (value, index, array) { return value.indexOf("lib.d.ts") < 0; });
var highPriorityFiles = [];
var mediumPriorityFiles = [];
var lowPriorityFiles = [];
@@ -43329,6 +43824,9 @@ var ts;
this.filenameToSourceFile = {};
this.updateGraphSeq = 0;
this.openRefCount = 0;
+ if (projectOptions && projectOptions.files) {
+ projectOptions.compilerOptions.allowNonTsExtensions = true;
+ }
this.compilerService = new CompilerService(this, projectOptions && projectOptions.compilerOptions);
}
Project.prototype.addOpenRef = function () {
@@ -43399,6 +43897,7 @@ var ts;
Project.prototype.setProjectOptions = function (projectOptions) {
this.projectOptions = projectOptions;
if (projectOptions.compilerOptions) {
+ projectOptions.compilerOptions.allowNonTsExtensions = true;
this.compilerService.setCompilerOptions(projectOptions.compilerOptions);
}
};
@@ -43824,7 +44323,6 @@ var ts;
}
}
if (content !== undefined) {
- var indentSize;
info = new ScriptInfo(this.host, fileName, content, openedByClient);
info.setFormatOptions(this.getFormatCodeOptions());
this.filenameToScriptInfo[fileName] = info;
@@ -44081,7 +44579,9 @@ var ts;
this.setCompilerOptions(opt);
}
else {
- this.setCompilerOptions(ts.getDefaultCompilerOptions());
+ var defaultOpts = ts.getDefaultCompilerOptions();
+ defaultOpts.allowNonTsExtensions = true;
+ this.setCompilerOptions(defaultOpts);
}
this.languageService = ts.createLanguageService(this.host, this.documentRegistry);
this.classifier = ts.createClassifier();
@@ -45635,7 +46135,7 @@ var ts;
};
CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) {
return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () {
- var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()));
+ var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), true, true);
var convertResult = {
referencedFiles: [],
importedFiles: [],
@@ -45696,7 +46196,7 @@ var ts;
TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) {
try {
if (this.documentRegistry === undefined) {
- this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
+ this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory());
}
var hostAdapter = new LanguageServiceShimHostAdapter(host);
var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry);
@@ -45728,7 +46228,7 @@ var ts;
};
TypeScriptServicesFactory.prototype.close = function () {
this._shims = [];
- this.documentRegistry = ts.createDocumentRegistry();
+ this.documentRegistry = undefined;
};
TypeScriptServicesFactory.prototype.registerShim = function (shim) {
this._shims.push(shim);
diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts
index 972ebfa472dbd..32a6dee462385 100644
--- a/lib/typescript.d.ts
+++ b/lib/typescript.d.ts
@@ -387,6 +387,7 @@ declare namespace ts {
right: Identifier;
}
type EntityName = Identifier | QualifiedName;
+ type PropertyName = Identifier | LiteralExpression | ComputedPropertyName;
type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern;
interface Declaration extends Node {
_declarationBrand: any;
@@ -425,7 +426,7 @@ declare namespace ts {
initializer?: Expression;
}
interface BindingElement extends Declaration {
- propertyName?: Identifier;
+ propertyName?: PropertyName;
dotDotDotToken?: Node;
name: Identifier | BindingPattern;
initializer?: Expression;
@@ -452,7 +453,7 @@ declare namespace ts {
objectAssignmentInitializer?: Expression;
}
interface VariableLikeDeclaration extends Declaration {
- propertyName?: Identifier;
+ propertyName?: PropertyName;
dotDotDotToken?: Node;
name: DeclarationName;
questionToken?: Node;
@@ -581,7 +582,7 @@ declare namespace ts {
asteriskToken?: Node;
expression?: Expression;
}
- interface BinaryExpression extends Expression {
+ interface BinaryExpression extends Expression, Declaration {
left: Expression;
operatorToken: Node;
right: Expression;
@@ -625,7 +626,7 @@ declare namespace ts {
interface ObjectLiteralExpression extends PrimaryExpression, Declaration {
properties: NodeArray;
}
- interface PropertyAccessExpression extends MemberExpression {
+ interface PropertyAccessExpression extends MemberExpression, Declaration {
expression: LeftHandSideExpression;
dotToken: Node;
name: Identifier;
@@ -1220,6 +1221,7 @@ declare namespace ts {
ObjectLiteral = 524288,
ESSymbol = 16777216,
ThisType = 33554432,
+ ObjectLiteralPatternWithComputedProperties = 67108864,
StringLike = 258,
NumberLike = 132,
ObjectType = 80896,
@@ -1537,7 +1539,6 @@ declare namespace ts {
function getTypeParameterOwner(d: Declaration): Declaration;
}
declare namespace ts {
- function getNodeConstructor(kind: SyntaxKind): new (pos?: number, end?: number) => Node;
function createNode(kind: SyntaxKind, pos?: number, end?: number): Node;
function forEachChild(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T;
function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes?: boolean): SourceFile;
@@ -2126,6 +2127,9 @@ declare namespace ts {
static typeAliasName: string;
static parameterName: string;
static docCommentTagName: string;
+ static jsxOpenTagName: string;
+ static jsxCloseTagName: string;
+ static jsxSelfClosingTagName: string;
}
enum ClassificationType {
comment = 1,
@@ -2146,6 +2150,9 @@ declare namespace ts {
typeAliasName = 16,
parameterName = 17,
docCommentTagName = 18,
+ jsxOpenTagName = 19,
+ jsxCloseTagName = 20,
+ jsxSelfClosingTagName = 21,
}
interface DisplayPartsSymbolWriter extends SymbolWriter {
displayParts(): SymbolDisplayPart[];
@@ -2171,7 +2178,7 @@ declare namespace ts {
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile;
function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string;
function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry;
- function preProcessFile(sourceText: string, readImportFiles?: boolean): PreProcessedFileInfo;
+ function preProcessFile(sourceText: string, readImportFiles?: boolean, detectJavaScriptImports?: boolean): PreProcessedFileInfo;
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry): LanguageService;
function createClassifier(): Classifier;
/**
diff --git a/lib/typescript.js b/lib/typescript.js
index 8b0ef04f96e45..498ddc3786075 100644
--- a/lib/typescript.js
+++ b/lib/typescript.js
@@ -622,6 +622,7 @@ var ts;
TypeFlags[TypeFlags["ContainsAnyFunctionType"] = 8388608] = "ContainsAnyFunctionType";
TypeFlags[TypeFlags["ESSymbol"] = 16777216] = "ESSymbol";
TypeFlags[TypeFlags["ThisType"] = 33554432] = "ThisType";
+ TypeFlags[TypeFlags["ObjectLiteralPatternWithComputedProperties"] = 67108864] = "ObjectLiteralPatternWithComputedProperties";
/* @internal */
TypeFlags[TypeFlags["Intrinsic"] = 16777343] = "Intrinsic";
/* @internal */
@@ -1530,12 +1531,7 @@ var ts;
* List of supported extensions in order of file resolution precedence.
*/
ts.supportedExtensions = [".ts", ".tsx", ".d.ts"];
- /**
- * List of extensions that will be used to look for external modules.
- * This list is kept separate from supportedExtensions to for cases when we'll allow to include .js files in compilation,
- * but still would like to load only TypeScript files as modules
- */
- ts.moduleFileExtensions = ts.supportedExtensions;
+ ts.supportedJsExtensions = ts.supportedExtensions.concat(".js", ".jsx");
function isSupportedSourceFileName(fileName) {
if (!fileName) {
return false;
@@ -1586,17 +1582,16 @@ var ts;
}
function Signature(checker) {
}
+ function Node(kind, pos, end) {
+ this.kind = kind;
+ this.pos = pos;
+ this.end = end;
+ this.flags = 0 /* None */;
+ this.parent = undefined;
+ }
ts.objectAllocator = {
- getNodeConstructor: function (kind) {
- function Node(pos, end) {
- this.pos = pos;
- this.end = end;
- this.flags = 0 /* None */;
- this.parent = undefined;
- }
- Node.prototype = { kind: kind };
- return Node;
- },
+ getNodeConstructor: function () { return Node; },
+ getSourceFileConstructor: function () { return Node; },
getSymbolConstructor: function () { return Symbol; },
getTypeConstructor: function () { return Type; },
getSignatureConstructor: function () { return Signature; }
@@ -1913,7 +1908,16 @@ var ts;
if (writeByteOrderMark) {
data = "\uFEFF" + data;
}
- _fs.writeFileSync(fileName, data, "utf8");
+ var fd;
+ try {
+ fd = _fs.openSync(fileName, "w");
+ _fs.writeSync(fd, data, undefined, "utf8");
+ }
+ finally {
+ if (fd !== undefined) {
+ _fs.closeSync(fd);
+ }
+ }
}
function getCanonicalPath(path) {
return useCaseSensitiveFileNames ? path.toLowerCase() : path;
@@ -2614,6 +2618,7 @@ var ts;
Disallow_inconsistently_cased_references_to_the_same_file: { code: 6078, category: ts.DiagnosticCategory.Message, key: "Disallow_inconsistently_cased_references_to_the_same_file_6078", message: "Disallow inconsistently-cased references to the same file." },
Specify_JSX_code_generation_Colon_preserve_or_react: { code: 6080, category: ts.DiagnosticCategory.Message, key: "Specify_JSX_code_generation_Colon_preserve_or_react_6080", message: "Specify JSX code generation: 'preserve' or 'react'" },
Argument_for_jsx_must_be_preserve_or_react: { code: 6081, category: ts.DiagnosticCategory.Message, key: "Argument_for_jsx_must_be_preserve_or_react_6081", message: "Argument for '--jsx' must be 'preserve' or 'react'." },
+ Only_amd_and_system_modules_are_supported_alongside_0: { code: 6082, category: ts.DiagnosticCategory.Error, key: "Only_amd_and_system_modules_are_supported_alongside_0_6082", message: "Only 'amd' and 'system' modules are supported alongside --{0}." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." },
@@ -3173,7 +3178,7 @@ var ts;
function getCommentRanges(text, pos, trailing) {
var result;
var collecting = trailing || pos === 0;
- while (true) {
+ while (pos < text.length) {
var ch = text.charCodeAt(pos);
switch (ch) {
case 13 /* carriageReturn */:
@@ -3242,6 +3247,7 @@ var ts;
}
return result;
}
+ return result;
}
function getLeadingCommentRanges(text, pos) {
return getCommentRanges(text, pos, /*trailing*/ false);
@@ -3343,7 +3349,7 @@ var ts;
error(ts.Diagnostics.Digit_expected);
}
}
- return +(text.substring(start, end));
+ return "" + +(text.substring(start, end));
}
function scanOctalDigits() {
var start = pos;
@@ -3770,7 +3776,7 @@ var ts;
return pos++, token = 36 /* MinusToken */;
case 46 /* dot */:
if (isDigit(text.charCodeAt(pos + 1))) {
- tokenValue = "" + scanNumber();
+ tokenValue = scanNumber();
return token = 8 /* NumericLiteral */;
}
if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) {
@@ -3873,7 +3879,7 @@ var ts;
case 55 /* _7 */:
case 56 /* _8 */:
case 57 /* _9 */:
- tokenValue = "" + scanNumber();
+ tokenValue = scanNumber();
return token = 8 /* NumericLiteral */;
case 58 /* colon */:
return pos++, token = 54 /* ColonToken */;
@@ -4177,1558 +4183,243 @@ var ts;
}
ts.createScanner = createScanner;
})(ts || (ts = {}));
-///
+///
/* @internal */
var ts;
(function (ts) {
- ts.bindTime = 0;
- (function (ModuleInstanceState) {
- ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
- ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
- ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
- })(ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
- var ModuleInstanceState = ts.ModuleInstanceState;
- var Reachability;
- (function (Reachability) {
- Reachability[Reachability["Unintialized"] = 1] = "Unintialized";
- Reachability[Reachability["Reachable"] = 2] = "Reachable";
- Reachability[Reachability["Unreachable"] = 4] = "Unreachable";
- Reachability[Reachability["ReportedUnreachable"] = 8] = "ReportedUnreachable";
- })(Reachability || (Reachability = {}));
- function or(state1, state2) {
- return (state1 | state2) & 2 /* Reachable */
- ? 2 /* Reachable */
- : (state1 & state2) & 8 /* ReportedUnreachable */
- ? 8 /* ReportedUnreachable */
- : 4 /* Unreachable */;
- }
- function getModuleInstanceState(node) {
- // A module is uninstantiated if it contains only
- // 1. interface declarations, type alias declarations
- if (node.kind === 215 /* InterfaceDeclaration */ || node.kind === 216 /* TypeAliasDeclaration */) {
- return 0 /* NonInstantiated */;
+ function getDeclarationOfKind(symbol, kind) {
+ var declarations = symbol.declarations;
+ if (declarations) {
+ for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
+ var declaration = declarations_1[_i];
+ if (declaration.kind === kind) {
+ return declaration;
+ }
+ }
}
- else if (ts.isConstEnumDeclaration(node)) {
- return 2 /* ConstEnumOnly */;
+ return undefined;
+ }
+ ts.getDeclarationOfKind = getDeclarationOfKind;
+ // Pool writers to avoid needing to allocate them for every symbol we write.
+ var stringWriters = [];
+ function getSingleLineStringWriter() {
+ if (stringWriters.length === 0) {
+ var str = "";
+ var writeText = function (text) { return str += text; };
+ return {
+ string: function () { return str; },
+ writeKeyword: writeText,
+ writeOperator: writeText,
+ writePunctuation: writeText,
+ writeSpace: writeText,
+ writeStringLiteral: writeText,
+ writeParameter: writeText,
+ writeSymbol: writeText,
+ // Completely ignore indentation for string writers. And map newlines to
+ // a single space.
+ writeLine: function () { return str += " "; },
+ increaseIndent: function () { },
+ decreaseIndent: function () { },
+ clear: function () { return str = ""; },
+ trackSymbol: function () { },
+ reportInaccessibleThisError: function () { }
+ };
}
- else if ((node.kind === 222 /* ImportDeclaration */ || node.kind === 221 /* ImportEqualsDeclaration */) && !(node.flags & 2 /* Export */)) {
- return 0 /* NonInstantiated */;
+ return stringWriters.pop();
+ }
+ ts.getSingleLineStringWriter = getSingleLineStringWriter;
+ function releaseStringWriter(writer) {
+ writer.clear();
+ stringWriters.push(writer);
+ }
+ ts.releaseStringWriter = releaseStringWriter;
+ function getFullWidth(node) {
+ return node.end - node.pos;
+ }
+ ts.getFullWidth = getFullWidth;
+ function arrayIsEqualTo(array1, array2, equaler) {
+ if (!array1 || !array2) {
+ return array1 === array2;
}
- else if (node.kind === 219 /* ModuleBlock */) {
- var state = 0 /* NonInstantiated */;
- ts.forEachChild(node, function (n) {
- switch (getModuleInstanceState(n)) {
- case 0 /* NonInstantiated */:
- // child is non-instantiated - continue searching
- return false;
- case 2 /* ConstEnumOnly */:
- // child is const enum only - record state and continue searching
- state = 2 /* ConstEnumOnly */;
- return false;
- case 1 /* Instantiated */:
- // child is instantiated - record state and stop
- state = 1 /* Instantiated */;
- return true;
- }
- });
- return state;
+ if (array1.length !== array2.length) {
+ return false;
}
- else if (node.kind === 218 /* ModuleDeclaration */) {
- return getModuleInstanceState(node.body);
+ for (var i = 0; i < array1.length; ++i) {
+ var equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
+ if (!equals) {
+ return false;
+ }
}
- else {
- return 1 /* Instantiated */;
+ return true;
+ }
+ ts.arrayIsEqualTo = arrayIsEqualTo;
+ function hasResolvedModule(sourceFile, moduleNameText) {
+ return sourceFile.resolvedModules && ts.hasProperty(sourceFile.resolvedModules, moduleNameText);
+ }
+ ts.hasResolvedModule = hasResolvedModule;
+ function getResolvedModule(sourceFile, moduleNameText) {
+ return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
+ }
+ ts.getResolvedModule = getResolvedModule;
+ function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
+ if (!sourceFile.resolvedModules) {
+ sourceFile.resolvedModules = {};
}
+ sourceFile.resolvedModules[moduleNameText] = resolvedModule;
}
- ts.getModuleInstanceState = getModuleInstanceState;
- var ContainerFlags;
- (function (ContainerFlags) {
- // The current node is not a container, and no container manipulation should happen before
- // recursing into it.
- ContainerFlags[ContainerFlags["None"] = 0] = "None";
- // The current node is a container. It should be set as the current container (and block-
- // container) before recursing into it. The current node does not have locals. Examples:
- //
- // Classes, ObjectLiterals, TypeLiterals, Interfaces...
- ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
- // The current node is a block-scoped-container. It should be set as the current block-
- // container before recursing into it. Examples:
- //
- // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
- ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
- ContainerFlags[ContainerFlags["HasLocals"] = 4] = "HasLocals";
- // If the current node is a container that also container that also contains locals. Examples:
- //
- // Functions, Methods, Modules, Source-files.
- ContainerFlags[ContainerFlags["IsContainerWithLocals"] = 5] = "IsContainerWithLocals";
- })(ContainerFlags || (ContainerFlags = {}));
- var binder = createBinder();
- function bindSourceFile(file, options) {
- var start = new Date().getTime();
- binder(file, options);
- ts.bindTime += new Date().getTime() - start;
+ ts.setResolvedModule = setResolvedModule;
+ // Returns true if this node contains a parse error anywhere underneath it.
+ function containsParseError(node) {
+ aggregateChildData(node);
+ return (node.parserContextFlags & 64 /* ThisNodeOrAnySubNodesHasError */) !== 0;
}
- ts.bindSourceFile = bindSourceFile;
- function createBinder() {
- var file;
- var options;
- var parent;
- var container;
- var blockScopeContainer;
- var lastContainer;
- var seenThisKeyword;
- // state used by reachability checks
- var hasExplicitReturn;
- var currentReachabilityState;
- var labelStack;
- var labelIndexMap;
- var implicitLabels;
- // If this file is an external module, then it is automatically in strict-mode according to
- // ES6. If it is not an external module, then we'll determine if it is in strict mode or
- // not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
- var inStrictMode;
- var symbolCount = 0;
- var Symbol;
- var classifiableNames;
- function bindSourceFile(f, opts) {
- file = f;
- options = opts;
- inStrictMode = !!file.externalModuleIndicator;
- classifiableNames = {};
- Symbol = ts.objectAllocator.getSymbolConstructor();
- if (!file.locals) {
- bind(file);
- file.symbolCount = symbolCount;
- file.classifiableNames = classifiableNames;
+ ts.containsParseError = containsParseError;
+ function aggregateChildData(node) {
+ if (!(node.parserContextFlags & 128 /* HasAggregatedChildData */)) {
+ // A node is considered to contain a parse error if:
+ // a) the parser explicitly marked that it had an error
+ // b) any of it's children reported that it had an error.
+ var thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & 16 /* ThisNodeHasError */) !== 0) ||
+ ts.forEachChild(node, containsParseError);
+ // If so, mark ourselves accordingly.
+ if (thisNodeOrAnySubNodesHasError) {
+ node.parserContextFlags |= 64 /* ThisNodeOrAnySubNodesHasError */;
}
- parent = undefined;
- container = undefined;
- blockScopeContainer = undefined;
- lastContainer = undefined;
- seenThisKeyword = false;
- hasExplicitReturn = false;
- labelStack = undefined;
- labelIndexMap = undefined;
- implicitLabels = undefined;
+ // Also mark that we've propogated the child information to this node. This way we can
+ // always consult the bit directly on this node without needing to check its children
+ // again.
+ node.parserContextFlags |= 128 /* HasAggregatedChildData */;
}
- return bindSourceFile;
- function createSymbol(flags, name) {
- symbolCount++;
- return new Symbol(flags, name);
+ }
+ function getSourceFileOfNode(node) {
+ while (node && node.kind !== 248 /* SourceFile */) {
+ node = node.parent;
}
- function addDeclarationToSymbol(symbol, node, symbolFlags) {
- symbol.flags |= symbolFlags;
- node.symbol = symbol;
- if (!symbol.declarations) {
- symbol.declarations = [];
- }
- symbol.declarations.push(node);
- if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) {
- symbol.exports = {};
- }
- if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) {
- symbol.members = {};
- }
- if (symbolFlags & 107455 /* Value */ && !symbol.valueDeclaration) {
- symbol.valueDeclaration = node;
- }
+ return node;
+ }
+ ts.getSourceFileOfNode = getSourceFileOfNode;
+ function getStartPositionOfLine(line, sourceFile) {
+ ts.Debug.assert(line >= 0);
+ return ts.getLineStarts(sourceFile)[line];
+ }
+ ts.getStartPositionOfLine = getStartPositionOfLine;
+ // This is a useful function for debugging purposes.
+ function nodePosToString(node) {
+ var file = getSourceFileOfNode(node);
+ var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
+ return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
+ }
+ ts.nodePosToString = nodePosToString;
+ function getStartPosOfNode(node) {
+ return node.pos;
+ }
+ ts.getStartPosOfNode = getStartPosOfNode;
+ // Returns true if this node is missing from the actual source code. A 'missing' node is different
+ // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
+ // in the tree), it is definitely missing. However, a node may be defined, but still be
+ // missing. This happens whenever the parser knows it needs to parse something, but can't
+ // get anything in the source code that it expects at that location. For example:
+ //
+ // let a: ;
+ //
+ // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
+ // code). So the parser will attempt to parse out a type, and will create an actual node.
+ // However, this node will be 'missing' in the sense that no actual source-code/tokens are
+ // contained within it.
+ function nodeIsMissing(node) {
+ if (!node) {
+ return true;
}
- // Should not be called on a declaration with a computed property name,
- // unless it is a well known Symbol.
- function getDeclarationName(node) {
- if (node.name) {
- if (node.kind === 218 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */) {
- return "\"" + node.name.text + "\"";
- }
- if (node.name.kind === 136 /* ComputedPropertyName */) {
- var nameExpression = node.name.expression;
- ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
- return ts.getPropertyNameForKnownSymbolName(nameExpression.name.text);
- }
- return node.name.text;
- }
- switch (node.kind) {
- case 144 /* Constructor */:
- return "__constructor";
- case 152 /* FunctionType */:
- case 147 /* CallSignature */:
- return "__call";
- case 153 /* ConstructorType */:
- case 148 /* ConstructSignature */:
- return "__new";
- case 149 /* IndexSignature */:
- return "__index";
- case 228 /* ExportDeclaration */:
- return "__export";
- case 227 /* ExportAssignment */:
- return node.isExportEquals ? "export=" : "default";
- case 213 /* FunctionDeclaration */:
- case 214 /* ClassDeclaration */:
- return node.flags & 512 /* Default */ ? "default" : undefined;
- }
+ return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
+ }
+ ts.nodeIsMissing = nodeIsMissing;
+ function nodeIsPresent(node) {
+ return !nodeIsMissing(node);
+ }
+ ts.nodeIsPresent = nodeIsPresent;
+ function getTokenPosOfNode(node, sourceFile) {
+ // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
+ // want to skip trivia because this will launch us forward to the next token.
+ if (nodeIsMissing(node)) {
+ return node.pos;
}
- function getDisplayName(node) {
- return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node);
+ return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
+ }
+ ts.getTokenPosOfNode = getTokenPosOfNode;
+ function getNonDecoratorTokenPosOfNode(node, sourceFile) {
+ if (nodeIsMissing(node) || !node.decorators) {
+ return getTokenPosOfNode(node, sourceFile);
}
- /**
- * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names.
- * @param symbolTable - The symbol table which node will be added to.
- * @param parent - node's parent declaration.
- * @param node - The declaration to be added to the symbol table
- * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
- * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
- */
- function declareSymbol(symbolTable, parent, node, includes, excludes) {
- ts.Debug.assert(!ts.hasDynamicName(node));
- var isDefaultExport = node.flags & 512 /* Default */;
- // The exported symbol for an export default function/class node is always named "default"
- var name = isDefaultExport && parent ? "default" : getDeclarationName(node);
- var symbol;
- if (name !== undefined) {
- // Check and see if the symbol table already has a symbol with this name. If not,
- // create a new symbol with this name and add it to the table. Note that we don't
- // give the new symbol any flags *yet*. This ensures that it will not conflict
- // with the 'excludes' flags we pass in.
- //
- // If we do get an existing symbol, see if it conflicts with the new symbol we're
- // creating. For example, a 'var' symbol and a 'class' symbol will conflict within
- // the same symbol table. If we have a conflict, report the issue on each
- // declaration we have for this symbol, and then create a new symbol for this
- // declaration.
- //
- // If we created a new symbol, either because we didn't have a symbol with this name
- // in the symbol table, or we conflicted with an existing symbol, then just add this
- // node as the sole declaration of the new symbol.
- //
- // Otherwise, we'll be merging into a compatible existing symbol (for example when
- // you have multiple 'vars' with the same name in the same container). In this case
- // just add this node into the declarations list of the symbol.
- symbol = ts.hasProperty(symbolTable, name)
- ? symbolTable[name]
- : (symbolTable[name] = createSymbol(0 /* None */, name));
- if (name && (includes & 788448 /* Classifiable */)) {
- classifiableNames[name] = name;
- }
- if (symbol.flags & excludes) {
- if (node.name) {
- node.name.parent = node;
- }
- // Report errors every position with duplicate declaration
- // Report errors on previous encountered declarations
- var message = symbol.flags & 2 /* BlockScopedVariable */
- ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
- : ts.Diagnostics.Duplicate_identifier_0;
- ts.forEach(symbol.declarations, function (declaration) {
- if (declaration.flags & 512 /* Default */) {
- message = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
- }
- });
- ts.forEach(symbol.declarations, function (declaration) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
- });
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
- symbol = createSymbol(0 /* None */, name);
- }
- }
- else {
- symbol = createSymbol(0 /* None */, "__missing");
- }
- addDeclarationToSymbol(symbol, node, includes);
- symbol.parent = parent;
- return symbol;
+ return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
+ }
+ ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
+ function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
+ if (includeTrivia === void 0) { includeTrivia = false; }
+ if (nodeIsMissing(node)) {
+ return "";
}
- function declareModuleMember(node, symbolFlags, symbolExcludes) {
- var hasExportModifier = ts.getCombinedNodeFlags(node) & 2 /* Export */;
- if (symbolFlags & 8388608 /* Alias */) {
- if (node.kind === 230 /* ExportSpecifier */ || (node.kind === 221 /* ImportEqualsDeclaration */ && hasExportModifier)) {
- return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- }
- else {
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
+ var text = sourceFile.text;
+ return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end);
+ }
+ ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
+ function getTextOfNodeFromSourceText(sourceText, node) {
+ if (nodeIsMissing(node)) {
+ return "";
+ }
+ return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
+ }
+ ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
+ function getTextOfNode(node, includeTrivia) {
+ if (includeTrivia === void 0) { includeTrivia = false; }
+ return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
+ }
+ ts.getTextOfNode = getTextOfNode;
+ // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
+ function escapeIdentifier(identifier) {
+ return identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier;
+ }
+ ts.escapeIdentifier = escapeIdentifier;
+ // Remove extra underscore from escaped identifier
+ function unescapeIdentifier(identifier) {
+ return identifier.length >= 3 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ && identifier.charCodeAt(2) === 95 /* _ */ ? identifier.substr(1) : identifier;
+ }
+ ts.unescapeIdentifier = unescapeIdentifier;
+ // Make an identifier from an external module name by extracting the string after the last "/" and replacing
+ // all non-alphanumeric characters with underscores
+ function makeIdentifierFromModuleName(moduleName) {
+ return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
+ }
+ ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
+ function isBlockOrCatchScoped(declaration) {
+ return (getCombinedNodeFlags(declaration) & 24576 /* BlockScoped */) !== 0 ||
+ isCatchClauseVariableDeclaration(declaration);
+ }
+ ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
+ // Gets the nearest enclosing block scope container that has the provided node
+ // as a descendant, that is not the provided node.
+ function getEnclosingBlockScopeContainer(node) {
+ var current = node.parent;
+ while (current) {
+ if (isFunctionLike(current)) {
+ return current;
}
- else {
- // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue,
- // ExportType, or ExportContainer flag, and an associated export symbol with all the correct flags set
- // on it. There are 2 main reasons:
- //
- // 1. We treat locals and exports of the same name as mutually exclusive within a container.
- // That means the binder will issue a Duplicate Identifier error if you mix locals and exports
- // with the same name in the same container.
- // TODO: Make this a more specific error and decouple it from the exclusion logic.
- // 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
- // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
- // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
- if (hasExportModifier || container.flags & 131072 /* ExportContext */) {
- var exportKind = (symbolFlags & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0) |
- (symbolFlags & 793056 /* Type */ ? 2097152 /* ExportType */ : 0) |
- (symbolFlags & 1536 /* Namespace */ ? 4194304 /* ExportNamespace */ : 0);
- var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
- local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- node.localSymbol = local;
- return local;
- }
- else {
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
+ switch (current.kind) {
+ case 248 /* SourceFile */:
+ case 220 /* CaseBlock */:
+ case 244 /* CatchClause */:
+ case 218 /* ModuleDeclaration */:
+ case 199 /* ForStatement */:
+ case 200 /* ForInStatement */:
+ case 201 /* ForOfStatement */:
+ return current;
+ case 192 /* Block */:
+ // function block is not considered block-scope container
+ // see comment in binder.ts: bind(...), case for SyntaxKind.Block
+ if (!isFunctionLike(current.parent)) {
+ return current;
+ }
}
- }
- // All container nodes are kept on a linked list in declaration order. This list is used by
- // the getLocalNameOfContainer function in the type checker to validate that the local name
- // used for a container is unique.
- function bindChildren(node) {
- // Before we recurse into a node's chilren, we first save the existing parent, container
- // and block-container. Then after we pop out of processing the children, we restore
- // these saved values.
- var saveParent = parent;
- var saveContainer = container;
- var savedBlockScopeContainer = blockScopeContainer;
- // This node will now be set as the parent of all of its children as we recurse into them.
- parent = node;
- // Depending on what kind of node this is, we may have to adjust the current container
- // and block-container. If the current node is a container, then it is automatically
- // considered the current block-container as well. Also, for containers that we know
- // may contain locals, we proactively initialize the .locals field. We do this because
- // it's highly likely that the .locals will be needed to place some child in (for example,
- // a parameter, or variable declaration).
- //
- // However, we do not proactively create the .locals for block-containers because it's
- // totally normal and common for block-containers to never actually have a block-scoped
- // variable in them. We don't want to end up allocating an object for every 'block' we
- // run into when most of them won't be necessary.
- //
- // Finally, if this is a block-container, then we clear out any existing .locals object
- // it may contain within it. This happens in incremental scenarios. Because we can be
- // reusing a node from a previous compilation, that node may have had 'locals' created
- // for it. We must clear this so we don't accidently move any stale data forward from
- // a previous compilation.
- var containerFlags = getContainerFlags(node);
- if (containerFlags & 1 /* IsContainer */) {
- container = blockScopeContainer = node;
- if (containerFlags & 4 /* HasLocals */) {
- container.locals = {};
- }
- addToContainerChain(container);
- }
- else if (containerFlags & 2 /* IsBlockScopedContainer */) {
- blockScopeContainer = node;
- blockScopeContainer.locals = undefined;
- }
- var savedReachabilityState;
- var savedLabelStack;
- var savedLabels;
- var savedImplicitLabels;
- var savedHasExplicitReturn;
- var kind = node.kind;
- var flags = node.flags;
- // reset all reachability check related flags on node (for incremental scenarios)
- flags &= ~1572864 /* ReachabilityCheckFlags */;
- if (kind === 215 /* InterfaceDeclaration */) {
- seenThisKeyword = false;
- }
- var saveState = kind === 248 /* SourceFile */ || kind === 219 /* ModuleBlock */ || ts.isFunctionLikeKind(kind);
- if (saveState) {
- savedReachabilityState = currentReachabilityState;
- savedLabelStack = labelStack;
- savedLabels = labelIndexMap;
- savedImplicitLabels = implicitLabels;
- savedHasExplicitReturn = hasExplicitReturn;
- currentReachabilityState = 2 /* Reachable */;
- hasExplicitReturn = false;
- labelStack = labelIndexMap = implicitLabels = undefined;
- }
- bindReachableStatement(node);
- if (currentReachabilityState === 2 /* Reachable */ && ts.isFunctionLikeKind(kind) && ts.nodeIsPresent(node.body)) {
- flags |= 524288 /* HasImplicitReturn */;
- if (hasExplicitReturn) {
- flags |= 1048576 /* HasExplicitReturn */;
- }
- }
- if (kind === 215 /* InterfaceDeclaration */) {
- flags = seenThisKeyword ? flags | 262144 /* ContainsThis */ : flags & ~262144 /* ContainsThis */;
- }
- node.flags = flags;
- if (saveState) {
- hasExplicitReturn = savedHasExplicitReturn;
- currentReachabilityState = savedReachabilityState;
- labelStack = savedLabelStack;
- labelIndexMap = savedLabels;
- implicitLabels = savedImplicitLabels;
- }
- container = saveContainer;
- parent = saveParent;
- blockScopeContainer = savedBlockScopeContainer;
- }
- /**
- * Returns true if node and its subnodes were successfully traversed.
- * Returning false means that node was not examined and caller needs to dive into the node himself.
- */
- function bindReachableStatement(node) {
- if (checkUnreachable(node)) {
- ts.forEachChild(node, bind);
- return;
- }
- switch (node.kind) {
- case 198 /* WhileStatement */:
- bindWhileStatement(node);
- break;
- case 197 /* DoStatement */:
- bindDoStatement(node);
- break;
- case 199 /* ForStatement */:
- bindForStatement(node);
- break;
- case 200 /* ForInStatement */:
- case 201 /* ForOfStatement */:
- bindForInOrForOfStatement(node);
- break;
- case 196 /* IfStatement */:
- bindIfStatement(node);
- break;
- case 204 /* ReturnStatement */:
- case 208 /* ThrowStatement */:
- bindReturnOrThrow(node);
- break;
- case 203 /* BreakStatement */:
- case 202 /* ContinueStatement */:
- bindBreakOrContinueStatement(node);
- break;
- case 209 /* TryStatement */:
- bindTryStatement(node);
- break;
- case 206 /* SwitchStatement */:
- bindSwitchStatement(node);
- break;
- case 220 /* CaseBlock */:
- bindCaseBlock(node);
- break;
- case 207 /* LabeledStatement */:
- bindLabeledStatement(node);
- break;
- default:
- ts.forEachChild(node, bind);
- break;
- }
- }
- function bindWhileStatement(n) {
- var preWhileState = n.expression.kind === 84 /* FalseKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
- var postWhileState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
- // bind expressions (don't affect reachability)
- bind(n.expression);
- currentReachabilityState = preWhileState;
- var postWhileLabel = pushImplicitLabel();
- bind(n.statement);
- popImplicitLabel(postWhileLabel, postWhileState);
- }
- function bindDoStatement(n) {
- var preDoState = currentReachabilityState;
- var postDoLabel = pushImplicitLabel();
- bind(n.statement);
- var postDoState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : preDoState;
- popImplicitLabel(postDoLabel, postDoState);
- // bind expressions (don't affect reachability)
- bind(n.expression);
- }
- function bindForStatement(n) {
- var preForState = currentReachabilityState;
- var postForLabel = pushImplicitLabel();
- // bind expressions (don't affect reachability)
- bind(n.initializer);
- bind(n.condition);
- bind(n.incrementor);
- bind(n.statement);
- // for statement is considered infinite when it condition is either omitted or is true keyword
- // - for(..;;..)
- // - for(..;true;..)
- var isInfiniteLoop = (!n.condition || n.condition.kind === 99 /* TrueKeyword */);
- var postForState = isInfiniteLoop ? 4 /* Unreachable */ : preForState;
- popImplicitLabel(postForLabel, postForState);
- }
- function bindForInOrForOfStatement(n) {
- var preStatementState = currentReachabilityState;
- var postStatementLabel = pushImplicitLabel();
- // bind expressions (don't affect reachability)
- bind(n.initializer);
- bind(n.expression);
- bind(n.statement);
- popImplicitLabel(postStatementLabel, preStatementState);
- }
- function bindIfStatement(n) {
- // denotes reachability state when entering 'thenStatement' part of the if statement:
- // i.e. if condition is false then thenStatement is unreachable
- var ifTrueState = n.expression.kind === 84 /* FalseKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
- // denotes reachability state when entering 'elseStatement':
- // i.e. if condition is true then elseStatement is unreachable
- var ifFalseState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
- currentReachabilityState = ifTrueState;
- // bind expression (don't affect reachability)
- bind(n.expression);
- bind(n.thenStatement);
- if (n.elseStatement) {
- var preElseState = currentReachabilityState;
- currentReachabilityState = ifFalseState;
- bind(n.elseStatement);
- currentReachabilityState = or(currentReachabilityState, preElseState);
- }
- else {
- currentReachabilityState = or(currentReachabilityState, ifFalseState);
- }
- }
- function bindReturnOrThrow(n) {
- // bind expression (don't affect reachability)
- bind(n.expression);
- if (n.kind === 204 /* ReturnStatement */) {
- hasExplicitReturn = true;
- }
- currentReachabilityState = 4 /* Unreachable */;
- }
- function bindBreakOrContinueStatement(n) {
- // call bind on label (don't affect reachability)
- bind(n.label);
- // for continue case touch label so it will be marked a used
- var isValidJump = jumpToLabel(n.label, n.kind === 203 /* BreakStatement */ ? currentReachabilityState : 4 /* Unreachable */);
- if (isValidJump) {
- currentReachabilityState = 4 /* Unreachable */;
- }
- }
- function bindTryStatement(n) {
- // catch\finally blocks has the same reachability as try block
- var preTryState = currentReachabilityState;
- bind(n.tryBlock);
- var postTryState = currentReachabilityState;
- currentReachabilityState = preTryState;
- bind(n.catchClause);
- var postCatchState = currentReachabilityState;
- currentReachabilityState = preTryState;
- bind(n.finallyBlock);
- // post catch/finally state is reachable if
- // - post try state is reachable - control flow can fall out of try block
- // - post catch state is reachable - control flow can fall out of catch block
- currentReachabilityState = or(postTryState, postCatchState);
- }
- function bindSwitchStatement(n) {
- var preSwitchState = currentReachabilityState;
- var postSwitchLabel = pushImplicitLabel();
- // bind expression (don't affect reachability)
- bind(n.expression);
- bind(n.caseBlock);
- var hasDefault = ts.forEach(n.caseBlock.clauses, function (c) { return c.kind === 242 /* DefaultClause */; });
- // post switch state is unreachable if switch is exaustive (has a default case ) and does not have fallthrough from the last case
- var postSwitchState = hasDefault && currentReachabilityState !== 2 /* Reachable */ ? 4 /* Unreachable */ : preSwitchState;
- popImplicitLabel(postSwitchLabel, postSwitchState);
- }
- function bindCaseBlock(n) {
- var startState = currentReachabilityState;
- for (var _i = 0, _a = n.clauses; _i < _a.length; _i++) {
- var clause = _a[_i];
- currentReachabilityState = startState;
- bind(clause);
- if (clause.statements.length && currentReachabilityState === 2 /* Reachable */ && options.noFallthroughCasesInSwitch) {
- errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
- }
- }
- }
- function bindLabeledStatement(n) {
- // call bind on label (don't affect reachability)
- bind(n.label);
- var ok = pushNamedLabel(n.label);
- bind(n.statement);
- if (ok) {
- popNamedLabel(n.label, currentReachabilityState);
- }
- }
- function getContainerFlags(node) {
- switch (node.kind) {
- case 186 /* ClassExpression */:
- case 214 /* ClassDeclaration */:
- case 215 /* InterfaceDeclaration */:
- case 217 /* EnumDeclaration */:
- case 155 /* TypeLiteral */:
- case 165 /* ObjectLiteralExpression */:
- return 1 /* IsContainer */;
- case 147 /* CallSignature */:
- case 148 /* ConstructSignature */:
- case 149 /* IndexSignature */:
- case 143 /* MethodDeclaration */:
- case 142 /* MethodSignature */:
- case 213 /* FunctionDeclaration */:
- case 144 /* Constructor */:
- case 145 /* GetAccessor */:
- case 146 /* SetAccessor */:
- case 152 /* FunctionType */:
- case 153 /* ConstructorType */:
- case 173 /* FunctionExpression */:
- case 174 /* ArrowFunction */:
- case 218 /* ModuleDeclaration */:
- case 248 /* SourceFile */:
- case 216 /* TypeAliasDeclaration */:
- return 5 /* IsContainerWithLocals */;
- case 244 /* CatchClause */:
- case 199 /* ForStatement */:
- case 200 /* ForInStatement */:
- case 201 /* ForOfStatement */:
- case 220 /* CaseBlock */:
- return 2 /* IsBlockScopedContainer */;
- case 192 /* Block */:
- // do not treat blocks directly inside a function as a block-scoped-container.
- // Locals that reside in this block should go to the function locals. Othewise 'x'
- // would not appear to be a redeclaration of a block scoped local in the following
- // example:
- //
- // function foo() {
- // var x;
- // let x;
- // }
- //
- // If we placed 'var x' into the function locals and 'let x' into the locals of
- // the block, then there would be no collision.
- //
- // By not creating a new block-scoped-container here, we ensure that both 'var x'
- // and 'let x' go into the Function-container's locals, and we do get a collision
- // conflict.
- return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
- }
- return 0 /* None */;
- }
- function addToContainerChain(next) {
- if (lastContainer) {
- lastContainer.nextContainer = next;
- }
- lastContainer = next;
- }
- function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
- // Just call this directly so that the return type of this function stays "void".
- declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes);
- }
- function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) {
- switch (container.kind) {
- // Modules, source files, and classes need specialized handling for how their
- // members are declared (for example, a member of a class will go into a specific
- // symbol table depending on if it is static or not). We defer to specialized
- // handlers to take care of declaring these child members.
- case 218 /* ModuleDeclaration */:
- return declareModuleMember(node, symbolFlags, symbolExcludes);
- case 248 /* SourceFile */:
- return declareSourceFileMember(node, symbolFlags, symbolExcludes);
- case 186 /* ClassExpression */:
- case 214 /* ClassDeclaration */:
- return declareClassMember(node, symbolFlags, symbolExcludes);
- case 217 /* EnumDeclaration */:
- return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- case 155 /* TypeLiteral */:
- case 165 /* ObjectLiteralExpression */:
- case 215 /* InterfaceDeclaration */:
- // Interface/Object-types always have their children added to the 'members' of
- // their container. They are only accessible through an instance of their
- // container, and are never in scope otherwise (even inside the body of the
- // object / type / interface declaring them). An exception is type parameters,
- // which are in scope without qualification (similar to 'locals').
- return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
- case 152 /* FunctionType */:
- case 153 /* ConstructorType */:
- case 147 /* CallSignature */:
- case 148 /* ConstructSignature */:
- case 149 /* IndexSignature */:
- case 143 /* MethodDeclaration */:
- case 142 /* MethodSignature */:
- case 144 /* Constructor */:
- case 145 /* GetAccessor */:
- case 146 /* SetAccessor */:
- case 213 /* FunctionDeclaration */:
- case 173 /* FunctionExpression */:
- case 174 /* ArrowFunction */:
- case 216 /* TypeAliasDeclaration */:
- // All the children of these container types are never visible through another
- // symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
- // they're only accessed 'lexically' (i.e. from code that exists underneath
- // their container in the tree. To accomplish this, we simply add their declared
- // symbol to the 'locals' of the container. These symbols can then be found as
- // the type checker walks up the containers, checking them for matching names.
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- }
- function declareClassMember(node, symbolFlags, symbolExcludes) {
- return node.flags & 64 /* Static */
- ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
- : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
- }
- function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
- return ts.isExternalModule(file)
- ? declareModuleMember(node, symbolFlags, symbolExcludes)
- : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- function hasExportDeclarations(node) {
- var body = node.kind === 248 /* SourceFile */ ? node : node.body;
- if (body.kind === 248 /* SourceFile */ || body.kind === 219 /* ModuleBlock */) {
- for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
- var stat = _a[_i];
- if (stat.kind === 228 /* ExportDeclaration */ || stat.kind === 227 /* ExportAssignment */) {
- return true;
- }
- }
- }
- return false;
- }
- function setExportContextFlag(node) {
- // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
- // declarations with export modifiers) is an export context in which declarations are implicitly exported.
- if (ts.isInAmbientContext(node) && !hasExportDeclarations(node)) {
- node.flags |= 131072 /* ExportContext */;
- }
- else {
- node.flags &= ~131072 /* ExportContext */;
- }
- }
- function bindModuleDeclaration(node) {
- setExportContextFlag(node);
- if (node.name.kind === 9 /* StringLiteral */) {
- declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
- }
- else {
- var state = getModuleInstanceState(node);
- if (state === 0 /* NonInstantiated */) {
- declareSymbolAndAddToSymbolTable(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */);
- }
- else {
- declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
- if (node.symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)) {
- // if module was already merged with some function, class or non-const enum
- // treat is a non-const-enum-only
- node.symbol.constEnumOnlyModule = false;
- }
- else {
- var currentModuleIsConstEnumOnly = state === 2 /* ConstEnumOnly */;
- if (node.symbol.constEnumOnlyModule === undefined) {
- // non-merged case - use the current state
- node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
- }
- else {
- // merged case: module is const enum only if all its pieces are non-instantiated or const enum
- node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
- }
- }
- }
- }
- }
- function bindFunctionOrConstructorType(node) {
- // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
- // to the one we would get for: { <...>(...): T }
- //
- // We do that by making an anonymous type literal symbol, and then setting the function
- // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
- // from an actual type literal symbol you would have gotten had you used the long form.
- var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node));
- addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
- var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type");
- addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
- typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a);
- var _a;
- }
- function bindObjectLiteralExpression(node) {
- var ElementKind;
- (function (ElementKind) {
- ElementKind[ElementKind["Property"] = 1] = "Property";
- ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
- })(ElementKind || (ElementKind = {}));
- if (inStrictMode) {
- var seen = {};
- for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
- var prop = _a[_i];
- if (prop.name.kind !== 69 /* Identifier */) {
- continue;
- }
- var identifier = prop.name;
- // ECMA-262 11.1.5 Object Initialiser
- // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
- // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
- // IsDataDescriptor(propId.descriptor) is true.
- // b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
- // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
- // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
- // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
- var currentKind = prop.kind === 245 /* PropertyAssignment */ || prop.kind === 246 /* ShorthandPropertyAssignment */ || prop.kind === 143 /* MethodDeclaration */
- ? 1 /* Property */
- : 2 /* Accessor */;
- var existingKind = seen[identifier.text];
- if (!existingKind) {
- seen[identifier.text] = currentKind;
- continue;
- }
- if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
- var span = ts.getErrorSpanForNode(file, identifier);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
- }
- }
- }
- return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object");
- }
- function bindAnonymousDeclaration(node, symbolFlags, name) {
- var symbol = createSymbol(symbolFlags, name);
- addDeclarationToSymbol(symbol, node, symbolFlags);
- }
- function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
- switch (blockScopeContainer.kind) {
- case 218 /* ModuleDeclaration */:
- declareModuleMember(node, symbolFlags, symbolExcludes);
- break;
- case 248 /* SourceFile */:
- if (ts.isExternalModule(container)) {
- declareModuleMember(node, symbolFlags, symbolExcludes);
- break;
- }
- // fall through.
- default:
- if (!blockScopeContainer.locals) {
- blockScopeContainer.locals = {};
- addToContainerChain(blockScopeContainer);
- }
- declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- }
- function bindBlockScopedVariableDeclaration(node) {
- bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
- }
- // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
- // check for reserved words used as identifiers in strict mode code.
- function checkStrictModeIdentifier(node) {
- if (inStrictMode &&
- node.originalKeywordKind >= 106 /* FirstFutureReservedWord */ &&
- node.originalKeywordKind <= 114 /* LastFutureReservedWord */ &&
- !ts.isIdentifierName(node)) {
- // Report error only if there are no parse errors in file
- if (!file.parseDiagnostics.length) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
- }
- }
- }
- function getStrictModeIdentifierMessage(node) {
- // Provide specialized messages to help the user understand why we think they're in
- // strict mode.
- if (ts.getContainingClass(node)) {
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
- }
- if (file.externalModuleIndicator) {
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
- }
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
- }
- function checkStrictModeBinaryExpression(node) {
- if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
- // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
- // Assignment operator(11.13) or of a PostfixExpression(11.3)
- checkStrictModeEvalOrArguments(node, node.left);
- }
- }
- function checkStrictModeCatchClause(node) {
- // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
- // Catch production is eval or arguments
- if (inStrictMode && node.variableDeclaration) {
- checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
- }
- }
- function checkStrictModeDeleteExpression(node) {
- // Grammar checking
- if (inStrictMode && node.expression.kind === 69 /* Identifier */) {
- // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
- // UnaryExpression is a direct reference to a variable, function argument, or function name
- var span = ts.getErrorSpanForNode(file, node.expression);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
- }
- }
- function isEvalOrArgumentsIdentifier(node) {
- return node.kind === 69 /* Identifier */ &&
- (node.text === "eval" || node.text === "arguments");
- }
- function checkStrictModeEvalOrArguments(contextNode, name) {
- if (name && name.kind === 69 /* Identifier */) {
- var identifier = name;
- if (isEvalOrArgumentsIdentifier(identifier)) {
- // We check first if the name is inside class declaration or class expression; if so give explicit message
- // otherwise report generic error message.
- var span = ts.getErrorSpanForNode(file, name);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
- }
- }
- }
- function getStrictModeEvalOrArgumentsMessage(node) {
- // Provide specialized messages to help the user understand why we think they're in
- // strict mode.
- if (ts.getContainingClass(node)) {
- return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
- }
- if (file.externalModuleIndicator) {
- return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
- }
- return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
- }
- function checkStrictModeFunctionName(node) {
- if (inStrictMode) {
- // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
- checkStrictModeEvalOrArguments(node, node.name);
- }
- }
- function checkStrictModeNumericLiteral(node) {
- if (inStrictMode && node.flags & 32768 /* OctalLiteral */) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
- }
- }
- function checkStrictModePostfixUnaryExpression(node) {
- // Grammar checking
- // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
- // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
- // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
- if (inStrictMode) {
- checkStrictModeEvalOrArguments(node, node.operand);
- }
- }
- function checkStrictModePrefixUnaryExpression(node) {
- // Grammar checking
- if (inStrictMode) {
- if (node.operator === 41 /* PlusPlusToken */ || node.operator === 42 /* MinusMinusToken */) {
- checkStrictModeEvalOrArguments(node, node.operand);
- }
- }
- }
- function checkStrictModeWithStatement(node) {
- // Grammar checking for withStatement
- if (inStrictMode) {
- errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
- }
- }
- function errorOnFirstToken(node, message, arg0, arg1, arg2) {
- var span = ts.getSpanOfTokenAtPosition(file, node.pos);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
- }
- function getDestructuringParameterName(node) {
- return "__" + ts.indexOf(node.parent.parameters, node);
- }
- function bind(node) {
- if (!node) {
- return;
- }
- node.parent = parent;
- var savedInStrictMode = inStrictMode;
- if (!savedInStrictMode) {
- updateStrictMode(node);
- }
- // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
- // and then potentially add the symbol to an appropriate symbol table. Possible
- // destination symbol tables are:
- //
- // 1) The 'exports' table of the current container's symbol.
- // 2) The 'members' table of the current container's symbol.
- // 3) The 'locals' table of the current container.
- //
- // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
- // (like TypeLiterals for example) will not be put in any table.
- bindWorker(node);
- // Then we recurse into the children of the node to bind them as well. For certain
- // symbols we do specialized work when we recurse. For example, we'll keep track of
- // the current 'container' node when it changes. This helps us know which symbol table
- // a local should go into for example.
- bindChildren(node);
- inStrictMode = savedInStrictMode;
- }
- function updateStrictMode(node) {
- switch (node.kind) {
- case 248 /* SourceFile */:
- case 219 /* ModuleBlock */:
- updateStrictModeStatementList(node.statements);
- return;
- case 192 /* Block */:
- if (ts.isFunctionLike(node.parent)) {
- updateStrictModeStatementList(node.statements);
- }
- return;
- case 214 /* ClassDeclaration */:
- case 186 /* ClassExpression */:
- // All classes are automatically in strict mode in ES6.
- inStrictMode = true;
- return;
- }
- }
- function updateStrictModeStatementList(statements) {
- for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
- var statement = statements_1[_i];
- if (!ts.isPrologueDirective(statement)) {
- return;
- }
- if (isUseStrictPrologueDirective(statement)) {
- inStrictMode = true;
- return;
- }
- }
- }
- /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
- function isUseStrictPrologueDirective(node) {
- var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression);
- // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
- // string to contain unicode escapes (as per ES5).
- return nodeText === "\"use strict\"" || nodeText === "'use strict'";
- }
- function bindWorker(node) {
- switch (node.kind) {
- case 69 /* Identifier */:
- return checkStrictModeIdentifier(node);
- case 181 /* BinaryExpression */:
- return checkStrictModeBinaryExpression(node);
- case 244 /* CatchClause */:
- return checkStrictModeCatchClause(node);
- case 175 /* DeleteExpression */:
- return checkStrictModeDeleteExpression(node);
- case 8 /* NumericLiteral */:
- return checkStrictModeNumericLiteral(node);
- case 180 /* PostfixUnaryExpression */:
- return checkStrictModePostfixUnaryExpression(node);
- case 179 /* PrefixUnaryExpression */:
- return checkStrictModePrefixUnaryExpression(node);
- case 205 /* WithStatement */:
- return checkStrictModeWithStatement(node);
- case 97 /* ThisKeyword */:
- seenThisKeyword = true;
- return;
- case 137 /* TypeParameter */:
- return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */);
- case 138 /* Parameter */:
- return bindParameter(node);
- case 211 /* VariableDeclaration */:
- case 163 /* BindingElement */:
- return bindVariableDeclarationOrBindingElement(node);
- case 141 /* PropertyDeclaration */:
- case 140 /* PropertySignature */:
- return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 107455 /* PropertyExcludes */);
- case 245 /* PropertyAssignment */:
- case 246 /* ShorthandPropertyAssignment */:
- return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */);
- case 247 /* EnumMember */:
- return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */);
- case 147 /* CallSignature */:
- case 148 /* ConstructSignature */:
- case 149 /* IndexSignature */:
- return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
- case 143 /* MethodDeclaration */:
- case 142 /* MethodSignature */:
- // If this is an ObjectLiteralExpression method, then it sits in the same space
- // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes
- // so that it will conflict with any other object literal members with the same
- // name.
- return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */);
- case 213 /* FunctionDeclaration */:
- checkStrictModeFunctionName(node);
- return declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */);
- case 144 /* Constructor */:
- return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
- case 145 /* GetAccessor */:
- return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */);
- case 146 /* SetAccessor */:
- return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */);
- case 152 /* FunctionType */:
- case 153 /* ConstructorType */:
- return bindFunctionOrConstructorType(node);
- case 155 /* TypeLiteral */:
- return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type");
- case 165 /* ObjectLiteralExpression */:
- return bindObjectLiteralExpression(node);
- case 173 /* FunctionExpression */:
- case 174 /* ArrowFunction */:
- checkStrictModeFunctionName(node);
- var bindingName = node.name ? node.name.text : "__function";
- return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
- case 186 /* ClassExpression */:
- case 214 /* ClassDeclaration */:
- return bindClassLikeDeclaration(node);
- case 215 /* InterfaceDeclaration */:
- return bindBlockScopedDeclaration(node, 64 /* Interface */, 792960 /* InterfaceExcludes */);
- case 216 /* TypeAliasDeclaration */:
- return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */);
- case 217 /* EnumDeclaration */:
- return bindEnumDeclaration(node);
- case 218 /* ModuleDeclaration */:
- return bindModuleDeclaration(node);
- case 221 /* ImportEqualsDeclaration */:
- case 224 /* NamespaceImport */:
- case 226 /* ImportSpecifier */:
- case 230 /* ExportSpecifier */:
- return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
- case 223 /* ImportClause */:
- return bindImportClause(node);
- case 228 /* ExportDeclaration */:
- return bindExportDeclaration(node);
- case 227 /* ExportAssignment */:
- return bindExportAssignment(node);
- case 248 /* SourceFile */:
- return bindSourceFileIfExternalModule();
- }
- }
- function bindSourceFileIfExternalModule() {
- setExportContextFlag(file);
- if (ts.isExternalModule(file)) {
- bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
- }
- }
- function bindExportAssignment(node) {
- if (!container.symbol || !container.symbol.exports) {
- // Export assignment in some sort of block construct
- bindAnonymousDeclaration(node, 8388608 /* Alias */, getDeclarationName(node));
- }
- else if (node.expression.kind === 69 /* Identifier */) {
- // An export default clause with an identifier exports all meanings of that identifier
- declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
- }
- else {
- // An export default clause with an expression exports a value
- declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
- }
- }
- function bindExportDeclaration(node) {
- if (!container.symbol || !container.symbol.exports) {
- // Export * in some sort of block construct
- bindAnonymousDeclaration(node, 1073741824 /* ExportStar */, getDeclarationName(node));
- }
- else if (!node.exportClause) {
- // All export * declarations are collected in an __export symbol
- declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0 /* None */);
- }
- }
- function bindImportClause(node) {
- if (node.name) {
- declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
- }
- }
- function bindClassLikeDeclaration(node) {
- if (node.kind === 214 /* ClassDeclaration */) {
- bindBlockScopedDeclaration(node, 32 /* Class */, 899519 /* ClassExcludes */);
- }
- else {
- var bindingName = node.name ? node.name.text : "__class";
- bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
- // Add name of class expression into the map for semantic classifier
- if (node.name) {
- classifiableNames[node.name.text] = node.name.text;
- }
- }
- var symbol = node.symbol;
- // TypeScript 1.0 spec (April 2014): 8.4
- // Every class automatically contains a static property member named 'prototype', the
- // type of which is an instantiation of the class type with type Any supplied as a type
- // argument for each type parameter. It is an error to explicitly declare a static
- // property member with the name 'prototype'.
- //
- // Note: we check for this here because this class may be merging into a module. The
- // module might have an exported variable called 'prototype'. We can't allow that as
- // that would clash with the built-in 'prototype' for the class.
- var prototypeSymbol = createSymbol(4 /* Property */ | 134217728 /* Prototype */, "prototype");
- if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) {
- if (node.name) {
- node.name.parent = node;
- }
- file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
- }
- symbol.exports[prototypeSymbol.name] = prototypeSymbol;
- prototypeSymbol.parent = symbol;
- }
- function bindEnumDeclaration(node) {
- return ts.isConst(node)
- ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */)
- : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */);
- }
- function bindVariableDeclarationOrBindingElement(node) {
- if (inStrictMode) {
- checkStrictModeEvalOrArguments(node, node.name);
- }
- if (!ts.isBindingPattern(node.name)) {
- if (ts.isBlockOrCatchScoped(node)) {
- bindBlockScopedVariableDeclaration(node);
- }
- else if (ts.isParameterDeclaration(node)) {
- // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
- // because its parent chain has already been set up, since parents are set before descending into children.
- //
- // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
- // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
- // For example:
- // function foo([a,a]) {} // Duplicate Identifier error
- // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
- // // which correctly set excluded symbols
- declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
- }
- else {
- declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */);
- }
- }
- }
- function bindParameter(node) {
- if (inStrictMode) {
- // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
- // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
- checkStrictModeEvalOrArguments(node, node.name);
- }
- if (ts.isBindingPattern(node.name)) {
- bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, getDestructuringParameterName(node));
- }
- else {
- declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
- }
- // If this is a property-parameter, then also declare the property symbol into the
- // containing class.
- if (node.flags & 56 /* AccessibilityModifier */ &&
- node.parent.kind === 144 /* Constructor */ &&
- ts.isClassLike(node.parent.parent)) {
- var classDeclaration = node.parent.parent;
- declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */);
- }
- }
- function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
- return ts.hasDynamicName(node)
- ? bindAnonymousDeclaration(node, symbolFlags, "__computed")
- : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
- }
- // reachability checks
- function pushNamedLabel(name) {
- initializeReachabilityStateIfNecessary();
- if (ts.hasProperty(labelIndexMap, name.text)) {
- return false;
- }
- labelIndexMap[name.text] = labelStack.push(1 /* Unintialized */) - 1;
- return true;
- }
- function pushImplicitLabel() {
- initializeReachabilityStateIfNecessary();
- var index = labelStack.push(1 /* Unintialized */) - 1;
- implicitLabels.push(index);
- return index;
- }
- function popNamedLabel(label, outerState) {
- var index = labelIndexMap[label.text];
- ts.Debug.assert(index !== undefined);
- ts.Debug.assert(labelStack.length == index + 1);
- labelIndexMap[label.text] = undefined;
- setCurrentStateAtLabel(labelStack.pop(), outerState, label);
- }
- function popImplicitLabel(implicitLabelIndex, outerState) {
- if (labelStack.length !== implicitLabelIndex + 1) {
- ts.Debug.assert(false, "Label stack: " + labelStack.length + ", index:" + implicitLabelIndex);
- }
- var i = implicitLabels.pop();
- if (implicitLabelIndex !== i) {
- ts.Debug.assert(false, "i: " + i + ", index: " + implicitLabelIndex);
- }
- setCurrentStateAtLabel(labelStack.pop(), outerState, /*name*/ undefined);
- }
- function setCurrentStateAtLabel(innerMergedState, outerState, label) {
- if (innerMergedState === 1 /* Unintialized */) {
- if (label && !options.allowUnusedLabels) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(label, ts.Diagnostics.Unused_label));
- }
- currentReachabilityState = outerState;
- }
- else {
- currentReachabilityState = or(innerMergedState, outerState);
- }
- }
- function jumpToLabel(label, outerState) {
- initializeReachabilityStateIfNecessary();
- var index = label ? labelIndexMap[label.text] : ts.lastOrUndefined(implicitLabels);
- if (index === undefined) {
- // reference to unknown label or
- // break/continue used outside of loops
- return false;
- }
- var stateAtLabel = labelStack[index];
- labelStack[index] = stateAtLabel === 1 /* Unintialized */ ? outerState : or(stateAtLabel, outerState);
- return true;
- }
- function checkUnreachable(node) {
- switch (currentReachabilityState) {
- case 4 /* Unreachable */:
- var reportError =
- // report error on all statements
- ts.isStatement(node) ||
- // report error on class declarations
- node.kind === 214 /* ClassDeclaration */ ||
- // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
- (node.kind === 218 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node)) ||
- // report error on regular enums and const enums if preserveConstEnums is set
- (node.kind === 217 /* EnumDeclaration */ && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
- if (reportError) {
- currentReachabilityState = 8 /* ReportedUnreachable */;
- // unreachable code is reported if
- // - user has explicitly asked about it AND
- // - statement is in not ambient context (statements in ambient context is already an error
- // so we should not report extras) AND
- // - node is not variable statement OR
- // - node is block scoped variable statement OR
- // - node is not block scoped variable statement and at least one variable declaration has initializer
- // Rationale: we don't want to report errors on non-initialized var's since they are hoisted
- // On the other side we do want to report errors on non-initialized 'lets' because of TDZ
- var reportUnreachableCode = !options.allowUnreachableCode &&
- !ts.isInAmbientContext(node) &&
- (node.kind !== 193 /* VariableStatement */ ||
- ts.getCombinedNodeFlags(node.declarationList) & 24576 /* BlockScoped */ ||
- ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
- if (reportUnreachableCode) {
- errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
- }
- }
- case 8 /* ReportedUnreachable */:
- return true;
- default:
- return false;
- }
- function shouldReportErrorOnModuleDeclaration(node) {
- var instanceState = getModuleInstanceState(node);
- return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && options.preserveConstEnums);
- }
- }
- function initializeReachabilityStateIfNecessary() {
- if (labelIndexMap) {
- return;
- }
- currentReachabilityState = 2 /* Reachable */;
- labelIndexMap = {};
- labelStack = [];
- implicitLabels = [];
- }
- }
-})(ts || (ts = {}));
-///
-///
-/* @internal */
-var ts;
-(function (ts) {
- function getDeclarationOfKind(symbol, kind) {
- var declarations = symbol.declarations;
- if (declarations) {
- for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
- var declaration = declarations_1[_i];
- if (declaration.kind === kind) {
- return declaration;
- }
- }
- }
- return undefined;
- }
- ts.getDeclarationOfKind = getDeclarationOfKind;
- // Pool writers to avoid needing to allocate them for every symbol we write.
- var stringWriters = [];
- function getSingleLineStringWriter() {
- if (stringWriters.length === 0) {
- var str = "";
- var writeText = function (text) { return str += text; };
- return {
- string: function () { return str; },
- writeKeyword: writeText,
- writeOperator: writeText,
- writePunctuation: writeText,
- writeSpace: writeText,
- writeStringLiteral: writeText,
- writeParameter: writeText,
- writeSymbol: writeText,
- // Completely ignore indentation for string writers. And map newlines to
- // a single space.
- writeLine: function () { return str += " "; },
- increaseIndent: function () { },
- decreaseIndent: function () { },
- clear: function () { return str = ""; },
- trackSymbol: function () { },
- reportInaccessibleThisError: function () { }
- };
- }
- return stringWriters.pop();
- }
- ts.getSingleLineStringWriter = getSingleLineStringWriter;
- function releaseStringWriter(writer) {
- writer.clear();
- stringWriters.push(writer);
- }
- ts.releaseStringWriter = releaseStringWriter;
- function getFullWidth(node) {
- return node.end - node.pos;
- }
- ts.getFullWidth = getFullWidth;
- function arrayIsEqualTo(array1, array2, equaler) {
- if (!array1 || !array2) {
- return array1 === array2;
- }
- if (array1.length !== array2.length) {
- return false;
- }
- for (var i = 0; i < array1.length; ++i) {
- var equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
- if (!equals) {
- return false;
- }
- }
- return true;
- }
- ts.arrayIsEqualTo = arrayIsEqualTo;
- function hasResolvedModule(sourceFile, moduleNameText) {
- return sourceFile.resolvedModules && ts.hasProperty(sourceFile.resolvedModules, moduleNameText);
- }
- ts.hasResolvedModule = hasResolvedModule;
- function getResolvedModule(sourceFile, moduleNameText) {
- return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
- }
- ts.getResolvedModule = getResolvedModule;
- function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
- if (!sourceFile.resolvedModules) {
- sourceFile.resolvedModules = {};
- }
- sourceFile.resolvedModules[moduleNameText] = resolvedModule;
- }
- ts.setResolvedModule = setResolvedModule;
- // Returns true if this node contains a parse error anywhere underneath it.
- function containsParseError(node) {
- aggregateChildData(node);
- return (node.parserContextFlags & 64 /* ThisNodeOrAnySubNodesHasError */) !== 0;
- }
- ts.containsParseError = containsParseError;
- function aggregateChildData(node) {
- if (!(node.parserContextFlags & 128 /* HasAggregatedChildData */)) {
- // A node is considered to contain a parse error if:
- // a) the parser explicitly marked that it had an error
- // b) any of it's children reported that it had an error.
- var thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & 16 /* ThisNodeHasError */) !== 0) ||
- ts.forEachChild(node, containsParseError);
- // If so, mark ourselves accordingly.
- if (thisNodeOrAnySubNodesHasError) {
- node.parserContextFlags |= 64 /* ThisNodeOrAnySubNodesHasError */;
- }
- // Also mark that we've propogated the child information to this node. This way we can
- // always consult the bit directly on this node without needing to check its children
- // again.
- node.parserContextFlags |= 128 /* HasAggregatedChildData */;
- }
- }
- function getSourceFileOfNode(node) {
- while (node && node.kind !== 248 /* SourceFile */) {
- node = node.parent;
- }
- return node;
- }
- ts.getSourceFileOfNode = getSourceFileOfNode;
- function getStartPositionOfLine(line, sourceFile) {
- ts.Debug.assert(line >= 0);
- return ts.getLineStarts(sourceFile)[line];
- }
- ts.getStartPositionOfLine = getStartPositionOfLine;
- // This is a useful function for debugging purposes.
- function nodePosToString(node) {
- var file = getSourceFileOfNode(node);
- var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
- return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
- }
- ts.nodePosToString = nodePosToString;
- function getStartPosOfNode(node) {
- return node.pos;
- }
- ts.getStartPosOfNode = getStartPosOfNode;
- // Returns true if this node is missing from the actual source code. A 'missing' node is different
- // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
- // in the tree), it is definitely missing. However, a node may be defined, but still be
- // missing. This happens whenever the parser knows it needs to parse something, but can't
- // get anything in the source code that it expects at that location. For example:
- //
- // let a: ;
- //
- // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
- // code). So the parser will attempt to parse out a type, and will create an actual node.
- // However, this node will be 'missing' in the sense that no actual source-code/tokens are
- // contained within it.
- function nodeIsMissing(node) {
- if (!node) {
- return true;
- }
- return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
- }
- ts.nodeIsMissing = nodeIsMissing;
- function nodeIsPresent(node) {
- return !nodeIsMissing(node);
- }
- ts.nodeIsPresent = nodeIsPresent;
- function getTokenPosOfNode(node, sourceFile) {
- // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
- // want to skip trivia because this will launch us forward to the next token.
- if (nodeIsMissing(node)) {
- return node.pos;
- }
- return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
- }
- ts.getTokenPosOfNode = getTokenPosOfNode;
- function getNonDecoratorTokenPosOfNode(node, sourceFile) {
- if (nodeIsMissing(node) || !node.decorators) {
- return getTokenPosOfNode(node, sourceFile);
- }
- return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
- }
- ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
- function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
- if (includeTrivia === void 0) { includeTrivia = false; }
- if (nodeIsMissing(node)) {
- return "";
- }
- var text = sourceFile.text;
- return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end);
- }
- ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
- function getTextOfNodeFromSourceText(sourceText, node) {
- if (nodeIsMissing(node)) {
- return "";
- }
- return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
- }
- ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
- function getTextOfNode(node, includeTrivia) {
- if (includeTrivia === void 0) { includeTrivia = false; }
- return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
- }
- ts.getTextOfNode = getTextOfNode;
- // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
- function escapeIdentifier(identifier) {
- return identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier;
- }
- ts.escapeIdentifier = escapeIdentifier;
- // Remove extra underscore from escaped identifier
- function unescapeIdentifier(identifier) {
- return identifier.length >= 3 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ && identifier.charCodeAt(2) === 95 /* _ */ ? identifier.substr(1) : identifier;
- }
- ts.unescapeIdentifier = unescapeIdentifier;
- // Make an identifier from an external module name by extracting the string after the last "/" and replacing
- // all non-alphanumeric characters with underscores
- function makeIdentifierFromModuleName(moduleName) {
- return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
- }
- ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
- function isBlockOrCatchScoped(declaration) {
- return (getCombinedNodeFlags(declaration) & 24576 /* BlockScoped */) !== 0 ||
- isCatchClauseVariableDeclaration(declaration);
- }
- ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
- // Gets the nearest enclosing block scope container that has the provided node
- // as a descendant, that is not the provided node.
- function getEnclosingBlockScopeContainer(node) {
- var current = node.parent;
- while (current) {
- if (isFunctionLike(current)) {
- return current;
- }
- switch (current.kind) {
- case 248 /* SourceFile */:
- case 220 /* CaseBlock */:
- case 244 /* CatchClause */:
- case 218 /* ModuleDeclaration */:
- case 199 /* ForStatement */:
- case 200 /* ForInStatement */:
- case 201 /* ForOfStatement */:
- return current;
- case 192 /* Block */:
- // function block is not considered block-scope container
- // see comment in binder.ts: bind(...), case for SyntaxKind.Block
- if (!isFunctionLike(current.parent)) {
- return current;
- }
- }
- current = current.parent;
+ current = current.parent;
}
}
ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
@@ -5812,6 +4503,10 @@ var ts;
return file.externalModuleIndicator !== undefined;
}
ts.isExternalModule = isExternalModule;
+ function isExternalOrCommonJsModule(file) {
+ return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
+ }
+ ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
function isDeclarationFile(file) {
return (file.flags & 4096 /* DeclarationFile */) !== 0;
}
@@ -5865,19 +4560,27 @@ var ts;
return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
}
ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
+ function getLeadingCommentRangesOfNodeFromText(node, text) {
+ return ts.getLeadingCommentRanges(text, node.pos);
+ }
+ ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText;
function getJsDocComments(node, sourceFileOfNode) {
+ return getJsDocCommentsFromText(node, sourceFileOfNode.text);
+ }
+ ts.getJsDocComments = getJsDocComments;
+ function getJsDocCommentsFromText(node, text) {
var commentRanges = (node.kind === 138 /* Parameter */ || node.kind === 137 /* TypeParameter */) ?
- ts.concatenate(ts.getTrailingCommentRanges(sourceFileOfNode.text, node.pos), ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) :
- getLeadingCommentRangesOfNode(node, sourceFileOfNode);
+ ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
+ getLeadingCommentRangesOfNodeFromText(node, text);
return ts.filter(commentRanges, isJsDocComment);
function isJsDocComment(comment) {
// True if the comment starts with '/**' but not if it is '/**/'
- return sourceFileOfNode.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
- sourceFileOfNode.text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
- sourceFileOfNode.text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
+ return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
+ text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
+ text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
}
}
- ts.getJsDocComments = getJsDocComments;
+ ts.getJsDocCommentsFromText = getJsDocCommentsFromText;
ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/;
ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/;
function isTypeNode(node) {
@@ -6464,6 +5167,57 @@ var ts;
return node.kind === 221 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 232 /* ExternalModuleReference */;
}
ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
+ function isSourceFileJavaScript(file) {
+ return isInJavaScriptFile(file);
+ }
+ ts.isSourceFileJavaScript = isSourceFileJavaScript;
+ function isInJavaScriptFile(node) {
+ return node && !!(node.parserContextFlags & 32 /* JavaScriptFile */);
+ }
+ ts.isInJavaScriptFile = isInJavaScriptFile;
+ /**
+ * Returns true if the node is a CallExpression to the identifier 'require' with
+ * exactly one string literal argument.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ function isRequireCall(expression) {
+ // of the form 'require("name")'
+ return expression.kind === 168 /* CallExpression */ &&
+ expression.expression.kind === 69 /* Identifier */ &&
+ expression.expression.text === "require" &&
+ expression.arguments.length === 1 &&
+ expression.arguments[0].kind === 9 /* StringLiteral */;
+ }
+ ts.isRequireCall = isRequireCall;
+ /**
+ * Returns true if the node is an assignment to a property on the identifier 'exports'.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ function isExportsPropertyAssignment(expression) {
+ // of the form 'exports.name = expr' where 'name' and 'expr' are arbitrary
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === 181 /* BinaryExpression */) &&
+ (expression.operatorToken.kind === 56 /* EqualsToken */) &&
+ (expression.left.kind === 166 /* PropertyAccessExpression */) &&
+ (expression.left.expression.kind === 69 /* Identifier */) &&
+ ((expression.left.expression).text === "exports");
+ }
+ ts.isExportsPropertyAssignment = isExportsPropertyAssignment;
+ /**
+ * Returns true if the node is an assignment to the property access expression 'module.exports'.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ function isModuleExportsAssignment(expression) {
+ // of the form 'module.exports = expr' where 'expr' is arbitrary
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === 181 /* BinaryExpression */) &&
+ (expression.operatorToken.kind === 56 /* EqualsToken */) &&
+ (expression.left.kind === 166 /* PropertyAccessExpression */) &&
+ (expression.left.expression.kind === 69 /* Identifier */) &&
+ ((expression.left.expression).text === "module") &&
+ (expression.left.name.text === "exports");
+ }
+ ts.isModuleExportsAssignment = isModuleExportsAssignment;
function getExternalModuleName(node) {
if (node.kind === 222 /* ImportDeclaration */) {
return node.moduleSpecifier;
@@ -6791,8 +5545,8 @@ var ts;
function getFileReferenceFromReferencePath(comment, commentRange) {
var simpleReferenceRegEx = /^\/\/\/\s*/gim;
- if (simpleReferenceRegEx.exec(comment)) {
- if (isNoDefaultLibRegEx.exec(comment)) {
+ if (simpleReferenceRegEx.test(comment)) {
+ if (isNoDefaultLibRegEx.test(comment)) {
return {
isNoDefaultLib: true
};
@@ -6834,6 +5588,10 @@ var ts;
return isFunctionLike(node) && (node.flags & 256 /* Async */) !== 0 && !isAccessor(node);
}
ts.isAsyncFunctionLike = isAsyncFunctionLike;
+ function isStringOrNumericLiteral(kind) {
+ return kind === 9 /* StringLiteral */ || kind === 8 /* NumericLiteral */;
+ }
+ ts.isStringOrNumericLiteral = isStringOrNumericLiteral;
/**
* A declaration has a dynamic name if both of the following are true:
* 1. The declaration has a computed property name
@@ -6842,11 +5600,15 @@ var ts;
* Symbol.
*/
function hasDynamicName(declaration) {
- return declaration.name &&
- declaration.name.kind === 136 /* ComputedPropertyName */ &&
- !isWellKnownSymbolSyntactically(declaration.name.expression);
+ return declaration.name && isDynamicName(declaration.name);
}
ts.hasDynamicName = hasDynamicName;
+ function isDynamicName(name) {
+ return name.kind === 136 /* ComputedPropertyName */ &&
+ !isStringOrNumericLiteral(name.expression.kind) &&
+ !isWellKnownSymbolSyntactically(name.expression);
+ }
+ ts.isDynamicName = isDynamicName;
/**
* Checks if the expression is of the form:
* Symbol.name
@@ -7087,11 +5849,11 @@ var ts;
}
ts.getIndentSize = getIndentSize;
function createTextWriter(newLine) {
- var output = "";
- var indent = 0;
- var lineStart = true;
- var lineCount = 0;
- var linePos = 0;
+ var output;
+ var indent;
+ var lineStart;
+ var lineCount;
+ var linePos;
function write(s) {
if (s && s.length) {
if (lineStart) {
@@ -7101,6 +5863,13 @@ var ts;
output += s;
}
}
+ function reset() {
+ output = "";
+ indent = 0;
+ lineStart = true;
+ lineCount = 0;
+ linePos = 0;
+ }
function rawWrite(s) {
if (s !== undefined) {
if (lineStart) {
@@ -7127,9 +5896,10 @@ var ts;
lineStart = true;
}
}
- function writeTextOfNode(sourceFile, node) {
- write(getSourceTextOfNodeFromSourceFile(sourceFile, node));
+ function writeTextOfNode(text, node) {
+ write(getTextOfNodeFromSourceText(text, node));
}
+ reset();
return {
write: write,
rawWrite: rawWrite,
@@ -7142,10 +5912,20 @@ var ts;
getTextPos: function () { return output.length; },
getLine: function () { return lineCount + 1; },
getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; },
- getText: function () { return output; }
+ getText: function () { return output; },
+ reset: reset
};
}
ts.createTextWriter = createTextWriter;
+ /**
+ * Resolves a local path to a path which is absolute to the base of the emit
+ */
+ function getExternalModuleNameFromPath(host, fileName) {
+ var dir = host.getCurrentDirectory();
+ var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, fileName, dir, function (f) { return host.getCanonicalFileName(f); }, /*isAbsolutePathAnUrl*/ false);
+ return ts.removeFileExtension(relativePath);
+ }
+ ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
function getOwnEmitOutputFilePath(sourceFile, host, extension) {
var compilerOptions = host.getCompilerOptions();
var emitOutputFilePathWithoutExtension;
@@ -7174,6 +5954,10 @@ var ts;
return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line;
}
ts.getLineOfLocalPosition = getLineOfLocalPosition;
+ function getLineOfLocalPositionFromLineMap(lineMap, pos) {
+ return ts.computeLineAndCharacterOfPosition(lineMap, pos).line;
+ }
+ ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
function getFirstConstructorWithBody(node) {
return ts.forEach(node.members, function (member) {
if (member.kind === 144 /* Constructor */ && nodeIsPresent(member.body)) {
@@ -7246,22 +6030,22 @@ var ts;
};
}
ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
- function emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments) {
+ function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
// If the leading comments start on different line than the start of node, write new line
if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
- getLineOfLocalPosition(currentSourceFile, node.pos) !== getLineOfLocalPosition(currentSourceFile, leadingComments[0].pos)) {
+ getLineOfLocalPositionFromLineMap(lineMap, node.pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
writer.writeLine();
}
}
ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
- function emitComments(currentSourceFile, writer, comments, trailingSeparator, newLine, writeComment) {
+ function emitComments(text, lineMap, writer, comments, trailingSeparator, newLine, writeComment) {
var emitLeadingSpace = !trailingSeparator;
ts.forEach(comments, function (comment) {
if (emitLeadingSpace) {
writer.write(" ");
emitLeadingSpace = false;
}
- writeComment(currentSourceFile, writer, comment, newLine);
+ writeComment(text, lineMap, writer, comment, newLine);
if (comment.hasTrailingNewLine) {
writer.writeLine();
}
@@ -7279,7 +6063,7 @@ var ts;
* Detached comment is a comment at the top of file or function body that is separated from
* the next statement by space.
*/
- function emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, removeComments) {
+ function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
var leadingComments;
var currentDetachedCommentInfo;
if (removeComments) {
@@ -7289,12 +6073,12 @@ var ts;
//
// var x = 10;
if (node.pos === 0) {
- leadingComments = ts.filter(ts.getLeadingCommentRanges(currentSourceFile.text, node.pos), isPinnedComment);
+ leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment);
}
}
else {
// removeComments is false, just get detached as normal and bypass the process to filter comment
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
+ leadingComments = ts.getLeadingCommentRanges(text, node.pos);
}
if (leadingComments) {
var detachedComments = [];
@@ -7302,8 +6086,8 @@ var ts;
for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
var comment = leadingComments_1[_i];
if (lastComment) {
- var lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastComment.end);
- var commentLine = getLineOfLocalPosition(currentSourceFile, comment.pos);
+ var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
+ var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
if (commentLine >= lastCommentLine + 2) {
// There was a blank line between the last comment and this comment. This
// comment is not part of the copyright comments. Return what we have so
@@ -7318,36 +6102,36 @@ var ts;
// All comments look like they could have been part of the copyright header. Make
// sure there is at least one blank line between it and the node. If not, it's not
// a copyright header.
- var lastCommentLine = getLineOfLocalPosition(currentSourceFile, ts.lastOrUndefined(detachedComments).end);
- var nodeLine = getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node.pos));
+ var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.lastOrUndefined(detachedComments).end);
+ var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
if (nodeLine >= lastCommentLine + 2) {
// Valid detachedComments
- emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
- emitComments(currentSourceFile, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
+ emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
+ emitComments(text, lineMap, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end };
}
}
}
return currentDetachedCommentInfo;
function isPinnedComment(comment) {
- return currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
+ return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
+ text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
}
}
ts.emitDetachedComments = emitDetachedComments;
- function writeCommentRange(currentSourceFile, writer, comment, newLine) {
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */) {
- var firstCommentLineAndCharacter = ts.getLineAndCharacterOfPosition(currentSourceFile, comment.pos);
- var lineCount = ts.getLineStarts(currentSourceFile).length;
+ function writeCommentRange(text, lineMap, writer, comment, newLine) {
+ if (text.charCodeAt(comment.pos + 1) === 42 /* asterisk */) {
+ var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, comment.pos);
+ var lineCount = lineMap.length;
var firstCommentLineIndent;
for (var pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
var nextLineStart = (currentLine + 1) === lineCount
- ? currentSourceFile.text.length + 1
- : getStartPositionOfLine(currentLine + 1, currentSourceFile);
+ ? text.length + 1
+ : lineMap[currentLine + 1];
if (pos !== comment.pos) {
// If we are not emitting first line, we need to write the spaces to adjust the alignment
if (firstCommentLineIndent === undefined) {
- firstCommentLineIndent = calculateIndent(getStartPositionOfLine(firstCommentLineAndCharacter.line, currentSourceFile), comment.pos);
+ firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], comment.pos);
}
// These are number of spaces writer is going to write at current indent
var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
@@ -7365,7 +6149,7 @@ var ts;
// More right indented comment */ --4 = 8 - 4 + 11
// class c { }
// }
- var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(pos, nextLineStart);
+ var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
if (spacesToEmit > 0) {
var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
@@ -7383,45 +6167,45 @@ var ts;
}
}
// Write the comment line text
- writeTrimmedCurrentLine(pos, nextLineStart);
+ writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart);
pos = nextLineStart;
}
}
else {
// Single line comment of style //....
- writer.write(currentSourceFile.text.substring(comment.pos, comment.end));
- }
- function writeTrimmedCurrentLine(pos, nextLineStart) {
- var end = Math.min(comment.end, nextLineStart - 1);
- var currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, "");
- if (currentLineText) {
- // trimmed forward and ending spaces text
- writer.write(currentLineText);
- if (end !== comment.end) {
- writer.writeLine();
- }
- }
- else {
- // Empty string - make sure we write empty line
- writer.writeLiteral(newLine);
+ writer.write(text.substring(comment.pos, comment.end));
+ }
+ }
+ ts.writeCommentRange = writeCommentRange;
+ function writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart) {
+ var end = Math.min(comment.end, nextLineStart - 1);
+ var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
+ if (currentLineText) {
+ // trimmed forward and ending spaces text
+ writer.write(currentLineText);
+ if (end !== comment.end) {
+ writer.writeLine();
}
}
- function calculateIndent(pos, end) {
- var currentLineIndent = 0;
- for (; pos < end && ts.isWhiteSpace(currentSourceFile.text.charCodeAt(pos)); pos++) {
- if (currentSourceFile.text.charCodeAt(pos) === 9 /* tab */) {
- // Tabs = TabSize = indent size and go to next tabStop
- currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
- }
- else {
- // Single space
- currentLineIndent++;
- }
+ else {
+ // Empty string - make sure we write empty line
+ writer.writeLiteral(newLine);
+ }
+ }
+ function calculateIndent(text, pos, end) {
+ var currentLineIndent = 0;
+ for (; pos < end && ts.isWhiteSpace(text.charCodeAt(pos)); pos++) {
+ if (text.charCodeAt(pos) === 9 /* tab */) {
+ // Tabs = TabSize = indent size and go to next tabStop
+ currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
+ }
+ else {
+ // Single space
+ currentLineIndent++;
}
- return currentLineIndent;
}
+ return currentLineIndent;
}
- ts.writeCommentRange = writeCommentRange;
function modifierToFlag(token) {
switch (token) {
case 113 /* StaticKeyword */: return 64 /* Static */;
@@ -7517,14 +6301,14 @@ var ts;
return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 512 /* Default */) ? symbol.valueDeclaration.localSymbol : undefined;
}
ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
- function isJavaScript(fileName) {
- return ts.fileExtensionIs(fileName, ".js");
+ function hasJavaScriptFileExtension(fileName) {
+ return ts.fileExtensionIs(fileName, ".js") || ts.fileExtensionIs(fileName, ".jsx");
}
- ts.isJavaScript = isJavaScript;
- function isTsx(fileName) {
- return ts.fileExtensionIs(fileName, ".tsx");
+ ts.hasJavaScriptFileExtension = hasJavaScriptFileExtension;
+ function allowsJsxExpressions(fileName) {
+ return ts.fileExtensionIs(fileName, ".tsx") || ts.fileExtensionIs(fileName, ".jsx");
}
- ts.isTsx = isTsx;
+ ts.allowsJsxExpressions = allowsJsxExpressions;
/**
* Replace each instance of non-ascii characters by one, two, three, or four escape sequences
* representing the UTF-8 encoding of the character, and return the expanded char code list.
@@ -7835,18 +6619,20 @@ var ts;
}
ts.getTypeParameterOwner = getTypeParameterOwner;
})(ts || (ts = {}));
-///
///
+///
var ts;
(function (ts) {
- var nodeConstructors = new Array(272 /* Count */);
/* @internal */ ts.parseTime = 0;
- function getNodeConstructor(kind) {
- return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind));
- }
- ts.getNodeConstructor = getNodeConstructor;
+ var NodeConstructor;
+ var SourceFileConstructor;
function createNode(kind, pos, end) {
- return new (getNodeConstructor(kind))(pos, end);
+ if (kind === 248 /* SourceFile */) {
+ return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
+ }
+ else {
+ return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
+ }
}
ts.createNode = createNode;
function visitNode(cbNode, node) {
@@ -8269,6 +7055,9 @@ var ts;
// up by avoiding the cost of creating/compiling scanners over and over again.
var scanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ true);
var disallowInAndDecoratorContext = 1 /* DisallowIn */ | 4 /* Decorator */;
+ // capture constructors in 'initializeState' to avoid null checks
+ var NodeConstructor;
+ var SourceFileConstructor;
var sourceFile;
var parseDiagnostics;
var syntaxCursor;
@@ -8354,13 +7143,16 @@ var ts;
// attached to the EOF token.
var parseErrorBeforeNextFinishedNode = false;
function parseSourceFile(fileName, _sourceText, languageVersion, _syntaxCursor, setParentNodes) {
- initializeState(fileName, _sourceText, languageVersion, _syntaxCursor);
+ var isJavaScriptFile = ts.hasJavaScriptFileExtension(fileName) || _sourceText.lastIndexOf("// @language=javascript", 0) === 0;
+ initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor);
var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes);
clearState();
return result;
}
Parser.parseSourceFile = parseSourceFile;
- function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor) {
+ function initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor) {
+ NodeConstructor = ts.objectAllocator.getNodeConstructor();
+ SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
sourceText = _sourceText;
syntaxCursor = _syntaxCursor;
parseDiagnostics = [];
@@ -8368,13 +7160,13 @@ var ts;
identifiers = {};
identifierCount = 0;
nodeCount = 0;
- contextFlags = ts.isJavaScript(fileName) ? 32 /* JavaScriptFile */ : 0 /* None */;
+ contextFlags = isJavaScriptFile ? 32 /* JavaScriptFile */ : 0 /* None */;
parseErrorBeforeNextFinishedNode = false;
// Initialize and prime the scanner before parsing the source elements.
scanner.setText(sourceText);
scanner.setOnError(scanError);
scanner.setScriptTarget(languageVersion);
- scanner.setLanguageVariant(ts.isTsx(fileName) ? 1 /* JSX */ : 0 /* Standard */);
+ scanner.setLanguageVariant(ts.allowsJsxExpressions(fileName) ? 1 /* JSX */ : 0 /* Standard */);
}
function clearState() {
// Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily.
@@ -8389,6 +7181,9 @@ var ts;
}
function parseSourceFileWorker(fileName, languageVersion, setParentNodes) {
sourceFile = createSourceFile(fileName, languageVersion);
+ if (contextFlags & 32 /* JavaScriptFile */) {
+ sourceFile.parserContextFlags = 32 /* JavaScriptFile */;
+ }
// Prime the scanner.
token = nextToken();
processReferenceComments(sourceFile);
@@ -8406,7 +7201,7 @@ var ts;
// If this is a javascript file, proactively see if we can get JSDoc comments for
// relevant nodes in the file. We'll use these to provide typing informaion if they're
// available.
- if (ts.isJavaScript(fileName)) {
+ if (ts.isSourceFileJavaScript(sourceFile)) {
addJSDocComments();
}
return sourceFile;
@@ -8461,15 +7256,16 @@ var ts;
}
Parser.fixupParentReferences = fixupParentReferences;
function createSourceFile(fileName, languageVersion) {
- var sourceFile = createNode(248 /* SourceFile */, /*pos*/ 0);
- sourceFile.pos = 0;
- sourceFile.end = sourceText.length;
+ // code from createNode is inlined here so createNode won't have to deal with special case of creating source files
+ // this is quite rare comparing to other nodes and createNode should be as fast as possible
+ var sourceFile = new SourceFileConstructor(248 /* SourceFile */, /*pos*/ 0, /* end */ sourceText.length);
+ nodeCount++;
sourceFile.text = sourceText;
sourceFile.bindDiagnostics = [];
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = ts.normalizePath(fileName);
sourceFile.flags = ts.fileExtensionIs(sourceFile.fileName, ".d.ts") ? 4096 /* DeclarationFile */ : 0;
- sourceFile.languageVariant = ts.isTsx(sourceFile.fileName) ? 1 /* JSX */ : 0 /* Standard */;
+ sourceFile.languageVariant = ts.allowsJsxExpressions(sourceFile.fileName) ? 1 /* JSX */ : 0 /* Standard */;
return sourceFile;
}
function setContextFlag(val, flag) {
@@ -8734,12 +7530,13 @@ var ts;
return parseExpected(23 /* SemicolonToken */);
}
}
+ // note: this function creates only node
function createNode(kind, pos) {
nodeCount++;
if (!(pos >= 0)) {
pos = scanner.getStartPos();
}
- return new (nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)))(pos, pos);
+ return new NodeConstructor(kind, pos, pos);
}
function finishNode(node, end) {
node.end = end === undefined ? scanner.getStartPos() : end;
@@ -8904,7 +7701,7 @@ var ts;
case 12 /* ObjectLiteralMembers */:
return token === 19 /* OpenBracketToken */ || token === 37 /* AsteriskToken */ || isLiteralPropertyName();
case 9 /* ObjectBindingElements */:
- return isLiteralPropertyName();
+ return token === 19 /* OpenBracketToken */ || isLiteralPropertyName();
case 7 /* HeritageClauseElement */:
// If we see { } then only consume it as an expression if it is followed by , or {
// That way we won't consume the body of a class in its heritage clause.
@@ -9584,9 +8381,7 @@ var ts;
}
function parseParameterType() {
if (parseOptional(54 /* ColonToken */)) {
- return token === 9 /* StringLiteral */
- ? parseLiteralNode(/*internName*/ true)
- : parseType();
+ return parseType();
}
return undefined;
}
@@ -9917,6 +8712,8 @@ var ts;
// If these are followed by a dot, then parse these out as a dotted type reference instead.
var node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReferenceOrTypePredicate();
+ case 9 /* StringLiteral */:
+ return parseLiteralNode(/*internName*/ true);
case 103 /* VoidKeyword */:
case 97 /* ThisKeyword */:
return parseTokenNode();
@@ -9946,6 +8743,7 @@ var ts;
case 19 /* OpenBracketToken */:
case 25 /* LessThanToken */:
case 92 /* NewKeyword */:
+ case 9 /* StringLiteral */:
return true;
case 17 /* OpenParenToken */:
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
@@ -10362,7 +9160,7 @@ var ts;
return 1 /* True */;
}
// This *could* be a parenthesized arrow function.
- // Return Unknown to let the caller know.
+ // Return Unknown to const the caller know.
return 2 /* Unknown */;
}
else {
@@ -10448,7 +9246,7 @@ var ts;
// user meant to supply a block. For example, if the user wrote:
//
// a =>
- // let v = 0;
+ // const v = 0;
// }
//
// they may be missing an open brace. Check to see if that's the case so we can
@@ -10485,3202 +9283,4567 @@ var ts;
function isInOrOfKeyword(t) {
return t === 90 /* InKeyword */ || t === 134 /* OfKeyword */;
}
- function parseBinaryExpressionRest(precedence, leftOperand) {
+ function parseBinaryExpressionRest(precedence, leftOperand) {
+ while (true) {
+ // We either have a binary operator here, or we're finished. We call
+ // reScanGreaterToken so that we merge token sequences like > and = into >=
+ reScanGreaterToken();
+ var newPrecedence = getBinaryOperatorPrecedence();
+ // Check the precedence to see if we should "take" this operator
+ // - For left associative operator (all operator but **), consume the operator,
+ // recursively call the function below, and parse binaryExpression as a rightOperand
+ // of the caller if the new precendence of the operator is greater then or equal to the current precendence.
+ // For example:
+ // a - b - c;
+ // ^token; leftOperand = b. Return b to the caller as a rightOperand
+ // a * b - c
+ // ^token; leftOperand = b. Return b to the caller as a rightOperand
+ // a - b * c;
+ // ^token; leftOperand = b. Return b * c to the caller as a rightOperand
+ // - For right associative operator (**), consume the operator, recursively call the function
+ // and parse binaryExpression as a rightOperand of the caller if the new precendence of
+ // the operator is strictly grater than the current precendence
+ // For example:
+ // a ** b ** c;
+ // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
+ // a - b ** c;
+ // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
+ // a ** b - c
+ // ^token; leftOperand = b. Return b to the caller as a rightOperand
+ var consumeCurrentOperator = token === 38 /* AsteriskAsteriskToken */ ?
+ newPrecedence >= precedence :
+ newPrecedence > precedence;
+ if (!consumeCurrentOperator) {
+ break;
+ }
+ if (token === 90 /* InKeyword */ && inDisallowInContext()) {
+ break;
+ }
+ if (token === 116 /* AsKeyword */) {
+ // Make sure we *do* perform ASI for constructs like this:
+ // var x = foo
+ // as (Bar)
+ // This should be parsed as an initialized variable, followed
+ // by a function call to 'as' with the argument 'Bar'
+ if (scanner.hasPrecedingLineBreak()) {
+ break;
+ }
+ else {
+ nextToken();
+ leftOperand = makeAsExpression(leftOperand, parseType());
+ }
+ }
+ else {
+ leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+ }
+ }
+ return leftOperand;
+ }
+ function isBinaryOperator() {
+ if (inDisallowInContext() && token === 90 /* InKeyword */) {
+ return false;
+ }
+ return getBinaryOperatorPrecedence() > 0;
+ }
+ function getBinaryOperatorPrecedence() {
+ switch (token) {
+ case 52 /* BarBarToken */:
+ return 1;
+ case 51 /* AmpersandAmpersandToken */:
+ return 2;
+ case 47 /* BarToken */:
+ return 3;
+ case 48 /* CaretToken */:
+ return 4;
+ case 46 /* AmpersandToken */:
+ return 5;
+ case 30 /* EqualsEqualsToken */:
+ case 31 /* ExclamationEqualsToken */:
+ case 32 /* EqualsEqualsEqualsToken */:
+ case 33 /* ExclamationEqualsEqualsToken */:
+ return 6;
+ case 25 /* LessThanToken */:
+ case 27 /* GreaterThanToken */:
+ case 28 /* LessThanEqualsToken */:
+ case 29 /* GreaterThanEqualsToken */:
+ case 91 /* InstanceOfKeyword */:
+ case 90 /* InKeyword */:
+ case 116 /* AsKeyword */:
+ return 7;
+ case 43 /* LessThanLessThanToken */:
+ case 44 /* GreaterThanGreaterThanToken */:
+ case 45 /* GreaterThanGreaterThanGreaterThanToken */:
+ return 8;
+ case 35 /* PlusToken */:
+ case 36 /* MinusToken */:
+ return 9;
+ case 37 /* AsteriskToken */:
+ case 39 /* SlashToken */:
+ case 40 /* PercentToken */:
+ return 10;
+ case 38 /* AsteriskAsteriskToken */:
+ return 11;
+ }
+ // -1 is lower than all other precedences. Returning it will cause binary expression
+ // parsing to stop.
+ return -1;
+ }
+ function makeBinaryExpression(left, operatorToken, right) {
+ var node = createNode(181 /* BinaryExpression */, left.pos);
+ node.left = left;
+ node.operatorToken = operatorToken;
+ node.right = right;
+ return finishNode(node);
+ }
+ function makeAsExpression(left, right) {
+ var node = createNode(189 /* AsExpression */, left.pos);
+ node.expression = left;
+ node.type = right;
+ return finishNode(node);
+ }
+ function parsePrefixUnaryExpression() {
+ var node = createNode(179 /* PrefixUnaryExpression */);
+ node.operator = token;
+ nextToken();
+ node.operand = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function parseDeleteExpression() {
+ var node = createNode(175 /* DeleteExpression */);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function parseTypeOfExpression() {
+ var node = createNode(176 /* TypeOfExpression */);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function parseVoidExpression() {
+ var node = createNode(177 /* VoidExpression */);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function isAwaitExpression() {
+ if (token === 119 /* AwaitKeyword */) {
+ if (inAwaitContext()) {
+ return true;
+ }
+ // here we are using similar heuristics as 'isYieldExpression'
+ return lookAhead(nextTokenIsIdentifierOnSameLine);
+ }
+ return false;
+ }
+ function parseAwaitExpression() {
+ var node = createNode(178 /* AwaitExpression */);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ /**
+ * Parse ES7 unary expression and await expression
+ *
+ * ES7 UnaryExpression:
+ * 1) SimpleUnaryExpression[?yield]
+ * 2) IncrementExpression[?yield] ** UnaryExpression[?yield]
+ */
+ function parseUnaryExpressionOrHigher() {
+ if (isAwaitExpression()) {
+ return parseAwaitExpression();
+ }
+ if (isIncrementExpression()) {
+ var incrementExpression = parseIncrementExpression();
+ return token === 38 /* AsteriskAsteriskToken */ ?
+ parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
+ incrementExpression;
+ }
+ var unaryOperator = token;
+ var simpleUnaryExpression = parseSimpleUnaryExpression();
+ if (token === 38 /* AsteriskAsteriskToken */) {
+ var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
+ if (simpleUnaryExpression.kind === 171 /* TypeAssertionExpression */) {
+ parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
+ }
+ else {
+ parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
+ }
+ }
+ return simpleUnaryExpression;
+ }
+ /**
+ * Parse ES7 simple-unary expression or higher:
+ *
+ * ES7 SimpleUnaryExpression:
+ * 1) IncrementExpression[?yield]
+ * 2) delete UnaryExpression[?yield]
+ * 3) void UnaryExpression[?yield]
+ * 4) typeof UnaryExpression[?yield]
+ * 5) + UnaryExpression[?yield]
+ * 6) - UnaryExpression[?yield]
+ * 7) ~ UnaryExpression[?yield]
+ * 8) ! UnaryExpression[?yield]
+ */
+ function parseSimpleUnaryExpression() {
+ switch (token) {
+ case 35 /* PlusToken */:
+ case 36 /* MinusToken */:
+ case 50 /* TildeToken */:
+ case 49 /* ExclamationToken */:
+ return parsePrefixUnaryExpression();
+ case 78 /* DeleteKeyword */:
+ return parseDeleteExpression();
+ case 101 /* TypeOfKeyword */:
+ return parseTypeOfExpression();
+ case 103 /* VoidKeyword */:
+ return parseVoidExpression();
+ case 25 /* LessThanToken */:
+ // This is modified UnaryExpression grammar in TypeScript
+ // UnaryExpression (modified):
+ // < type > UnaryExpression
+ return parseTypeAssertion();
+ default:
+ return parseIncrementExpression();
+ }
+ }
+ /**
+ * Check if the current token can possibly be an ES7 increment expression.
+ *
+ * ES7 IncrementExpression:
+ * LeftHandSideExpression[?Yield]
+ * LeftHandSideExpression[?Yield][no LineTerminator here]++
+ * LeftHandSideExpression[?Yield][no LineTerminator here]--
+ * ++LeftHandSideExpression[?Yield]
+ * --LeftHandSideExpression[?Yield]
+ */
+ function isIncrementExpression() {
+ // This function is called inside parseUnaryExpression to decide
+ // whether to call parseSimpleUnaryExpression or call parseIncrmentExpression directly
+ switch (token) {
+ case 35 /* PlusToken */:
+ case 36 /* MinusToken */:
+ case 50 /* TildeToken */:
+ case 49 /* ExclamationToken */:
+ case 78 /* DeleteKeyword */:
+ case 101 /* TypeOfKeyword */:
+ case 103 /* VoidKeyword */:
+ return false;
+ case 25 /* LessThanToken */:
+ // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
+ if (sourceFile.languageVariant !== 1 /* JSX */) {
+ return false;
+ }
+ // We are in JSX context and the token is part of JSXElement.
+ // Fall through
+ default:
+ return true;
+ }
+ }
+ /**
+ * Parse ES7 IncrementExpression. IncrementExpression is used instead of ES6's PostFixExpression.
+ *
+ * ES7 IncrementExpression[yield]:
+ * 1) LeftHandSideExpression[?yield]
+ * 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
+ * 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
+ * 4) ++LeftHandSideExpression[?yield]
+ * 5) --LeftHandSideExpression[?yield]
+ * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
+ */
+ function parseIncrementExpression() {
+ if (token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) {
+ var node = createNode(179 /* PrefixUnaryExpression */);
+ node.operator = token;
+ nextToken();
+ node.operand = parseLeftHandSideExpressionOrHigher();
+ return finishNode(node);
+ }
+ else if (sourceFile.languageVariant === 1 /* JSX */ && token === 25 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeyword)) {
+ // JSXElement is part of primaryExpression
+ return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
+ }
+ var expression = parseLeftHandSideExpressionOrHigher();
+ ts.Debug.assert(ts.isLeftHandSideExpression(expression));
+ if ((token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
+ var node = createNode(180 /* PostfixUnaryExpression */, expression.pos);
+ node.operand = expression;
+ node.operator = token;
+ nextToken();
+ return finishNode(node);
+ }
+ return expression;
+ }
+ function parseLeftHandSideExpressionOrHigher() {
+ // Original Ecma:
+ // LeftHandSideExpression: See 11.2
+ // NewExpression
+ // CallExpression
+ //
+ // Our simplification:
+ //
+ // LeftHandSideExpression: See 11.2
+ // MemberExpression
+ // CallExpression
+ //
+ // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
+ // MemberExpression to make our lives easier.
+ //
+ // to best understand the below code, it's important to see how CallExpression expands
+ // out into its own productions:
+ //
+ // CallExpression:
+ // MemberExpression Arguments
+ // CallExpression Arguments
+ // CallExpression[Expression]
+ // CallExpression.IdentifierName
+ // super ( ArgumentListopt )
+ // super.IdentifierName
+ //
+ // Because of the recursion in these calls, we need to bottom out first. There are two
+ // bottom out states we can run into. Either we see 'super' which must start either of
+ // the last two CallExpression productions. Or we have a MemberExpression which either
+ // completes the LeftHandSideExpression, or starts the beginning of the first four
+ // CallExpression productions.
+ var expression = token === 95 /* SuperKeyword */
+ ? parseSuperExpression()
+ : parseMemberExpressionOrHigher();
+ // Now, we *may* be complete. However, we might have consumed the start of a
+ // CallExpression. As such, we need to consume the rest of it here to be complete.
+ return parseCallExpressionRest(expression);
+ }
+ function parseMemberExpressionOrHigher() {
+ // Note: to make our lives simpler, we decompose the the NewExpression productions and
+ // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
+ // like so:
+ //
+ // PrimaryExpression : See 11.1
+ // this
+ // Identifier
+ // Literal
+ // ArrayLiteral
+ // ObjectLiteral
+ // (Expression)
+ // FunctionExpression
+ // new MemberExpression Arguments?
+ //
+ // MemberExpression : See 11.2
+ // PrimaryExpression
+ // MemberExpression[Expression]
+ // MemberExpression.IdentifierName
+ //
+ // CallExpression : See 11.2
+ // MemberExpression
+ // CallExpression Arguments
+ // CallExpression[Expression]
+ // CallExpression.IdentifierName
+ //
+ // Technically this is ambiguous. i.e. CallExpression defines:
+ //
+ // CallExpression:
+ // CallExpression Arguments
+ //
+ // If you see: "new Foo()"
+ //
+ // Then that could be treated as a single ObjectCreationExpression, or it could be
+ // treated as the invocation of "new Foo". We disambiguate that in code (to match
+ // the original grammar) by making sure that if we see an ObjectCreationExpression
+ // we always consume arguments if they are there. So we treat "new Foo()" as an
+ // object creation only, and not at all as an invocation) Another way to think
+ // about this is that for every "new" that we see, we will consume an argument list if
+ // it is there as part of the *associated* object creation node. Any additional
+ // argument lists we see, will become invocation expressions.
+ //
+ // Because there are no other places in the grammar now that refer to FunctionExpression
+ // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
+ // production.
+ //
+ // Because CallExpression and MemberExpression are left recursive, we need to bottom out
+ // of the recursion immediately. So we parse out a primary expression to start with.
+ var expression = parsePrimaryExpression();
+ return parseMemberExpressionRest(expression);
+ }
+ function parseSuperExpression() {
+ var expression = parseTokenNode();
+ if (token === 17 /* OpenParenToken */ || token === 21 /* DotToken */ || token === 19 /* OpenBracketToken */) {
+ return expression;
+ }
+ // If we have seen "super" it must be followed by '(' or '.'.
+ // If it wasn't then just try to parse out a '.' and report an error.
+ var node = createNode(166 /* PropertyAccessExpression */, expression.pos);
+ node.expression = expression;
+ node.dotToken = parseExpectedToken(21 /* DotToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
+ node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
+ return finishNode(node);
+ }
+ function parseJsxElementOrSelfClosingElement(inExpressionContext) {
+ var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
+ var result;
+ if (opening.kind === 235 /* JsxOpeningElement */) {
+ var node = createNode(233 /* JsxElement */, opening.pos);
+ node.openingElement = opening;
+ node.children = parseJsxChildren(node.openingElement.tagName);
+ node.closingElement = parseJsxClosingElement(inExpressionContext);
+ result = finishNode(node);
+ }
+ else {
+ ts.Debug.assert(opening.kind === 234 /* JsxSelfClosingElement */);
+ // Nothing else to do for self-closing elements
+ result = opening;
+ }
+ // If the user writes the invalid code '' in an expression context (i.e. not wrapped in
+ // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag
+ // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
+ // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
+ // does less damage and we can report a better error.
+ // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
+ // of one sort or another.
+ if (inExpressionContext && token === 25 /* LessThanToken */) {
+ var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true); });
+ if (invalidElement) {
+ parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
+ var badNode = createNode(181 /* BinaryExpression */, result.pos);
+ badNode.end = invalidElement.end;
+ badNode.left = result;
+ badNode.right = invalidElement;
+ badNode.operatorToken = createMissingNode(24 /* CommaToken */, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
+ badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
+ return badNode;
+ }
+ }
+ return result;
+ }
+ function parseJsxText() {
+ var node = createNode(236 /* JsxText */, scanner.getStartPos());
+ token = scanner.scanJsxToken();
+ return finishNode(node);
+ }
+ function parseJsxChild() {
+ switch (token) {
+ case 236 /* JsxText */:
+ return parseJsxText();
+ case 15 /* OpenBraceToken */:
+ return parseJsxExpression(/*inExpressionContext*/ false);
+ case 25 /* LessThanToken */:
+ return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
+ }
+ ts.Debug.fail("Unknown JSX child kind " + token);
+ }
+ function parseJsxChildren(openingTagName) {
+ var result = [];
+ result.pos = scanner.getStartPos();
+ var saveParsingContext = parsingContext;
+ parsingContext |= 1 << 14 /* JsxChildren */;
while (true) {
- // We either have a binary operator here, or we're finished. We call
- // reScanGreaterToken so that we merge token sequences like > and = into >=
- reScanGreaterToken();
- var newPrecedence = getBinaryOperatorPrecedence();
- // Check the precedence to see if we should "take" this operator
- // - For left associative operator (all operator but **), consume the operator,
- // recursively call the function below, and parse binaryExpression as a rightOperand
- // of the caller if the new precendence of the operator is greater then or equal to the current precendence.
- // For example:
- // a - b - c;
- // ^token; leftOperand = b. Return b to the caller as a rightOperand
- // a * b - c
- // ^token; leftOperand = b. Return b to the caller as a rightOperand
- // a - b * c;
- // ^token; leftOperand = b. Return b * c to the caller as a rightOperand
- // - For right associative operator (**), consume the operator, recursively call the function
- // and parse binaryExpression as a rightOperand of the caller if the new precendence of
- // the operator is strictly grater than the current precendence
- // For example:
- // a ** b ** c;
- // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
- // a - b ** c;
- // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
- // a ** b - c
- // ^token; leftOperand = b. Return b to the caller as a rightOperand
- var consumeCurrentOperator = token === 38 /* AsteriskAsteriskToken */ ?
- newPrecedence >= precedence :
- newPrecedence > precedence;
- if (!consumeCurrentOperator) {
+ token = scanner.reScanJsxToken();
+ if (token === 26 /* LessThanSlashToken */) {
break;
}
- if (token === 90 /* InKeyword */ && inDisallowInContext()) {
+ else if (token === 1 /* EndOfFileToken */) {
+ parseErrorAtCurrentToken(ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, openingTagName));
break;
}
- if (token === 116 /* AsKeyword */) {
- // Make sure we *do* perform ASI for constructs like this:
- // var x = foo
- // as (Bar)
- // This should be parsed as an initialized variable, followed
- // by a function call to 'as' with the argument 'Bar'
- if (scanner.hasPrecedingLineBreak()) {
- break;
- }
- else {
- nextToken();
- leftOperand = makeAsExpression(leftOperand, parseType());
- }
+ result.push(parseJsxChild());
+ }
+ result.end = scanner.getTokenPos();
+ parsingContext = saveParsingContext;
+ return result;
+ }
+ function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
+ var fullStart = scanner.getStartPos();
+ parseExpected(25 /* LessThanToken */);
+ var tagName = parseJsxElementName();
+ var attributes = parseList(13 /* JsxAttributes */, parseJsxAttribute);
+ var node;
+ if (token === 27 /* GreaterThanToken */) {
+ // Closing tag, so scan the immediately-following text with the JSX scanning instead
+ // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
+ // scanning errors
+ node = createNode(235 /* JsxOpeningElement */, fullStart);
+ scanJsxText();
+ }
+ else {
+ parseExpected(39 /* SlashToken */);
+ if (inExpressionContext) {
+ parseExpected(27 /* GreaterThanToken */);
}
else {
- leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+ parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*advance*/ false);
+ scanJsxText();
}
+ node = createNode(234 /* JsxSelfClosingElement */, fullStart);
}
- return leftOperand;
+ node.tagName = tagName;
+ node.attributes = attributes;
+ return finishNode(node);
}
- function isBinaryOperator() {
- if (inDisallowInContext() && token === 90 /* InKeyword */) {
- return false;
+ function parseJsxElementName() {
+ scanJsxIdentifier();
+ var elementName = parseIdentifierName();
+ while (parseOptional(21 /* DotToken */)) {
+ scanJsxIdentifier();
+ var node = createNode(135 /* QualifiedName */, elementName.pos);
+ node.left = elementName;
+ node.right = parseIdentifierName();
+ elementName = finishNode(node);
}
- return getBinaryOperatorPrecedence() > 0;
+ return elementName;
}
- function getBinaryOperatorPrecedence() {
- switch (token) {
- case 52 /* BarBarToken */:
- return 1;
- case 51 /* AmpersandAmpersandToken */:
- return 2;
- case 47 /* BarToken */:
- return 3;
- case 48 /* CaretToken */:
- return 4;
- case 46 /* AmpersandToken */:
- return 5;
- case 30 /* EqualsEqualsToken */:
- case 31 /* ExclamationEqualsToken */:
- case 32 /* EqualsEqualsEqualsToken */:
- case 33 /* ExclamationEqualsEqualsToken */:
- return 6;
- case 25 /* LessThanToken */:
- case 27 /* GreaterThanToken */:
- case 28 /* LessThanEqualsToken */:
- case 29 /* GreaterThanEqualsToken */:
- case 91 /* InstanceOfKeyword */:
- case 90 /* InKeyword */:
- case 116 /* AsKeyword */:
- return 7;
- case 43 /* LessThanLessThanToken */:
- case 44 /* GreaterThanGreaterThanToken */:
- case 45 /* GreaterThanGreaterThanGreaterThanToken */:
- return 8;
- case 35 /* PlusToken */:
- case 36 /* MinusToken */:
- return 9;
- case 37 /* AsteriskToken */:
- case 39 /* SlashToken */:
- case 40 /* PercentToken */:
- return 10;
- case 38 /* AsteriskAsteriskToken */:
- return 11;
+ function parseJsxExpression(inExpressionContext) {
+ var node = createNode(240 /* JsxExpression */);
+ parseExpected(15 /* OpenBraceToken */);
+ if (token !== 16 /* CloseBraceToken */) {
+ node.expression = parseExpression();
+ }
+ if (inExpressionContext) {
+ parseExpected(16 /* CloseBraceToken */);
+ }
+ else {
+ parseExpected(16 /* CloseBraceToken */, /*message*/ undefined, /*advance*/ false);
+ scanJsxText();
}
- // -1 is lower than all other precedences. Returning it will cause binary expression
- // parsing to stop.
- return -1;
- }
- function makeBinaryExpression(left, operatorToken, right) {
- var node = createNode(181 /* BinaryExpression */, left.pos);
- node.left = left;
- node.operatorToken = operatorToken;
- node.right = right;
return finishNode(node);
}
- function makeAsExpression(left, right) {
- var node = createNode(189 /* AsExpression */, left.pos);
- node.expression = left;
- node.type = right;
+ function parseJsxAttribute() {
+ if (token === 15 /* OpenBraceToken */) {
+ return parseJsxSpreadAttribute();
+ }
+ scanJsxIdentifier();
+ var node = createNode(238 /* JsxAttribute */);
+ node.name = parseIdentifierName();
+ if (parseOptional(56 /* EqualsToken */)) {
+ switch (token) {
+ case 9 /* StringLiteral */:
+ node.initializer = parseLiteralNode();
+ break;
+ default:
+ node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
+ break;
+ }
+ }
return finishNode(node);
}
- function parsePrefixUnaryExpression() {
- var node = createNode(179 /* PrefixUnaryExpression */);
- node.operator = token;
- nextToken();
- node.operand = parseSimpleUnaryExpression();
+ function parseJsxSpreadAttribute() {
+ var node = createNode(239 /* JsxSpreadAttribute */);
+ parseExpected(15 /* OpenBraceToken */);
+ parseExpected(22 /* DotDotDotToken */);
+ node.expression = parseExpression();
+ parseExpected(16 /* CloseBraceToken */);
return finishNode(node);
}
- function parseDeleteExpression() {
- var node = createNode(175 /* DeleteExpression */);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
+ function parseJsxClosingElement(inExpressionContext) {
+ var node = createNode(237 /* JsxClosingElement */);
+ parseExpected(26 /* LessThanSlashToken */);
+ node.tagName = parseJsxElementName();
+ if (inExpressionContext) {
+ parseExpected(27 /* GreaterThanToken */);
+ }
+ else {
+ parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*advance*/ false);
+ scanJsxText();
+ }
return finishNode(node);
}
- function parseTypeOfExpression() {
- var node = createNode(176 /* TypeOfExpression */);
- nextToken();
+ function parseTypeAssertion() {
+ var node = createNode(171 /* TypeAssertionExpression */);
+ parseExpected(25 /* LessThanToken */);
+ node.type = parseType();
+ parseExpected(27 /* GreaterThanToken */);
node.expression = parseSimpleUnaryExpression();
return finishNode(node);
}
- function parseVoidExpression() {
- var node = createNode(177 /* VoidExpression */);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function parseMemberExpressionRest(expression) {
+ while (true) {
+ var dotToken = parseOptionalToken(21 /* DotToken */);
+ if (dotToken) {
+ var propertyAccess = createNode(166 /* PropertyAccessExpression */, expression.pos);
+ propertyAccess.expression = expression;
+ propertyAccess.dotToken = dotToken;
+ propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
+ expression = finishNode(propertyAccess);
+ continue;
+ }
+ // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
+ if (!inDecoratorContext() && parseOptional(19 /* OpenBracketToken */)) {
+ var indexedAccess = createNode(167 /* ElementAccessExpression */, expression.pos);
+ indexedAccess.expression = expression;
+ // It's not uncommon for a user to write: "new Type[]".
+ // Check for that common pattern and report a better error message.
+ if (token !== 20 /* CloseBracketToken */) {
+ indexedAccess.argumentExpression = allowInAnd(parseExpression);
+ if (indexedAccess.argumentExpression.kind === 9 /* StringLiteral */ || indexedAccess.argumentExpression.kind === 8 /* NumericLiteral */) {
+ var literal = indexedAccess.argumentExpression;
+ literal.text = internIdentifier(literal.text);
+ }
+ }
+ parseExpected(20 /* CloseBracketToken */);
+ expression = finishNode(indexedAccess);
+ continue;
+ }
+ if (token === 11 /* NoSubstitutionTemplateLiteral */ || token === 12 /* TemplateHead */) {
+ var tagExpression = createNode(170 /* TaggedTemplateExpression */, expression.pos);
+ tagExpression.tag = expression;
+ tagExpression.template = token === 11 /* NoSubstitutionTemplateLiteral */
+ ? parseLiteralNode()
+ : parseTemplateExpression();
+ expression = finishNode(tagExpression);
+ continue;
+ }
+ return expression;
+ }
}
- function isAwaitExpression() {
- if (token === 119 /* AwaitKeyword */) {
- if (inAwaitContext()) {
- return true;
+ function parseCallExpressionRest(expression) {
+ while (true) {
+ expression = parseMemberExpressionRest(expression);
+ if (token === 25 /* LessThanToken */) {
+ // See if this is the start of a generic invocation. If so, consume it and
+ // keep checking for postfix expressions. Otherwise, it's just a '<' that's
+ // part of an arithmetic expression. Break out so we consume it higher in the
+ // stack.
+ var typeArguments = tryParse(parseTypeArgumentsInExpression);
+ if (!typeArguments) {
+ return expression;
+ }
+ var callExpr = createNode(168 /* CallExpression */, expression.pos);
+ callExpr.expression = expression;
+ callExpr.typeArguments = typeArguments;
+ callExpr.arguments = parseArgumentList();
+ expression = finishNode(callExpr);
+ continue;
}
- // here we are using similar heuristics as 'isYieldExpression'
- return lookAhead(nextTokenIsIdentifierOnSameLine);
+ else if (token === 17 /* OpenParenToken */) {
+ var callExpr = createNode(168 /* CallExpression */, expression.pos);
+ callExpr.expression = expression;
+ callExpr.arguments = parseArgumentList();
+ expression = finishNode(callExpr);
+ continue;
+ }
+ return expression;
}
- return false;
}
- function parseAwaitExpression() {
- var node = createNode(178 /* AwaitExpression */);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function parseArgumentList() {
+ parseExpected(17 /* OpenParenToken */);
+ var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
+ parseExpected(18 /* CloseParenToken */);
+ return result;
}
- /**
- * Parse ES7 unary expression and await expression
- *
- * ES7 UnaryExpression:
- * 1) SimpleUnaryExpression[?yield]
- * 2) IncrementExpression[?yield] ** UnaryExpression[?yield]
- */
- function parseUnaryExpressionOrHigher() {
- if (isAwaitExpression()) {
- return parseAwaitExpression();
- }
- if (isIncrementExpression()) {
- var incrementExpression = parseIncrementExpression();
- return token === 38 /* AsteriskAsteriskToken */ ?
- parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
- incrementExpression;
+ function parseTypeArgumentsInExpression() {
+ if (!parseOptional(25 /* LessThanToken */)) {
+ return undefined;
}
- var unaryOperator = token;
- var simpleUnaryExpression = parseSimpleUnaryExpression();
- if (token === 38 /* AsteriskAsteriskToken */) {
- var diagnostic;
- var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
- if (simpleUnaryExpression.kind === 171 /* TypeAssertionExpression */) {
- parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
- }
- else {
- parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
- }
+ var typeArguments = parseDelimitedList(18 /* TypeArguments */, parseType);
+ if (!parseExpected(27 /* GreaterThanToken */)) {
+ // If it doesn't have the closing > then it's definitely not an type argument list.
+ return undefined;
}
- return simpleUnaryExpression;
+ // If we have a '<', then only parse this as a arugment list if the type arguments
+ // are complete and we have an open paren. if we don't, rewind and return nothing.
+ return typeArguments && canFollowTypeArgumentsInExpression()
+ ? typeArguments
+ : undefined;
}
- /**
- * Parse ES7 simple-unary expression or higher:
- *
- * ES7 SimpleUnaryExpression:
- * 1) IncrementExpression[?yield]
- * 2) delete UnaryExpression[?yield]
- * 3) void UnaryExpression[?yield]
- * 4) typeof UnaryExpression[?yield]
- * 5) + UnaryExpression[?yield]
- * 6) - UnaryExpression[?yield]
- * 7) ~ UnaryExpression[?yield]
- * 8) ! UnaryExpression[?yield]
- */
- function parseSimpleUnaryExpression() {
+ function canFollowTypeArgumentsInExpression() {
switch (token) {
- case 35 /* PlusToken */:
- case 36 /* MinusToken */:
- case 50 /* TildeToken */:
- case 49 /* ExclamationToken */:
- return parsePrefixUnaryExpression();
- case 78 /* DeleteKeyword */:
- return parseDeleteExpression();
- case 101 /* TypeOfKeyword */:
- return parseTypeOfExpression();
- case 103 /* VoidKeyword */:
- return parseVoidExpression();
- case 25 /* LessThanToken */:
- // This is modified UnaryExpression grammar in TypeScript
- // UnaryExpression (modified):
- // < type > UnaryExpression
- return parseTypeAssertion();
+ case 17 /* OpenParenToken */: // foo(
+ // this case are the only case where this token can legally follow a type argument
+ // list. So we definitely want to treat this as a type arg list.
+ case 21 /* DotToken */: // foo.
+ case 18 /* CloseParenToken */: // foo)
+ case 20 /* CloseBracketToken */: // foo]
+ case 54 /* ColonToken */: // foo:
+ case 23 /* SemicolonToken */: // foo;
+ case 53 /* QuestionToken */: // foo?
+ case 30 /* EqualsEqualsToken */: // foo ==
+ case 32 /* EqualsEqualsEqualsToken */: // foo ===
+ case 31 /* ExclamationEqualsToken */: // foo !=
+ case 33 /* ExclamationEqualsEqualsToken */: // foo !==
+ case 51 /* AmpersandAmpersandToken */: // foo &&
+ case 52 /* BarBarToken */: // foo ||
+ case 48 /* CaretToken */: // foo ^
+ case 46 /* AmpersandToken */: // foo &
+ case 47 /* BarToken */: // foo |
+ case 16 /* CloseBraceToken */: // foo }
+ case 1 /* EndOfFileToken */:
+ // these cases can't legally follow a type arg list. However, they're not legal
+ // expressions either. The user is probably in the middle of a generic type. So
+ // treat it as such.
+ return true;
+ case 24 /* CommaToken */: // foo,
+ case 15 /* OpenBraceToken */: // foo {
+ // We don't want to treat these as type arguments. Otherwise we'll parse this
+ // as an invocation expression. Instead, we want to parse out the expression
+ // in isolation from the type arguments.
default:
- return parseIncrementExpression();
+ // Anything else treat as an expression.
+ return false;
}
}
- /**
- * Check if the current token can possibly be an ES7 increment expression.
- *
- * ES7 IncrementExpression:
- * LeftHandSideExpression[?Yield]
- * LeftHandSideExpression[?Yield][no LineTerminator here]++
- * LeftHandSideExpression[?Yield][no LineTerminator here]--
- * ++LeftHandSideExpression[?Yield]
- * --LeftHandSideExpression[?Yield]
- */
- function isIncrementExpression() {
- // This function is called inside parseUnaryExpression to decide
- // whether to call parseSimpleUnaryExpression or call parseIncrmentExpression directly
+ function parsePrimaryExpression() {
switch (token) {
- case 35 /* PlusToken */:
- case 36 /* MinusToken */:
- case 50 /* TildeToken */:
- case 49 /* ExclamationToken */:
- case 78 /* DeleteKeyword */:
- case 101 /* TypeOfKeyword */:
- case 103 /* VoidKeyword */:
- return false;
- case 25 /* LessThanToken */:
- // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
- if (sourceFile.languageVariant !== 1 /* JSX */) {
- return false;
+ case 8 /* NumericLiteral */:
+ case 9 /* StringLiteral */:
+ case 11 /* NoSubstitutionTemplateLiteral */:
+ return parseLiteralNode();
+ case 97 /* ThisKeyword */:
+ case 95 /* SuperKeyword */:
+ case 93 /* NullKeyword */:
+ case 99 /* TrueKeyword */:
+ case 84 /* FalseKeyword */:
+ return parseTokenNode();
+ case 17 /* OpenParenToken */:
+ return parseParenthesizedExpression();
+ case 19 /* OpenBracketToken */:
+ return parseArrayLiteralExpression();
+ case 15 /* OpenBraceToken */:
+ return parseObjectLiteralExpression();
+ case 118 /* AsyncKeyword */:
+ // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
+ // If we encounter `async [no LineTerminator here] function` then this is an async
+ // function; otherwise, its an identifier.
+ if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
+ break;
}
- // We are in JSX context and the token is part of JSXElement.
- // Fall through
- default:
- return true;
+ return parseFunctionExpression();
+ case 73 /* ClassKeyword */:
+ return parseClassExpression();
+ case 87 /* FunctionKeyword */:
+ return parseFunctionExpression();
+ case 92 /* NewKeyword */:
+ return parseNewExpression();
+ case 39 /* SlashToken */:
+ case 61 /* SlashEqualsToken */:
+ if (reScanSlashToken() === 10 /* RegularExpressionLiteral */) {
+ return parseLiteralNode();
+ }
+ break;
+ case 12 /* TemplateHead */:
+ return parseTemplateExpression();
+ }
+ return parseIdentifier(ts.Diagnostics.Expression_expected);
+ }
+ function parseParenthesizedExpression() {
+ var node = createNode(172 /* ParenthesizedExpression */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ return finishNode(node);
+ }
+ function parseSpreadElement() {
+ var node = createNode(185 /* SpreadElementExpression */);
+ parseExpected(22 /* DotDotDotToken */);
+ node.expression = parseAssignmentExpressionOrHigher();
+ return finishNode(node);
+ }
+ function parseArgumentOrArrayLiteralElement() {
+ return token === 22 /* DotDotDotToken */ ? parseSpreadElement() :
+ token === 24 /* CommaToken */ ? createNode(187 /* OmittedExpression */) :
+ parseAssignmentExpressionOrHigher();
+ }
+ function parseArgumentExpression() {
+ return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
+ }
+ function parseArrayLiteralExpression() {
+ var node = createNode(164 /* ArrayLiteralExpression */);
+ parseExpected(19 /* OpenBracketToken */);
+ if (scanner.hasPrecedingLineBreak())
+ node.flags |= 1024 /* MultiLine */;
+ node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
+ parseExpected(20 /* CloseBracketToken */);
+ return finishNode(node);
+ }
+ function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
+ if (parseContextualModifier(123 /* GetKeyword */)) {
+ return parseAccessorDeclaration(145 /* GetAccessor */, fullStart, decorators, modifiers);
+ }
+ else if (parseContextualModifier(129 /* SetKeyword */)) {
+ return parseAccessorDeclaration(146 /* SetAccessor */, fullStart, decorators, modifiers);
}
+ return undefined;
}
- /**
- * Parse ES7 IncrementExpression. IncrementExpression is used instead of ES6's PostFixExpression.
- *
- * ES7 IncrementExpression[yield]:
- * 1) LeftHandSideExpression[?yield]
- * 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
- * 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
- * 4) ++LeftHandSideExpression[?yield]
- * 5) --LeftHandSideExpression[?yield]
- * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
- */
- function parseIncrementExpression() {
- if (token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) {
- var node = createNode(179 /* PrefixUnaryExpression */);
- node.operator = token;
- nextToken();
- node.operand = parseLeftHandSideExpressionOrHigher();
- return finishNode(node);
+ function parseObjectLiteralElement() {
+ var fullStart = scanner.getStartPos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
+ if (accessor) {
+ return accessor;
}
- else if (sourceFile.languageVariant === 1 /* JSX */ && token === 25 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeyword)) {
- // JSXElement is part of primaryExpression
- return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
+ var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
+ var tokenIsIdentifier = isIdentifier();
+ var nameToken = token;
+ var propertyName = parsePropertyName();
+ // Disallowing of optional property assignments happens in the grammar checker.
+ var questionToken = parseOptionalToken(53 /* QuestionToken */);
+ if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
+ return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
}
- var expression = parseLeftHandSideExpressionOrHigher();
- ts.Debug.assert(ts.isLeftHandSideExpression(expression));
- if ((token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
- var node = createNode(180 /* PostfixUnaryExpression */, expression.pos);
- node.operand = expression;
- node.operator = token;
- nextToken();
- return finishNode(node);
+ // check if it is short-hand property assignment or normal property assignment
+ // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
+ // CoverInitializedName[Yield] :
+ // IdentifierReference[?Yield] Initializer[In, ?Yield]
+ // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
+ var isShorthandPropertyAssignment = tokenIsIdentifier && (token === 24 /* CommaToken */ || token === 16 /* CloseBraceToken */ || token === 56 /* EqualsToken */);
+ if (isShorthandPropertyAssignment) {
+ var shorthandDeclaration = createNode(246 /* ShorthandPropertyAssignment */, fullStart);
+ shorthandDeclaration.name = propertyName;
+ shorthandDeclaration.questionToken = questionToken;
+ var equalsToken = parseOptionalToken(56 /* EqualsToken */);
+ if (equalsToken) {
+ shorthandDeclaration.equalsToken = equalsToken;
+ shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
+ }
+ return finishNode(shorthandDeclaration);
+ }
+ else {
+ var propertyAssignment = createNode(245 /* PropertyAssignment */, fullStart);
+ propertyAssignment.name = propertyName;
+ propertyAssignment.questionToken = questionToken;
+ parseExpected(54 /* ColonToken */);
+ propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
+ return finishNode(propertyAssignment);
}
- return expression;
}
- function parseLeftHandSideExpressionOrHigher() {
- // Original Ecma:
- // LeftHandSideExpression: See 11.2
- // NewExpression
- // CallExpression
- //
- // Our simplification:
- //
- // LeftHandSideExpression: See 11.2
- // MemberExpression
- // CallExpression
- //
- // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
- // MemberExpression to make our lives easier.
- //
- // to best understand the below code, it's important to see how CallExpression expands
- // out into its own productions:
- //
- // CallExpression:
- // MemberExpression Arguments
- // CallExpression Arguments
- // CallExpression[Expression]
- // CallExpression.IdentifierName
- // super ( ArgumentListopt )
- // super.IdentifierName
- //
- // Because of the recursion in these calls, we need to bottom out first. There are two
- // bottom out states we can run into. Either we see 'super' which must start either of
- // the last two CallExpression productions. Or we have a MemberExpression which either
- // completes the LeftHandSideExpression, or starts the beginning of the first four
- // CallExpression productions.
- var expression = token === 95 /* SuperKeyword */
- ? parseSuperExpression()
- : parseMemberExpressionOrHigher();
- // Now, we *may* be complete. However, we might have consumed the start of a
- // CallExpression. As such, we need to consume the rest of it here to be complete.
- return parseCallExpressionRest(expression);
+ function parseObjectLiteralExpression() {
+ var node = createNode(165 /* ObjectLiteralExpression */);
+ parseExpected(15 /* OpenBraceToken */);
+ if (scanner.hasPrecedingLineBreak()) {
+ node.flags |= 1024 /* MultiLine */;
+ }
+ node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimeter*/ true);
+ parseExpected(16 /* CloseBraceToken */);
+ return finishNode(node);
}
- function parseMemberExpressionOrHigher() {
- // Note: to make our lives simpler, we decompose the the NewExpression productions and
- // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
- // like so:
- //
- // PrimaryExpression : See 11.1
- // this
- // Identifier
- // Literal
- // ArrayLiteral
- // ObjectLiteral
- // (Expression)
- // FunctionExpression
- // new MemberExpression Arguments?
- //
- // MemberExpression : See 11.2
- // PrimaryExpression
- // MemberExpression[Expression]
- // MemberExpression.IdentifierName
- //
- // CallExpression : See 11.2
- // MemberExpression
- // CallExpression Arguments
- // CallExpression[Expression]
- // CallExpression.IdentifierName
- //
- // Technically this is ambiguous. i.e. CallExpression defines:
- //
- // CallExpression:
- // CallExpression Arguments
- //
- // If you see: "new Foo()"
- //
- // Then that could be treated as a single ObjectCreationExpression, or it could be
- // treated as the invocation of "new Foo". We disambiguate that in code (to match
- // the original grammar) by making sure that if we see an ObjectCreationExpression
- // we always consume arguments if they are there. So we treat "new Foo()" as an
- // object creation only, and not at all as an invocation) Another way to think
- // about this is that for every "new" that we see, we will consume an argument list if
- // it is there as part of the *associated* object creation node. Any additional
- // argument lists we see, will become invocation expressions.
- //
- // Because there are no other places in the grammar now that refer to FunctionExpression
- // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
- // production.
+ function parseFunctionExpression() {
+ // GeneratorExpression:
+ // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
//
- // Because CallExpression and MemberExpression are left recursive, we need to bottom out
- // of the recursion immediately. So we parse out a primary expression to start with.
- var expression = parsePrimaryExpression();
- return parseMemberExpressionRest(expression);
+ // FunctionExpression:
+ // function BindingIdentifier[opt](FormalParameters){ FunctionBody }
+ var saveDecoratorContext = inDecoratorContext();
+ if (saveDecoratorContext) {
+ setDecoratorContext(false);
+ }
+ var node = createNode(173 /* FunctionExpression */);
+ setModifiers(node, parseModifiers());
+ parseExpected(87 /* FunctionKeyword */);
+ node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
+ var isGenerator = !!node.asteriskToken;
+ var isAsync = !!(node.flags & 256 /* Async */);
+ node.name =
+ isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
+ isGenerator ? doInYieldContext(parseOptionalIdentifier) :
+ isAsync ? doInAwaitContext(parseOptionalIdentifier) :
+ parseOptionalIdentifier();
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
+ node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
+ if (saveDecoratorContext) {
+ setDecoratorContext(true);
+ }
+ return finishNode(node);
}
- function parseSuperExpression() {
- var expression = parseTokenNode();
- if (token === 17 /* OpenParenToken */ || token === 21 /* DotToken */ || token === 19 /* OpenBracketToken */) {
- return expression;
+ function parseOptionalIdentifier() {
+ return isIdentifier() ? parseIdentifier() : undefined;
+ }
+ function parseNewExpression() {
+ var node = createNode(169 /* NewExpression */);
+ parseExpected(92 /* NewKeyword */);
+ node.expression = parseMemberExpressionOrHigher();
+ node.typeArguments = tryParse(parseTypeArgumentsInExpression);
+ if (node.typeArguments || token === 17 /* OpenParenToken */) {
+ node.arguments = parseArgumentList();
}
- // If we have seen "super" it must be followed by '(' or '.'.
- // If it wasn't then just try to parse out a '.' and report an error.
- var node = createNode(166 /* PropertyAccessExpression */, expression.pos);
- node.expression = expression;
- node.dotToken = parseExpectedToken(21 /* DotToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
- node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
return finishNode(node);
}
- function parseJsxElementOrSelfClosingElement(inExpressionContext) {
- var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
- var result;
- if (opening.kind === 235 /* JsxOpeningElement */) {
- var node = createNode(233 /* JsxElement */, opening.pos);
- node.openingElement = opening;
- node.children = parseJsxChildren(node.openingElement.tagName);
- node.closingElement = parseJsxClosingElement(inExpressionContext);
- result = finishNode(node);
+ // STATEMENTS
+ function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
+ var node = createNode(192 /* Block */);
+ if (parseExpected(15 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
+ node.statements = parseList(1 /* BlockStatements */, parseStatement);
+ parseExpected(16 /* CloseBraceToken */);
}
else {
- ts.Debug.assert(opening.kind === 234 /* JsxSelfClosingElement */);
- // Nothing else to do for self-closing elements
- result = opening;
+ node.statements = createMissingList();
}
- // If the user writes the invalid code '' in an expression context (i.e. not wrapped in
- // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag
- // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
- // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
- // does less damage and we can report a better error.
- // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
- // of one sort or another.
- if (inExpressionContext && token === 25 /* LessThanToken */) {
- var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true); });
- if (invalidElement) {
- parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
- var badNode = createNode(181 /* BinaryExpression */, result.pos);
- badNode.end = invalidElement.end;
- badNode.left = result;
- badNode.right = invalidElement;
- badNode.operatorToken = createMissingNode(24 /* CommaToken */, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
- badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
- return badNode;
- }
+ return finishNode(node);
+ }
+ function parseFunctionBlock(allowYield, allowAwait, ignoreMissingOpenBrace, diagnosticMessage) {
+ var savedYieldContext = inYieldContext();
+ setYieldContext(allowYield);
+ var savedAwaitContext = inAwaitContext();
+ setAwaitContext(allowAwait);
+ // We may be in a [Decorator] context when parsing a function expression or
+ // arrow function. The body of the function is not in [Decorator] context.
+ var saveDecoratorContext = inDecoratorContext();
+ if (saveDecoratorContext) {
+ setDecoratorContext(false);
}
- return result;
+ var block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
+ if (saveDecoratorContext) {
+ setDecoratorContext(true);
+ }
+ setYieldContext(savedYieldContext);
+ setAwaitContext(savedAwaitContext);
+ return block;
}
- function parseJsxText() {
- var node = createNode(236 /* JsxText */, scanner.getStartPos());
- token = scanner.scanJsxToken();
+ function parseEmptyStatement() {
+ var node = createNode(194 /* EmptyStatement */);
+ parseExpected(23 /* SemicolonToken */);
return finishNode(node);
}
- function parseJsxChild() {
- switch (token) {
- case 236 /* JsxText */:
- return parseJsxText();
- case 15 /* OpenBraceToken */:
- return parseJsxExpression(/*inExpressionContext*/ false);
- case 25 /* LessThanToken */:
- return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
- }
- ts.Debug.fail("Unknown JSX child kind " + token);
+ function parseIfStatement() {
+ var node = createNode(196 /* IfStatement */);
+ parseExpected(88 /* IfKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ node.thenStatement = parseStatement();
+ node.elseStatement = parseOptional(80 /* ElseKeyword */) ? parseStatement() : undefined;
+ return finishNode(node);
}
- function parseJsxChildren(openingTagName) {
- var result = [];
- result.pos = scanner.getStartPos();
- var saveParsingContext = parsingContext;
- parsingContext |= 1 << 14 /* JsxChildren */;
- while (true) {
- token = scanner.reScanJsxToken();
- if (token === 26 /* LessThanSlashToken */) {
- break;
+ function parseDoStatement() {
+ var node = createNode(197 /* DoStatement */);
+ parseExpected(79 /* DoKeyword */);
+ node.statement = parseStatement();
+ parseExpected(104 /* WhileKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
+ // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
+ // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
+ // do;while(0)x will have a semicolon inserted before x.
+ parseOptional(23 /* SemicolonToken */);
+ return finishNode(node);
+ }
+ function parseWhileStatement() {
+ var node = createNode(198 /* WhileStatement */);
+ parseExpected(104 /* WhileKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ node.statement = parseStatement();
+ return finishNode(node);
+ }
+ function parseForOrForInOrForOfStatement() {
+ var pos = getNodePos();
+ parseExpected(86 /* ForKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ var initializer = undefined;
+ if (token !== 23 /* SemicolonToken */) {
+ if (token === 102 /* VarKeyword */ || token === 108 /* LetKeyword */ || token === 74 /* ConstKeyword */) {
+ initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
}
- else if (token === 1 /* EndOfFileToken */) {
- parseErrorAtCurrentToken(ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, openingTagName));
- break;
+ else {
+ initializer = disallowInAnd(parseExpression);
}
- result.push(parseJsxChild());
}
- result.end = scanner.getTokenPos();
- parsingContext = saveParsingContext;
- return result;
- }
- function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
- var fullStart = scanner.getStartPos();
- parseExpected(25 /* LessThanToken */);
- var tagName = parseJsxElementName();
- var attributes = parseList(13 /* JsxAttributes */, parseJsxAttribute);
- var node;
- if (token === 27 /* GreaterThanToken */) {
- // Closing tag, so scan the immediately-following text with the JSX scanning instead
- // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
- // scanning errors
- node = createNode(235 /* JsxOpeningElement */, fullStart);
- scanJsxText();
+ var forOrForInOrForOfStatement;
+ if (parseOptional(90 /* InKeyword */)) {
+ var forInStatement = createNode(200 /* ForInStatement */, pos);
+ forInStatement.initializer = initializer;
+ forInStatement.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ forOrForInOrForOfStatement = forInStatement;
+ }
+ else if (parseOptional(134 /* OfKeyword */)) {
+ var forOfStatement = createNode(201 /* ForOfStatement */, pos);
+ forOfStatement.initializer = initializer;
+ forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
+ parseExpected(18 /* CloseParenToken */);
+ forOrForInOrForOfStatement = forOfStatement;
}
else {
- parseExpected(39 /* SlashToken */);
- if (inExpressionContext) {
- parseExpected(27 /* GreaterThanToken */);
+ var forStatement = createNode(199 /* ForStatement */, pos);
+ forStatement.initializer = initializer;
+ parseExpected(23 /* SemicolonToken */);
+ if (token !== 23 /* SemicolonToken */ && token !== 18 /* CloseParenToken */) {
+ forStatement.condition = allowInAnd(parseExpression);
}
- else {
- parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*advance*/ false);
- scanJsxText();
+ parseExpected(23 /* SemicolonToken */);
+ if (token !== 18 /* CloseParenToken */) {
+ forStatement.incrementor = allowInAnd(parseExpression);
}
- node = createNode(234 /* JsxSelfClosingElement */, fullStart);
+ parseExpected(18 /* CloseParenToken */);
+ forOrForInOrForOfStatement = forStatement;
}
- node.tagName = tagName;
- node.attributes = attributes;
+ forOrForInOrForOfStatement.statement = parseStatement();
+ return finishNode(forOrForInOrForOfStatement);
+ }
+ function parseBreakOrContinueStatement(kind) {
+ var node = createNode(kind);
+ parseExpected(kind === 203 /* BreakStatement */ ? 70 /* BreakKeyword */ : 75 /* ContinueKeyword */);
+ if (!canParseSemicolon()) {
+ node.label = parseIdentifier();
+ }
+ parseSemicolon();
return finishNode(node);
}
- function parseJsxElementName() {
- scanJsxIdentifier();
- var elementName = parseIdentifierName();
- while (parseOptional(21 /* DotToken */)) {
- scanJsxIdentifier();
- var node = createNode(135 /* QualifiedName */, elementName.pos);
- node.left = elementName;
- node.right = parseIdentifierName();
- elementName = finishNode(node);
+ function parseReturnStatement() {
+ var node = createNode(204 /* ReturnStatement */);
+ parseExpected(94 /* ReturnKeyword */);
+ if (!canParseSemicolon()) {
+ node.expression = allowInAnd(parseExpression);
}
- return elementName;
+ parseSemicolon();
+ return finishNode(node);
}
- function parseJsxExpression(inExpressionContext) {
- var node = createNode(240 /* JsxExpression */);
+ function parseWithStatement() {
+ var node = createNode(205 /* WithStatement */);
+ parseExpected(105 /* WithKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ node.statement = parseStatement();
+ return finishNode(node);
+ }
+ function parseCaseClause() {
+ var node = createNode(241 /* CaseClause */);
+ parseExpected(71 /* CaseKeyword */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(54 /* ColonToken */);
+ node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
+ return finishNode(node);
+ }
+ function parseDefaultClause() {
+ var node = createNode(242 /* DefaultClause */);
+ parseExpected(77 /* DefaultKeyword */);
+ parseExpected(54 /* ColonToken */);
+ node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
+ return finishNode(node);
+ }
+ function parseCaseOrDefaultClause() {
+ return token === 71 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
+ }
+ function parseSwitchStatement() {
+ var node = createNode(206 /* SwitchStatement */);
+ parseExpected(96 /* SwitchKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ var caseBlock = createNode(220 /* CaseBlock */, scanner.getStartPos());
parseExpected(15 /* OpenBraceToken */);
- if (token !== 16 /* CloseBraceToken */) {
- node.expression = parseExpression();
- }
- if (inExpressionContext) {
- parseExpected(16 /* CloseBraceToken */);
- }
- else {
- parseExpected(16 /* CloseBraceToken */, /*message*/ undefined, /*advance*/ false);
- scanJsxText();
- }
+ caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
+ parseExpected(16 /* CloseBraceToken */);
+ node.caseBlock = finishNode(caseBlock);
return finishNode(node);
}
- function parseJsxAttribute() {
- if (token === 15 /* OpenBraceToken */) {
- return parseJsxSpreadAttribute();
- }
- scanJsxIdentifier();
- var node = createNode(238 /* JsxAttribute */);
- node.name = parseIdentifierName();
- if (parseOptional(56 /* EqualsToken */)) {
- switch (token) {
- case 9 /* StringLiteral */:
- node.initializer = parseLiteralNode();
- break;
- default:
- node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
- break;
- }
+ function parseThrowStatement() {
+ // ThrowStatement[Yield] :
+ // throw [no LineTerminator here]Expression[In, ?Yield];
+ // Because of automatic semicolon insertion, we need to report error if this
+ // throw could be terminated with a semicolon. Note: we can't call 'parseExpression'
+ // directly as that might consume an expression on the following line.
+ // We just return 'undefined' in that case. The actual error will be reported in the
+ // grammar walker.
+ var node = createNode(208 /* ThrowStatement */);
+ parseExpected(98 /* ThrowKeyword */);
+ node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
+ parseSemicolon();
+ return finishNode(node);
+ }
+ // TODO: Review for error recovery
+ function parseTryStatement() {
+ var node = createNode(209 /* TryStatement */);
+ parseExpected(100 /* TryKeyword */);
+ node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
+ node.catchClause = token === 72 /* CatchKeyword */ ? parseCatchClause() : undefined;
+ // If we don't have a catch clause, then we must have a finally clause. Try to parse
+ // one out no matter what.
+ if (!node.catchClause || token === 85 /* FinallyKeyword */) {
+ parseExpected(85 /* FinallyKeyword */);
+ node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
}
return finishNode(node);
}
- function parseJsxSpreadAttribute() {
- var node = createNode(239 /* JsxSpreadAttribute */);
- parseExpected(15 /* OpenBraceToken */);
- parseExpected(22 /* DotDotDotToken */);
- node.expression = parseExpression();
- parseExpected(16 /* CloseBraceToken */);
+ function parseCatchClause() {
+ var result = createNode(244 /* CatchClause */);
+ parseExpected(72 /* CatchKeyword */);
+ if (parseExpected(17 /* OpenParenToken */)) {
+ result.variableDeclaration = parseVariableDeclaration();
+ }
+ parseExpected(18 /* CloseParenToken */);
+ result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
+ return finishNode(result);
+ }
+ function parseDebuggerStatement() {
+ var node = createNode(210 /* DebuggerStatement */);
+ parseExpected(76 /* DebuggerKeyword */);
+ parseSemicolon();
return finishNode(node);
}
- function parseJsxClosingElement(inExpressionContext) {
- var node = createNode(237 /* JsxClosingElement */);
- parseExpected(26 /* LessThanSlashToken */);
- node.tagName = parseJsxElementName();
- if (inExpressionContext) {
- parseExpected(27 /* GreaterThanToken */);
+ function parseExpressionOrLabeledStatement() {
+ // Avoiding having to do the lookahead for a labeled statement by just trying to parse
+ // out an expression, seeing if it is identifier and then seeing if it is followed by
+ // a colon.
+ var fullStart = scanner.getStartPos();
+ var expression = allowInAnd(parseExpression);
+ if (expression.kind === 69 /* Identifier */ && parseOptional(54 /* ColonToken */)) {
+ var labeledStatement = createNode(207 /* LabeledStatement */, fullStart);
+ labeledStatement.label = expression;
+ labeledStatement.statement = parseStatement();
+ return finishNode(labeledStatement);
}
else {
- parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*advance*/ false);
- scanJsxText();
+ var expressionStatement = createNode(195 /* ExpressionStatement */, fullStart);
+ expressionStatement.expression = expression;
+ parseSemicolon();
+ return finishNode(expressionStatement);
}
- return finishNode(node);
}
- function parseTypeAssertion() {
- var node = createNode(171 /* TypeAssertionExpression */);
- parseExpected(25 /* LessThanToken */);
- node.type = parseType();
- parseExpected(27 /* GreaterThanToken */);
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function nextTokenIsIdentifierOrKeywordOnSameLine() {
+ nextToken();
+ return ts.tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
}
- function parseMemberExpressionRest(expression) {
- while (true) {
- var dotToken = parseOptionalToken(21 /* DotToken */);
- if (dotToken) {
- var propertyAccess = createNode(166 /* PropertyAccessExpression */, expression.pos);
- propertyAccess.expression = expression;
- propertyAccess.dotToken = dotToken;
- propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
- expression = finishNode(propertyAccess);
- continue;
- }
- // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
- if (!inDecoratorContext() && parseOptional(19 /* OpenBracketToken */)) {
- var indexedAccess = createNode(167 /* ElementAccessExpression */, expression.pos);
- indexedAccess.expression = expression;
- // It's not uncommon for a user to write: "new Type[]".
- // Check for that common pattern and report a better error message.
- if (token !== 20 /* CloseBracketToken */) {
- indexedAccess.argumentExpression = allowInAnd(parseExpression);
- if (indexedAccess.argumentExpression.kind === 9 /* StringLiteral */ || indexedAccess.argumentExpression.kind === 8 /* NumericLiteral */) {
- var literal = indexedAccess.argumentExpression;
- literal.text = internIdentifier(literal.text);
- }
- }
- parseExpected(20 /* CloseBracketToken */);
- expression = finishNode(indexedAccess);
- continue;
- }
- if (token === 11 /* NoSubstitutionTemplateLiteral */ || token === 12 /* TemplateHead */) {
- var tagExpression = createNode(170 /* TaggedTemplateExpression */, expression.pos);
- tagExpression.tag = expression;
- tagExpression.template = token === 11 /* NoSubstitutionTemplateLiteral */
- ? parseLiteralNode()
- : parseTemplateExpression();
- expression = finishNode(tagExpression);
- continue;
- }
- return expression;
- }
+ function nextTokenIsFunctionKeywordOnSameLine() {
+ nextToken();
+ return token === 87 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
}
- function parseCallExpressionRest(expression) {
+ function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
+ nextToken();
+ return (ts.tokenIsIdentifierOrKeyword(token) || token === 8 /* NumericLiteral */) && !scanner.hasPrecedingLineBreak();
+ }
+ function isDeclaration() {
while (true) {
- expression = parseMemberExpressionRest(expression);
- if (token === 25 /* LessThanToken */) {
- // See if this is the start of a generic invocation. If so, consume it and
- // keep checking for postfix expressions. Otherwise, it's just a '<' that's
- // part of an arithmetic expression. Break out so we consume it higher in the
- // stack.
- var typeArguments = tryParse(parseTypeArgumentsInExpression);
- if (!typeArguments) {
- return expression;
- }
- var callExpr = createNode(168 /* CallExpression */, expression.pos);
- callExpr.expression = expression;
- callExpr.typeArguments = typeArguments;
- callExpr.arguments = parseArgumentList();
- expression = finishNode(callExpr);
- continue;
- }
- else if (token === 17 /* OpenParenToken */) {
- var callExpr = createNode(168 /* CallExpression */, expression.pos);
- callExpr.expression = expression;
- callExpr.arguments = parseArgumentList();
- expression = finishNode(callExpr);
- continue;
+ switch (token) {
+ case 102 /* VarKeyword */:
+ case 108 /* LetKeyword */:
+ case 74 /* ConstKeyword */:
+ case 87 /* FunctionKeyword */:
+ case 73 /* ClassKeyword */:
+ case 81 /* EnumKeyword */:
+ return true;
+ // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
+ // however, an identifier cannot be followed by another identifier on the same line. This is what we
+ // count on to parse out the respective declarations. For instance, we exploit this to say that
+ //
+ // namespace n
+ //
+ // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
+ //
+ // namespace
+ // n
+ //
+ // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
+ // We need to look one token ahead to see if it permissible to try parsing a declaration.
+ //
+ // *Note*: 'interface' is actually a strict mode reserved word. So while
+ //
+ // "use strict"
+ // interface
+ // I {}
+ //
+ // could be legal, it would add complexity for very little gain.
+ case 107 /* InterfaceKeyword */:
+ case 132 /* TypeKeyword */:
+ return nextTokenIsIdentifierOnSameLine();
+ case 125 /* ModuleKeyword */:
+ case 126 /* NamespaceKeyword */:
+ return nextTokenIsIdentifierOrStringLiteralOnSameLine();
+ case 115 /* AbstractKeyword */:
+ case 118 /* AsyncKeyword */:
+ case 122 /* DeclareKeyword */:
+ case 110 /* PrivateKeyword */:
+ case 111 /* ProtectedKeyword */:
+ case 112 /* PublicKeyword */:
+ nextToken();
+ // ASI takes effect for this modifier.
+ if (scanner.hasPrecedingLineBreak()) {
+ return false;
+ }
+ continue;
+ case 89 /* ImportKeyword */:
+ nextToken();
+ return token === 9 /* StringLiteral */ || token === 37 /* AsteriskToken */ ||
+ token === 15 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token);
+ case 82 /* ExportKeyword */:
+ nextToken();
+ if (token === 56 /* EqualsToken */ || token === 37 /* AsteriskToken */ ||
+ token === 15 /* OpenBraceToken */ || token === 77 /* DefaultKeyword */) {
+ return true;
+ }
+ continue;
+ case 113 /* StaticKeyword */:
+ nextToken();
+ continue;
+ default:
+ return false;
}
- return expression;
}
}
- function parseArgumentList() {
- parseExpected(17 /* OpenParenToken */);
- var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
- parseExpected(18 /* CloseParenToken */);
- return result;
- }
- function parseTypeArgumentsInExpression() {
- if (!parseOptional(25 /* LessThanToken */)) {
- return undefined;
- }
- var typeArguments = parseDelimitedList(18 /* TypeArguments */, parseType);
- if (!parseExpected(27 /* GreaterThanToken */)) {
- // If it doesn't have the closing > then it's definitely not an type argument list.
- return undefined;
- }
- // If we have a '<', then only parse this as a arugment list if the type arguments
- // are complete and we have an open paren. if we don't, rewind and return nothing.
- return typeArguments && canFollowTypeArgumentsInExpression()
- ? typeArguments
- : undefined;
+ function isStartOfDeclaration() {
+ return lookAhead(isDeclaration);
}
- function canFollowTypeArgumentsInExpression() {
+ function isStartOfStatement() {
switch (token) {
- case 17 /* OpenParenToken */: // foo(
- // this case are the only case where this token can legally follow a type argument
- // list. So we definitely want to treat this as a type arg list.
- case 21 /* DotToken */: // foo.
- case 18 /* CloseParenToken */: // foo)
- case 20 /* CloseBracketToken */: // foo]
- case 54 /* ColonToken */: // foo:
- case 23 /* SemicolonToken */: // foo;
- case 53 /* QuestionToken */: // foo?
- case 30 /* EqualsEqualsToken */: // foo ==
- case 32 /* EqualsEqualsEqualsToken */: // foo ===
- case 31 /* ExclamationEqualsToken */: // foo !=
- case 33 /* ExclamationEqualsEqualsToken */: // foo !==
- case 51 /* AmpersandAmpersandToken */: // foo &&
- case 52 /* BarBarToken */: // foo ||
- case 48 /* CaretToken */: // foo ^
- case 46 /* AmpersandToken */: // foo &
- case 47 /* BarToken */: // foo |
- case 16 /* CloseBraceToken */: // foo }
- case 1 /* EndOfFileToken */:
- // these cases can't legally follow a type arg list. However, they're not legal
- // expressions either. The user is probably in the middle of a generic type. So
- // treat it as such.
+ case 55 /* AtToken */:
+ case 23 /* SemicolonToken */:
+ case 15 /* OpenBraceToken */:
+ case 102 /* VarKeyword */:
+ case 108 /* LetKeyword */:
+ case 87 /* FunctionKeyword */:
+ case 73 /* ClassKeyword */:
+ case 81 /* EnumKeyword */:
+ case 88 /* IfKeyword */:
+ case 79 /* DoKeyword */:
+ case 104 /* WhileKeyword */:
+ case 86 /* ForKeyword */:
+ case 75 /* ContinueKeyword */:
+ case 70 /* BreakKeyword */:
+ case 94 /* ReturnKeyword */:
+ case 105 /* WithKeyword */:
+ case 96 /* SwitchKeyword */:
+ case 98 /* ThrowKeyword */:
+ case 100 /* TryKeyword */:
+ case 76 /* DebuggerKeyword */:
+ // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
+ // however, we say they are here so that we may gracefully parse them and error later.
+ case 72 /* CatchKeyword */:
+ case 85 /* FinallyKeyword */:
return true;
- case 24 /* CommaToken */: // foo,
- case 15 /* OpenBraceToken */: // foo {
- // We don't want to treat these as type arguments. Otherwise we'll parse this
- // as an invocation expression. Instead, we want to parse out the expression
- // in isolation from the type arguments.
+ case 74 /* ConstKeyword */:
+ case 82 /* ExportKeyword */:
+ case 89 /* ImportKeyword */:
+ return isStartOfDeclaration();
+ case 118 /* AsyncKeyword */:
+ case 122 /* DeclareKeyword */:
+ case 107 /* InterfaceKeyword */:
+ case 125 /* ModuleKeyword */:
+ case 126 /* NamespaceKeyword */:
+ case 132 /* TypeKeyword */:
+ // When these don't start a declaration, they're an identifier in an expression statement
+ return true;
+ case 112 /* PublicKeyword */:
+ case 110 /* PrivateKeyword */:
+ case 111 /* ProtectedKeyword */:
+ case 113 /* StaticKeyword */:
+ // When these don't start a declaration, they may be the start of a class member if an identifier
+ // immediately follows. Otherwise they're an identifier in an expression statement.
+ return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
default:
- // Anything else treat as an expression.
- return false;
+ return isStartOfExpression();
}
}
- function parsePrimaryExpression() {
+ function nextTokenIsIdentifierOrStartOfDestructuring() {
+ nextToken();
+ return isIdentifier() || token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */;
+ }
+ function isLetDeclaration() {
+ // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
+ // or [.
+ return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
+ }
+ function parseStatement() {
switch (token) {
- case 8 /* NumericLiteral */:
- case 9 /* StringLiteral */:
- case 11 /* NoSubstitutionTemplateLiteral */:
- return parseLiteralNode();
- case 97 /* ThisKeyword */:
- case 95 /* SuperKeyword */:
- case 93 /* NullKeyword */:
- case 99 /* TrueKeyword */:
- case 84 /* FalseKeyword */:
- return parseTokenNode();
- case 17 /* OpenParenToken */:
- return parseParenthesizedExpression();
- case 19 /* OpenBracketToken */:
- return parseArrayLiteralExpression();
+ case 23 /* SemicolonToken */:
+ return parseEmptyStatement();
case 15 /* OpenBraceToken */:
- return parseObjectLiteralExpression();
- case 118 /* AsyncKeyword */:
- // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
- // If we encounter `async [no LineTerminator here] function` then this is an async
- // function; otherwise, its an identifier.
- if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
- break;
+ return parseBlock(/*ignoreMissingOpenBrace*/ false);
+ case 102 /* VarKeyword */:
+ return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+ case 108 /* LetKeyword */:
+ if (isLetDeclaration()) {
+ return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
}
- return parseFunctionExpression();
- case 73 /* ClassKeyword */:
- return parseClassExpression();
+ break;
case 87 /* FunctionKeyword */:
- return parseFunctionExpression();
- case 92 /* NewKeyword */:
- return parseNewExpression();
- case 39 /* SlashToken */:
- case 61 /* SlashEqualsToken */:
- if (reScanSlashToken() === 10 /* RegularExpressionLiteral */) {
- return parseLiteralNode();
+ return parseFunctionDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+ case 73 /* ClassKeyword */:
+ return parseClassDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+ case 88 /* IfKeyword */:
+ return parseIfStatement();
+ case 79 /* DoKeyword */:
+ return parseDoStatement();
+ case 104 /* WhileKeyword */:
+ return parseWhileStatement();
+ case 86 /* ForKeyword */:
+ return parseForOrForInOrForOfStatement();
+ case 75 /* ContinueKeyword */:
+ return parseBreakOrContinueStatement(202 /* ContinueStatement */);
+ case 70 /* BreakKeyword */:
+ return parseBreakOrContinueStatement(203 /* BreakStatement */);
+ case 94 /* ReturnKeyword */:
+ return parseReturnStatement();
+ case 105 /* WithKeyword */:
+ return parseWithStatement();
+ case 96 /* SwitchKeyword */:
+ return parseSwitchStatement();
+ case 98 /* ThrowKeyword */:
+ return parseThrowStatement();
+ case 100 /* TryKeyword */:
+ // Include 'catch' and 'finally' for error recovery.
+ case 72 /* CatchKeyword */:
+ case 85 /* FinallyKeyword */:
+ return parseTryStatement();
+ case 76 /* DebuggerKeyword */:
+ return parseDebuggerStatement();
+ case 55 /* AtToken */:
+ return parseDeclaration();
+ case 118 /* AsyncKeyword */:
+ case 107 /* InterfaceKeyword */:
+ case 132 /* TypeKeyword */:
+ case 125 /* ModuleKeyword */:
+ case 126 /* NamespaceKeyword */:
+ case 122 /* DeclareKeyword */:
+ case 74 /* ConstKeyword */:
+ case 81 /* EnumKeyword */:
+ case 82 /* ExportKeyword */:
+ case 89 /* ImportKeyword */:
+ case 110 /* PrivateKeyword */:
+ case 111 /* ProtectedKeyword */:
+ case 112 /* PublicKeyword */:
+ case 115 /* AbstractKeyword */:
+ case 113 /* StaticKeyword */:
+ if (isStartOfDeclaration()) {
+ return parseDeclaration();
}
break;
- case 12 /* TemplateHead */:
- return parseTemplateExpression();
}
- return parseIdentifier(ts.Diagnostics.Expression_expected);
- }
- function parseParenthesizedExpression() {
- var node = createNode(172 /* ParenthesizedExpression */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- return finishNode(node);
- }
- function parseSpreadElement() {
- var node = createNode(185 /* SpreadElementExpression */);
- parseExpected(22 /* DotDotDotToken */);
- node.expression = parseAssignmentExpressionOrHigher();
- return finishNode(node);
- }
- function parseArgumentOrArrayLiteralElement() {
- return token === 22 /* DotDotDotToken */ ? parseSpreadElement() :
- token === 24 /* CommaToken */ ? createNode(187 /* OmittedExpression */) :
- parseAssignmentExpressionOrHigher();
+ return parseExpressionOrLabeledStatement();
}
- function parseArgumentExpression() {
- return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
+ function parseDeclaration() {
+ var fullStart = getNodePos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ switch (token) {
+ case 102 /* VarKeyword */:
+ case 108 /* LetKeyword */:
+ case 74 /* ConstKeyword */:
+ return parseVariableStatement(fullStart, decorators, modifiers);
+ case 87 /* FunctionKeyword */:
+ return parseFunctionDeclaration(fullStart, decorators, modifiers);
+ case 73 /* ClassKeyword */:
+ return parseClassDeclaration(fullStart, decorators, modifiers);
+ case 107 /* InterfaceKeyword */:
+ return parseInterfaceDeclaration(fullStart, decorators, modifiers);
+ case 132 /* TypeKeyword */:
+ return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
+ case 81 /* EnumKeyword */:
+ return parseEnumDeclaration(fullStart, decorators, modifiers);
+ case 125 /* ModuleKeyword */:
+ case 126 /* NamespaceKeyword */:
+ return parseModuleDeclaration(fullStart, decorators, modifiers);
+ case 89 /* ImportKeyword */:
+ return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
+ case 82 /* ExportKeyword */:
+ nextToken();
+ return token === 77 /* DefaultKeyword */ || token === 56 /* EqualsToken */ ?
+ parseExportAssignment(fullStart, decorators, modifiers) :
+ parseExportDeclaration(fullStart, decorators, modifiers);
+ default:
+ if (decorators || modifiers) {
+ // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
+ // would follow. For recovery and error reporting purposes, return an incomplete declaration.
+ var node = createMissingNode(231 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
+ node.pos = fullStart;
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ return finishNode(node);
+ }
+ }
}
- function parseArrayLiteralExpression() {
- var node = createNode(164 /* ArrayLiteralExpression */);
- parseExpected(19 /* OpenBracketToken */);
- if (scanner.hasPrecedingLineBreak())
- node.flags |= 1024 /* MultiLine */;
- node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
- parseExpected(20 /* CloseBracketToken */);
- return finishNode(node);
+ function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
+ nextToken();
+ return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === 9 /* StringLiteral */);
}
- function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
- if (parseContextualModifier(123 /* GetKeyword */)) {
- return parseAccessorDeclaration(145 /* GetAccessor */, fullStart, decorators, modifiers);
- }
- else if (parseContextualModifier(129 /* SetKeyword */)) {
- return parseAccessorDeclaration(146 /* SetAccessor */, fullStart, decorators, modifiers);
+ function parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage) {
+ if (token !== 15 /* OpenBraceToken */ && canParseSemicolon()) {
+ parseSemicolon();
+ return;
}
- return undefined;
+ return parseFunctionBlock(isGenerator, isAsync, /*ignoreMissingOpenBrace*/ false, diagnosticMessage);
}
- function parseObjectLiteralElement() {
- var fullStart = scanner.getStartPos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
- if (accessor) {
- return accessor;
- }
- var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
- var tokenIsIdentifier = isIdentifier();
- var nameToken = token;
- var propertyName = parsePropertyName();
- // Disallowing of optional property assignments happens in the grammar checker.
- var questionToken = parseOptionalToken(53 /* QuestionToken */);
- if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
- return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
+ // DECLARATIONS
+ function parseArrayBindingElement() {
+ if (token === 24 /* CommaToken */) {
+ return createNode(187 /* OmittedExpression */);
}
- // check if it is short-hand property assignment or normal property assignment
- // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
- // CoverInitializedName[Yield] :
- // IdentifierReference[?Yield] Initializer[In, ?Yield]
- // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
- var isShorthandPropertyAssignment = tokenIsIdentifier && (token === 24 /* CommaToken */ || token === 16 /* CloseBraceToken */ || token === 56 /* EqualsToken */);
- if (isShorthandPropertyAssignment) {
- var shorthandDeclaration = createNode(246 /* ShorthandPropertyAssignment */, fullStart);
- shorthandDeclaration.name = propertyName;
- shorthandDeclaration.questionToken = questionToken;
- var equalsToken = parseOptionalToken(56 /* EqualsToken */);
- if (equalsToken) {
- shorthandDeclaration.equalsToken = equalsToken;
- shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
- }
- return finishNode(shorthandDeclaration);
+ var node = createNode(163 /* BindingElement */);
+ node.dotDotDotToken = parseOptionalToken(22 /* DotDotDotToken */);
+ node.name = parseIdentifierOrPattern();
+ node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
+ return finishNode(node);
+ }
+ function parseObjectBindingElement() {
+ var node = createNode(163 /* BindingElement */);
+ var tokenIsIdentifier = isIdentifier();
+ var propertyName = parsePropertyName();
+ if (tokenIsIdentifier && token !== 54 /* ColonToken */) {
+ node.name = propertyName;
}
else {
- var propertyAssignment = createNode(245 /* PropertyAssignment */, fullStart);
- propertyAssignment.name = propertyName;
- propertyAssignment.questionToken = questionToken;
parseExpected(54 /* ColonToken */);
- propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
- return finishNode(propertyAssignment);
+ node.propertyName = propertyName;
+ node.name = parseIdentifierOrPattern();
}
+ node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
+ return finishNode(node);
}
- function parseObjectLiteralExpression() {
- var node = createNode(165 /* ObjectLiteralExpression */);
+ function parseObjectBindingPattern() {
+ var node = createNode(161 /* ObjectBindingPattern */);
parseExpected(15 /* OpenBraceToken */);
- if (scanner.hasPrecedingLineBreak()) {
- node.flags |= 1024 /* MultiLine */;
- }
- node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimeter*/ true);
+ node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
parseExpected(16 /* CloseBraceToken */);
return finishNode(node);
}
- function parseFunctionExpression() {
- // GeneratorExpression:
- // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
- //
- // FunctionExpression:
- // function BindingIdentifier[opt](FormalParameters){ FunctionBody }
- var saveDecoratorContext = inDecoratorContext();
- if (saveDecoratorContext) {
- setDecoratorContext(false);
- }
- var node = createNode(173 /* FunctionExpression */);
- setModifiers(node, parseModifiers());
- parseExpected(87 /* FunctionKeyword */);
- node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
- var isGenerator = !!node.asteriskToken;
- var isAsync = !!(node.flags & 256 /* Async */);
- node.name =
- isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
- isGenerator ? doInYieldContext(parseOptionalIdentifier) :
- isAsync ? doInAwaitContext(parseOptionalIdentifier) :
- parseOptionalIdentifier();
- fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
- node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
- if (saveDecoratorContext) {
- setDecoratorContext(true);
- }
+ function parseArrayBindingPattern() {
+ var node = createNode(162 /* ArrayBindingPattern */);
+ parseExpected(19 /* OpenBracketToken */);
+ node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
+ parseExpected(20 /* CloseBracketToken */);
return finishNode(node);
}
- function parseOptionalIdentifier() {
- return isIdentifier() ? parseIdentifier() : undefined;
+ function isIdentifierOrPattern() {
+ return token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */ || isIdentifier();
}
- function parseNewExpression() {
- var node = createNode(169 /* NewExpression */);
- parseExpected(92 /* NewKeyword */);
- node.expression = parseMemberExpressionOrHigher();
- node.typeArguments = tryParse(parseTypeArgumentsInExpression);
- if (node.typeArguments || token === 17 /* OpenParenToken */) {
- node.arguments = parseArgumentList();
+ function parseIdentifierOrPattern() {
+ if (token === 19 /* OpenBracketToken */) {
+ return parseArrayBindingPattern();
+ }
+ if (token === 15 /* OpenBraceToken */) {
+ return parseObjectBindingPattern();
+ }
+ return parseIdentifier();
+ }
+ function parseVariableDeclaration() {
+ var node = createNode(211 /* VariableDeclaration */);
+ node.name = parseIdentifierOrPattern();
+ node.type = parseTypeAnnotation();
+ if (!isInOrOfKeyword(token)) {
+ node.initializer = parseInitializer(/*inParameter*/ false);
}
return finishNode(node);
}
- // STATEMENTS
- function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
- var node = createNode(192 /* Block */);
- if (parseExpected(15 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
- node.statements = parseList(1 /* BlockStatements */, parseStatement);
- parseExpected(16 /* CloseBraceToken */);
+ function parseVariableDeclarationList(inForStatementInitializer) {
+ var node = createNode(212 /* VariableDeclarationList */);
+ switch (token) {
+ case 102 /* VarKeyword */:
+ break;
+ case 108 /* LetKeyword */:
+ node.flags |= 8192 /* Let */;
+ break;
+ case 74 /* ConstKeyword */:
+ node.flags |= 16384 /* Const */;
+ break;
+ default:
+ ts.Debug.fail();
+ }
+ nextToken();
+ // The user may have written the following:
+ //
+ // for (let of X) { }
+ //
+ // In this case, we want to parse an empty declaration list, and then parse 'of'
+ // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
+ // So we need to look ahead to determine if 'of' should be treated as a keyword in
+ // this context.
+ // The checker will then give an error that there is an empty declaration list.
+ if (token === 134 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
+ node.declarations = createMissingList();
}
else {
- node.statements = createMissingList();
+ var savedDisallowIn = inDisallowInContext();
+ setDisallowInContext(inForStatementInitializer);
+ node.declarations = parseDelimitedList(8 /* VariableDeclarations */, parseVariableDeclaration);
+ setDisallowInContext(savedDisallowIn);
}
return finishNode(node);
}
- function parseFunctionBlock(allowYield, allowAwait, ignoreMissingOpenBrace, diagnosticMessage) {
- var savedYieldContext = inYieldContext();
- setYieldContext(allowYield);
- var savedAwaitContext = inAwaitContext();
- setAwaitContext(allowAwait);
- // We may be in a [Decorator] context when parsing a function expression or
- // arrow function. The body of the function is not in [Decorator] context.
- var saveDecoratorContext = inDecoratorContext();
- if (saveDecoratorContext) {
- setDecoratorContext(false);
- }
- var block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
- if (saveDecoratorContext) {
- setDecoratorContext(true);
- }
- setYieldContext(savedYieldContext);
- setAwaitContext(savedAwaitContext);
- return block;
+ function canFollowContextualOfKeyword() {
+ return nextTokenIsIdentifier() && nextToken() === 18 /* CloseParenToken */;
}
- function parseEmptyStatement() {
- var node = createNode(194 /* EmptyStatement */);
- parseExpected(23 /* SemicolonToken */);
+ function parseVariableStatement(fullStart, decorators, modifiers) {
+ var node = createNode(193 /* VariableStatement */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
+ parseSemicolon();
return finishNode(node);
}
- function parseIfStatement() {
- var node = createNode(196 /* IfStatement */);
- parseExpected(88 /* IfKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- node.thenStatement = parseStatement();
- node.elseStatement = parseOptional(80 /* ElseKeyword */) ? parseStatement() : undefined;
+ function parseFunctionDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(213 /* FunctionDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(87 /* FunctionKeyword */);
+ node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
+ node.name = node.flags & 512 /* Default */ ? parseOptionalIdentifier() : parseIdentifier();
+ var isGenerator = !!node.asteriskToken;
+ var isAsync = !!(node.flags & 256 /* Async */);
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
+ node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, ts.Diagnostics.or_expected);
return finishNode(node);
}
- function parseDoStatement() {
- var node = createNode(197 /* DoStatement */);
- parseExpected(79 /* DoKeyword */);
- node.statement = parseStatement();
- parseExpected(104 /* WhileKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
- // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
- // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
- // do;while(0)x will have a semicolon inserted before x.
- parseOptional(23 /* SemicolonToken */);
+ function parseConstructorDeclaration(pos, decorators, modifiers) {
+ var node = createNode(144 /* Constructor */, pos);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(121 /* ConstructorKeyword */);
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
+ node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false, ts.Diagnostics.or_expected);
return finishNode(node);
}
- function parseWhileStatement() {
- var node = createNode(198 /* WhileStatement */);
- parseExpected(104 /* WhileKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- node.statement = parseStatement();
+ function parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, diagnosticMessage) {
+ var method = createNode(143 /* MethodDeclaration */, fullStart);
+ method.decorators = decorators;
+ setModifiers(method, modifiers);
+ method.asteriskToken = asteriskToken;
+ method.name = name;
+ method.questionToken = questionToken;
+ var isGenerator = !!asteriskToken;
+ var isAsync = !!(method.flags & 256 /* Async */);
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, method);
+ method.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage);
+ return finishNode(method);
+ }
+ function parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken) {
+ var property = createNode(141 /* PropertyDeclaration */, fullStart);
+ property.decorators = decorators;
+ setModifiers(property, modifiers);
+ property.name = name;
+ property.questionToken = questionToken;
+ property.type = parseTypeAnnotation();
+ // For instance properties specifically, since they are evaluated inside the constructor,
+ // we do *not * want to parse yield expressions, so we specifically turn the yield context
+ // off. The grammar would look something like this:
+ //
+ // MemberVariableDeclaration[Yield]:
+ // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initialiser_opt[In];
+ // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initialiser_opt[In, ?Yield];
+ //
+ // The checker may still error in the static case to explicitly disallow the yield expression.
+ property.initializer = modifiers && modifiers.flags & 64 /* Static */
+ ? allowInAnd(parseNonParameterInitializer)
+ : doOutsideOfContext(2 /* Yield */ | 1 /* DisallowIn */, parseNonParameterInitializer);
+ parseSemicolon();
+ return finishNode(property);
+ }
+ function parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers) {
+ var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
+ var name = parsePropertyName();
+ // Note: this is not legal as per the grammar. But we allow it in the parser and
+ // report an error in the grammar checker.
+ var questionToken = parseOptionalToken(53 /* QuestionToken */);
+ if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
+ return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, ts.Diagnostics.or_expected);
+ }
+ else {
+ return parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken);
+ }
+ }
+ function parseNonParameterInitializer() {
+ return parseInitializer(/*inParameter*/ false);
+ }
+ function parseAccessorDeclaration(kind, fullStart, decorators, modifiers) {
+ var node = createNode(kind, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.name = parsePropertyName();
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
+ node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false);
return finishNode(node);
}
- function parseForOrForInOrForOfStatement() {
- var pos = getNodePos();
- parseExpected(86 /* ForKeyword */);
- parseExpected(17 /* OpenParenToken */);
- var initializer = undefined;
- if (token !== 23 /* SemicolonToken */) {
- if (token === 102 /* VarKeyword */ || token === 108 /* LetKeyword */ || token === 74 /* ConstKeyword */) {
- initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
+ function isClassMemberModifier(idToken) {
+ switch (idToken) {
+ case 112 /* PublicKeyword */:
+ case 110 /* PrivateKeyword */:
+ case 111 /* ProtectedKeyword */:
+ case 113 /* StaticKeyword */:
+ return true;
+ default:
+ return false;
+ }
+ }
+ function isClassMemberStart() {
+ var idToken;
+ if (token === 55 /* AtToken */) {
+ return true;
+ }
+ // Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
+ while (ts.isModifier(token)) {
+ idToken = token;
+ // If the idToken is a class modifier (protected, private, public, and static), it is
+ // certain that we are starting to parse class member. This allows better error recovery
+ // Example:
+ // public foo() ... // true
+ // public @dec blah ... // true; we will then report an error later
+ // export public ... // true; we will then report an error later
+ if (isClassMemberModifier(idToken)) {
+ return true;
}
- else {
- initializer = disallowInAnd(parseExpression);
+ nextToken();
+ }
+ if (token === 37 /* AsteriskToken */) {
+ return true;
+ }
+ // Try to get the first property-like token following all modifiers.
+ // This can either be an identifier or the 'get' or 'set' keywords.
+ if (isLiteralPropertyName()) {
+ idToken = token;
+ nextToken();
+ }
+ // Index signatures and computed properties are class members; we can parse.
+ if (token === 19 /* OpenBracketToken */) {
+ return true;
+ }
+ // If we were able to get any potential identifier...
+ if (idToken !== undefined) {
+ // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
+ if (!ts.isKeyword(idToken) || idToken === 129 /* SetKeyword */ || idToken === 123 /* GetKeyword */) {
+ return true;
+ }
+ // If it *is* a keyword, but not an accessor, check a little farther along
+ // to see if it should actually be parsed as a class member.
+ switch (token) {
+ case 17 /* OpenParenToken */: // Method declaration
+ case 25 /* LessThanToken */: // Generic Method declaration
+ case 54 /* ColonToken */: // Type Annotation for declaration
+ case 56 /* EqualsToken */: // Initializer for declaration
+ case 53 /* QuestionToken */:
+ return true;
+ default:
+ // Covers
+ // - Semicolons (declaration termination)
+ // - Closing braces (end-of-class, must be declaration)
+ // - End-of-files (not valid, but permitted so that it gets caught later on)
+ // - Line-breaks (enabling *automatic semicolon insertion*)
+ return canParseSemicolon();
}
}
- var forOrForInOrForOfStatement;
- if (parseOptional(90 /* InKeyword */)) {
- var forInStatement = createNode(200 /* ForInStatement */, pos);
- forInStatement.initializer = initializer;
- forInStatement.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- forOrForInOrForOfStatement = forInStatement;
+ return false;
+ }
+ function parseDecorators() {
+ var decorators;
+ while (true) {
+ var decoratorStart = getNodePos();
+ if (!parseOptional(55 /* AtToken */)) {
+ break;
+ }
+ if (!decorators) {
+ decorators = [];
+ decorators.pos = scanner.getStartPos();
+ }
+ var decorator = createNode(139 /* Decorator */, decoratorStart);
+ decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
+ decorators.push(finishNode(decorator));
}
- else if (parseOptional(134 /* OfKeyword */)) {
- var forOfStatement = createNode(201 /* ForOfStatement */, pos);
- forOfStatement.initializer = initializer;
- forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
- parseExpected(18 /* CloseParenToken */);
- forOrForInOrForOfStatement = forOfStatement;
+ if (decorators) {
+ decorators.end = getNodeEnd();
}
- else {
- var forStatement = createNode(199 /* ForStatement */, pos);
- forStatement.initializer = initializer;
- parseExpected(23 /* SemicolonToken */);
- if (token !== 23 /* SemicolonToken */ && token !== 18 /* CloseParenToken */) {
- forStatement.condition = allowInAnd(parseExpression);
+ return decorators;
+ }
+ function parseModifiers() {
+ var flags = 0;
+ var modifiers;
+ while (true) {
+ var modifierStart = scanner.getStartPos();
+ var modifierKind = token;
+ if (!parseAnyContextualModifier()) {
+ break;
}
- parseExpected(23 /* SemicolonToken */);
- if (token !== 18 /* CloseParenToken */) {
- forStatement.incrementor = allowInAnd(parseExpression);
+ if (!modifiers) {
+ modifiers = [];
+ modifiers.pos = modifierStart;
}
- parseExpected(18 /* CloseParenToken */);
- forOrForInOrForOfStatement = forStatement;
+ flags |= ts.modifierToFlag(modifierKind);
+ modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
}
- forOrForInOrForOfStatement.statement = parseStatement();
- return finishNode(forOrForInOrForOfStatement);
+ if (modifiers) {
+ modifiers.flags = flags;
+ modifiers.end = scanner.getStartPos();
+ }
+ return modifiers;
}
- function parseBreakOrContinueStatement(kind) {
- var node = createNode(kind);
- parseExpected(kind === 203 /* BreakStatement */ ? 70 /* BreakKeyword */ : 75 /* ContinueKeyword */);
- if (!canParseSemicolon()) {
- node.label = parseIdentifier();
+ function parseModifiersForArrowFunction() {
+ var flags = 0;
+ var modifiers;
+ if (token === 118 /* AsyncKeyword */) {
+ var modifierStart = scanner.getStartPos();
+ var modifierKind = token;
+ nextToken();
+ modifiers = [];
+ modifiers.pos = modifierStart;
+ flags |= ts.modifierToFlag(modifierKind);
+ modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
+ modifiers.flags = flags;
+ modifiers.end = scanner.getStartPos();
}
- parseSemicolon();
- return finishNode(node);
+ return modifiers;
}
- function parseReturnStatement() {
- var node = createNode(204 /* ReturnStatement */);
- parseExpected(94 /* ReturnKeyword */);
- if (!canParseSemicolon()) {
- node.expression = allowInAnd(parseExpression);
+ function parseClassElement() {
+ if (token === 23 /* SemicolonToken */) {
+ var result = createNode(191 /* SemicolonClassElement */);
+ nextToken();
+ return finishNode(result);
}
- parseSemicolon();
- return finishNode(node);
+ var fullStart = getNodePos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
+ if (accessor) {
+ return accessor;
+ }
+ if (token === 121 /* ConstructorKeyword */) {
+ return parseConstructorDeclaration(fullStart, decorators, modifiers);
+ }
+ if (isIndexSignature()) {
+ return parseIndexSignatureDeclaration(fullStart, decorators, modifiers);
+ }
+ // It is very important that we check this *after* checking indexers because
+ // the [ token can start an index signature or a computed property name
+ if (ts.tokenIsIdentifierOrKeyword(token) ||
+ token === 9 /* StringLiteral */ ||
+ token === 8 /* NumericLiteral */ ||
+ token === 37 /* AsteriskToken */ ||
+ token === 19 /* OpenBracketToken */) {
+ return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
+ }
+ if (decorators || modifiers) {
+ // treat this as a property declaration with a missing name.
+ var name_7 = createMissingNode(69 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
+ return parsePropertyDeclaration(fullStart, decorators, modifiers, name_7, /*questionToken*/ undefined);
+ }
+ // 'isClassMemberStart' should have hinted not to attempt parsing.
+ ts.Debug.fail("Should not have attempted to parse class member declaration.");
}
- function parseWithStatement() {
- var node = createNode(205 /* WithStatement */);
- parseExpected(105 /* WithKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- node.statement = parseStatement();
+ function parseClassExpression() {
+ return parseClassDeclarationOrExpression(
+ /*fullStart*/ scanner.getStartPos(),
+ /*decorators*/ undefined,
+ /*modifiers*/ undefined, 186 /* ClassExpression */);
+ }
+ function parseClassDeclaration(fullStart, decorators, modifiers) {
+ return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 214 /* ClassDeclaration */);
+ }
+ function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
+ var node = createNode(kind, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(73 /* ClassKeyword */);
+ node.name = parseNameOfClassDeclarationOrExpression();
+ node.typeParameters = parseTypeParameters();
+ node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
+ if (parseExpected(15 /* OpenBraceToken */)) {
+ // ClassTail[Yield,Await] : (Modified) See 14.5
+ // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
+ node.members = parseClassMembers();
+ parseExpected(16 /* CloseBraceToken */);
+ }
+ else {
+ node.members = createMissingList();
+ }
return finishNode(node);
}
- function parseCaseClause() {
- var node = createNode(241 /* CaseClause */);
- parseExpected(71 /* CaseKeyword */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(54 /* ColonToken */);
- node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
- return finishNode(node);
+ function parseNameOfClassDeclarationOrExpression() {
+ // implements is a future reserved word so
+ // 'class implements' might mean either
+ // - class expression with omitted name, 'implements' starts heritage clause
+ // - class with name 'implements'
+ // 'isImplementsClause' helps to disambiguate between these two cases
+ return isIdentifier() && !isImplementsClause()
+ ? parseIdentifier()
+ : undefined;
+ }
+ function isImplementsClause() {
+ return token === 106 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
+ }
+ function parseHeritageClauses(isClassHeritageClause) {
+ // ClassTail[Yield,Await] : (Modified) See 14.5
+ // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
+ if (isHeritageClause()) {
+ return parseList(20 /* HeritageClauses */, parseHeritageClause);
+ }
+ return undefined;
+ }
+ function parseHeritageClausesWorker() {
+ return parseList(20 /* HeritageClauses */, parseHeritageClause);
+ }
+ function parseHeritageClause() {
+ if (token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */) {
+ var node = createNode(243 /* HeritageClause */);
+ node.token = token;
+ nextToken();
+ node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
+ return finishNode(node);
+ }
+ return undefined;
}
- function parseDefaultClause() {
- var node = createNode(242 /* DefaultClause */);
- parseExpected(77 /* DefaultKeyword */);
- parseExpected(54 /* ColonToken */);
- node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
+ function parseExpressionWithTypeArguments() {
+ var node = createNode(188 /* ExpressionWithTypeArguments */);
+ node.expression = parseLeftHandSideExpressionOrHigher();
+ if (token === 25 /* LessThanToken */) {
+ node.typeArguments = parseBracketedList(18 /* TypeArguments */, parseType, 25 /* LessThanToken */, 27 /* GreaterThanToken */);
+ }
return finishNode(node);
}
- function parseCaseOrDefaultClause() {
- return token === 71 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
+ function isHeritageClause() {
+ return token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
}
- function parseSwitchStatement() {
- var node = createNode(206 /* SwitchStatement */);
- parseExpected(96 /* SwitchKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- var caseBlock = createNode(220 /* CaseBlock */, scanner.getStartPos());
- parseExpected(15 /* OpenBraceToken */);
- caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
- parseExpected(16 /* CloseBraceToken */);
- node.caseBlock = finishNode(caseBlock);
+ function parseClassMembers() {
+ return parseList(5 /* ClassMembers */, parseClassElement);
+ }
+ function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(215 /* InterfaceDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(107 /* InterfaceKeyword */);
+ node.name = parseIdentifier();
+ node.typeParameters = parseTypeParameters();
+ node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false);
+ node.members = parseObjectTypeMembers();
return finishNode(node);
}
- function parseThrowStatement() {
- // ThrowStatement[Yield] :
- // throw [no LineTerminator here]Expression[In, ?Yield];
- // Because of automatic semicolon insertion, we need to report error if this
- // throw could be terminated with a semicolon. Note: we can't call 'parseExpression'
- // directly as that might consume an expression on the following line.
- // We just return 'undefined' in that case. The actual error will be reported in the
- // grammar walker.
- var node = createNode(208 /* ThrowStatement */);
- parseExpected(98 /* ThrowKeyword */);
- node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
+ function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(216 /* TypeAliasDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(132 /* TypeKeyword */);
+ node.name = parseIdentifier();
+ node.typeParameters = parseTypeParameters();
+ parseExpected(56 /* EqualsToken */);
+ node.type = parseType();
parseSemicolon();
return finishNode(node);
}
- // TODO: Review for error recovery
- function parseTryStatement() {
- var node = createNode(209 /* TryStatement */);
- parseExpected(100 /* TryKeyword */);
- node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
- node.catchClause = token === 72 /* CatchKeyword */ ? parseCatchClause() : undefined;
- // If we don't have a catch clause, then we must have a finally clause. Try to parse
- // one out no matter what.
- if (!node.catchClause || token === 85 /* FinallyKeyword */) {
- parseExpected(85 /* FinallyKeyword */);
- node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
- }
+ // In an ambient declaration, the grammar only allows integer literals as initializers.
+ // In a non-ambient declaration, the grammar allows uninitialized members only in a
+ // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
+ // or any time an integer literal initializer is encountered.
+ function parseEnumMember() {
+ var node = createNode(247 /* EnumMember */, scanner.getStartPos());
+ node.name = parsePropertyName();
+ node.initializer = allowInAnd(parseNonParameterInitializer);
return finishNode(node);
}
- function parseCatchClause() {
- var result = createNode(244 /* CatchClause */);
- parseExpected(72 /* CatchKeyword */);
- if (parseExpected(17 /* OpenParenToken */)) {
- result.variableDeclaration = parseVariableDeclaration();
+ function parseEnumDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(217 /* EnumDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(81 /* EnumKeyword */);
+ node.name = parseIdentifier();
+ if (parseExpected(15 /* OpenBraceToken */)) {
+ node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember);
+ parseExpected(16 /* CloseBraceToken */);
+ }
+ else {
+ node.members = createMissingList();
}
- parseExpected(18 /* CloseParenToken */);
- result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
- return finishNode(result);
- }
- function parseDebuggerStatement() {
- var node = createNode(210 /* DebuggerStatement */);
- parseExpected(76 /* DebuggerKeyword */);
- parseSemicolon();
return finishNode(node);
}
- function parseExpressionOrLabeledStatement() {
- // Avoiding having to do the lookahead for a labeled statement by just trying to parse
- // out an expression, seeing if it is identifier and then seeing if it is followed by
- // a colon.
- var fullStart = scanner.getStartPos();
- var expression = allowInAnd(parseExpression);
- if (expression.kind === 69 /* Identifier */ && parseOptional(54 /* ColonToken */)) {
- var labeledStatement = createNode(207 /* LabeledStatement */, fullStart);
- labeledStatement.label = expression;
- labeledStatement.statement = parseStatement();
- return finishNode(labeledStatement);
+ function parseModuleBlock() {
+ var node = createNode(219 /* ModuleBlock */, scanner.getStartPos());
+ if (parseExpected(15 /* OpenBraceToken */)) {
+ node.statements = parseList(1 /* BlockStatements */, parseStatement);
+ parseExpected(16 /* CloseBraceToken */);
}
else {
- var expressionStatement = createNode(195 /* ExpressionStatement */, fullStart);
- expressionStatement.expression = expression;
- parseSemicolon();
- return finishNode(expressionStatement);
+ node.statements = createMissingList();
}
+ return finishNode(node);
}
- function nextTokenIsIdentifierOrKeywordOnSameLine() {
- nextToken();
- return ts.tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
- }
- function nextTokenIsFunctionKeywordOnSameLine() {
- nextToken();
- return token === 87 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
+ function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
+ var node = createNode(218 /* ModuleDeclaration */, fullStart);
+ // If we are parsing a dotted namespace name, we want to
+ // propagate the 'Namespace' flag across the names if set.
+ var namespaceFlag = flags & 65536 /* Namespace */;
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.flags |= flags;
+ node.name = parseIdentifier();
+ node.body = parseOptional(21 /* DotToken */)
+ ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, 2 /* Export */ | namespaceFlag)
+ : parseModuleBlock();
+ return finishNode(node);
}
- function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
- nextToken();
- return (ts.tokenIsIdentifierOrKeyword(token) || token === 8 /* NumericLiteral */) && !scanner.hasPrecedingLineBreak();
+ function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(218 /* ModuleDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.name = parseLiteralNode(/*internName*/ true);
+ node.body = parseModuleBlock();
+ return finishNode(node);
}
- function isDeclaration() {
- while (true) {
- switch (token) {
- case 102 /* VarKeyword */:
- case 108 /* LetKeyword */:
- case 74 /* ConstKeyword */:
- case 87 /* FunctionKeyword */:
- case 73 /* ClassKeyword */:
- case 81 /* EnumKeyword */:
- return true;
- // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
- // however, an identifier cannot be followed by another identifier on the same line. This is what we
- // count on to parse out the respective declarations. For instance, we exploit this to say that
- //
- // namespace n
- //
- // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
- //
- // namespace
- // n
- //
- // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
- // We need to look one token ahead to see if it permissible to try parsing a declaration.
- //
- // *Note*: 'interface' is actually a strict mode reserved word. So while
- //
- // "use strict"
- // interface
- // I {}
- //
- // could be legal, it would add complexity for very little gain.
- case 107 /* InterfaceKeyword */:
- case 132 /* TypeKeyword */:
- return nextTokenIsIdentifierOnSameLine();
- case 125 /* ModuleKeyword */:
- case 126 /* NamespaceKeyword */:
- return nextTokenIsIdentifierOrStringLiteralOnSameLine();
- case 115 /* AbstractKeyword */:
- case 118 /* AsyncKeyword */:
- case 122 /* DeclareKeyword */:
- case 110 /* PrivateKeyword */:
- case 111 /* ProtectedKeyword */:
- case 112 /* PublicKeyword */:
- nextToken();
- // ASI takes effect for this modifier.
- if (scanner.hasPrecedingLineBreak()) {
- return false;
- }
- continue;
- case 89 /* ImportKeyword */:
- nextToken();
- return token === 9 /* StringLiteral */ || token === 37 /* AsteriskToken */ ||
- token === 15 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token);
- case 82 /* ExportKeyword */:
- nextToken();
- if (token === 56 /* EqualsToken */ || token === 37 /* AsteriskToken */ ||
- token === 15 /* OpenBraceToken */ || token === 77 /* DefaultKeyword */) {
- return true;
- }
- continue;
- case 113 /* StaticKeyword */:
- nextToken();
- continue;
- default:
- return false;
- }
+ function parseModuleDeclaration(fullStart, decorators, modifiers) {
+ var flags = modifiers ? modifiers.flags : 0;
+ if (parseOptional(126 /* NamespaceKeyword */)) {
+ flags |= 65536 /* Namespace */;
}
- }
- function isStartOfDeclaration() {
- return lookAhead(isDeclaration);
- }
- function isStartOfStatement() {
- switch (token) {
- case 55 /* AtToken */:
- case 23 /* SemicolonToken */:
- case 15 /* OpenBraceToken */:
- case 102 /* VarKeyword */:
- case 108 /* LetKeyword */:
- case 87 /* FunctionKeyword */:
- case 73 /* ClassKeyword */:
- case 81 /* EnumKeyword */:
- case 88 /* IfKeyword */:
- case 79 /* DoKeyword */:
- case 104 /* WhileKeyword */:
- case 86 /* ForKeyword */:
- case 75 /* ContinueKeyword */:
- case 70 /* BreakKeyword */:
- case 94 /* ReturnKeyword */:
- case 105 /* WithKeyword */:
- case 96 /* SwitchKeyword */:
- case 98 /* ThrowKeyword */:
- case 100 /* TryKeyword */:
- case 76 /* DebuggerKeyword */:
- // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
- // however, we say they are here so that we may gracefully parse them and error later.
- case 72 /* CatchKeyword */:
- case 85 /* FinallyKeyword */:
- return true;
- case 74 /* ConstKeyword */:
- case 82 /* ExportKeyword */:
- case 89 /* ImportKeyword */:
- return isStartOfDeclaration();
- case 118 /* AsyncKeyword */:
- case 122 /* DeclareKeyword */:
- case 107 /* InterfaceKeyword */:
- case 125 /* ModuleKeyword */:
- case 126 /* NamespaceKeyword */:
- case 132 /* TypeKeyword */:
- // When these don't start a declaration, they're an identifier in an expression statement
- return true;
- case 112 /* PublicKeyword */:
- case 110 /* PrivateKeyword */:
- case 111 /* ProtectedKeyword */:
- case 113 /* StaticKeyword */:
- // When these don't start a declaration, they may be the start of a class member if an identifier
- // immediately follows. Otherwise they're an identifier in an expression statement.
- return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
- default:
- return isStartOfExpression();
+ else {
+ parseExpected(125 /* ModuleKeyword */);
+ if (token === 9 /* StringLiteral */) {
+ return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
+ }
}
+ return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
}
- function nextTokenIsIdentifierOrStartOfDestructuring() {
- nextToken();
- return isIdentifier() || token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */;
- }
- function isLetDeclaration() {
- // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
- // or [.
- return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
+ function isExternalModuleReference() {
+ return token === 127 /* RequireKeyword */ &&
+ lookAhead(nextTokenIsOpenParen);
}
- function parseStatement() {
- switch (token) {
- case 23 /* SemicolonToken */:
- return parseEmptyStatement();
- case 15 /* OpenBraceToken */:
- return parseBlock(/*ignoreMissingOpenBrace*/ false);
- case 102 /* VarKeyword */:
- return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
- case 108 /* LetKeyword */:
- if (isLetDeclaration()) {
- return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
- }
- break;
- case 87 /* FunctionKeyword */:
- return parseFunctionDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
- case 73 /* ClassKeyword */:
- return parseClassDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
- case 88 /* IfKeyword */:
- return parseIfStatement();
- case 79 /* DoKeyword */:
- return parseDoStatement();
- case 104 /* WhileKeyword */:
- return parseWhileStatement();
- case 86 /* ForKeyword */:
- return parseForOrForInOrForOfStatement();
- case 75 /* ContinueKeyword */:
- return parseBreakOrContinueStatement(202 /* ContinueStatement */);
- case 70 /* BreakKeyword */:
- return parseBreakOrContinueStatement(203 /* BreakStatement */);
- case 94 /* ReturnKeyword */:
- return parseReturnStatement();
- case 105 /* WithKeyword */:
- return parseWithStatement();
- case 96 /* SwitchKeyword */:
- return parseSwitchStatement();
- case 98 /* ThrowKeyword */:
- return parseThrowStatement();
- case 100 /* TryKeyword */:
- // Include 'catch' and 'finally' for error recovery.
- case 72 /* CatchKeyword */:
- case 85 /* FinallyKeyword */:
- return parseTryStatement();
- case 76 /* DebuggerKeyword */:
- return parseDebuggerStatement();
- case 55 /* AtToken */:
- return parseDeclaration();
- case 118 /* AsyncKeyword */:
- case 107 /* InterfaceKeyword */:
- case 132 /* TypeKeyword */:
- case 125 /* ModuleKeyword */:
- case 126 /* NamespaceKeyword */:
- case 122 /* DeclareKeyword */:
- case 74 /* ConstKeyword */:
- case 81 /* EnumKeyword */:
- case 82 /* ExportKeyword */:
- case 89 /* ImportKeyword */:
- case 110 /* PrivateKeyword */:
- case 111 /* ProtectedKeyword */:
- case 112 /* PublicKeyword */:
- case 115 /* AbstractKeyword */:
- case 113 /* StaticKeyword */:
- if (isStartOfDeclaration()) {
- return parseDeclaration();
- }
- break;
- }
- return parseExpressionOrLabeledStatement();
+ function nextTokenIsOpenParen() {
+ return nextToken() === 17 /* OpenParenToken */;
}
- function parseDeclaration() {
- var fullStart = getNodePos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- switch (token) {
- case 102 /* VarKeyword */:
- case 108 /* LetKeyword */:
- case 74 /* ConstKeyword */:
- return parseVariableStatement(fullStart, decorators, modifiers);
- case 87 /* FunctionKeyword */:
- return parseFunctionDeclaration(fullStart, decorators, modifiers);
- case 73 /* ClassKeyword */:
- return parseClassDeclaration(fullStart, decorators, modifiers);
- case 107 /* InterfaceKeyword */:
- return parseInterfaceDeclaration(fullStart, decorators, modifiers);
- case 132 /* TypeKeyword */:
- return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
- case 81 /* EnumKeyword */:
- return parseEnumDeclaration(fullStart, decorators, modifiers);
- case 125 /* ModuleKeyword */:
- case 126 /* NamespaceKeyword */:
- return parseModuleDeclaration(fullStart, decorators, modifiers);
- case 89 /* ImportKeyword */:
- return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
- case 82 /* ExportKeyword */:
- nextToken();
- return token === 77 /* DefaultKeyword */ || token === 56 /* EqualsToken */ ?
- parseExportAssignment(fullStart, decorators, modifiers) :
- parseExportDeclaration(fullStart, decorators, modifiers);
- default:
- if (decorators || modifiers) {
- // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
- // would follow. For recovery and error reporting purposes, return an incomplete declaration.
- var node = createMissingNode(231 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
- node.pos = fullStart;
- node.decorators = decorators;
- setModifiers(node, modifiers);
- return finishNode(node);
- }
- }
+ function nextTokenIsSlash() {
+ return nextToken() === 39 /* SlashToken */;
}
- function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
+ function nextTokenIsCommaOrFromKeyword() {
nextToken();
- return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === 9 /* StringLiteral */);
+ return token === 24 /* CommaToken */ ||
+ token === 133 /* FromKeyword */;
}
- function parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage) {
- if (token !== 15 /* OpenBraceToken */ && canParseSemicolon()) {
- parseSemicolon();
- return;
+ function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
+ parseExpected(89 /* ImportKeyword */);
+ var afterImportPos = scanner.getStartPos();
+ var identifier;
+ if (isIdentifier()) {
+ identifier = parseIdentifier();
+ if (token !== 24 /* CommaToken */ && token !== 133 /* FromKeyword */) {
+ // ImportEquals declaration of type:
+ // import x = require("mod"); or
+ // import x = M.x;
+ var importEqualsDeclaration = createNode(221 /* ImportEqualsDeclaration */, fullStart);
+ importEqualsDeclaration.decorators = decorators;
+ setModifiers(importEqualsDeclaration, modifiers);
+ importEqualsDeclaration.name = identifier;
+ parseExpected(56 /* EqualsToken */);
+ importEqualsDeclaration.moduleReference = parseModuleReference();
+ parseSemicolon();
+ return finishNode(importEqualsDeclaration);
+ }
}
- return parseFunctionBlock(isGenerator, isAsync, /*ignoreMissingOpenBrace*/ false, diagnosticMessage);
- }
- // DECLARATIONS
- function parseArrayBindingElement() {
- if (token === 24 /* CommaToken */) {
- return createNode(187 /* OmittedExpression */);
+ // Import statement
+ var importDeclaration = createNode(222 /* ImportDeclaration */, fullStart);
+ importDeclaration.decorators = decorators;
+ setModifiers(importDeclaration, modifiers);
+ // ImportDeclaration:
+ // import ImportClause from ModuleSpecifier ;
+ // import ModuleSpecifier;
+ if (identifier ||
+ token === 37 /* AsteriskToken */ ||
+ token === 15 /* OpenBraceToken */) {
+ importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
+ parseExpected(133 /* FromKeyword */);
}
- var node = createNode(163 /* BindingElement */);
- node.dotDotDotToken = parseOptionalToken(22 /* DotDotDotToken */);
- node.name = parseIdentifierOrPattern();
- node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
- return finishNode(node);
+ importDeclaration.moduleSpecifier = parseModuleSpecifier();
+ parseSemicolon();
+ return finishNode(importDeclaration);
}
- function parseObjectBindingElement() {
- var node = createNode(163 /* BindingElement */);
- // TODO(andersh): Handle computed properties
- var tokenIsIdentifier = isIdentifier();
- var propertyName = parsePropertyName();
- if (tokenIsIdentifier && token !== 54 /* ColonToken */) {
- node.name = propertyName;
+ function parseImportClause(identifier, fullStart) {
+ // ImportClause:
+ // ImportedDefaultBinding
+ // NameSpaceImport
+ // NamedImports
+ // ImportedDefaultBinding, NameSpaceImport
+ // ImportedDefaultBinding, NamedImports
+ var importClause = createNode(223 /* ImportClause */, fullStart);
+ if (identifier) {
+ // ImportedDefaultBinding:
+ // ImportedBinding
+ importClause.name = identifier;
}
- else {
- parseExpected(54 /* ColonToken */);
- node.propertyName = propertyName;
- node.name = parseIdentifierOrPattern();
+ // If there was no default import or if there is comma token after default import
+ // parse namespace or named imports
+ if (!importClause.name ||
+ parseOptional(24 /* CommaToken */)) {
+ importClause.namedBindings = token === 37 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(225 /* NamedImports */);
}
- node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
- return finishNode(node);
- }
- function parseObjectBindingPattern() {
- var node = createNode(161 /* ObjectBindingPattern */);
- parseExpected(15 /* OpenBraceToken */);
- node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
- parseExpected(16 /* CloseBraceToken */);
- return finishNode(node);
+ return finishNode(importClause);
}
- function parseArrayBindingPattern() {
- var node = createNode(162 /* ArrayBindingPattern */);
- parseExpected(19 /* OpenBracketToken */);
- node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
- parseExpected(20 /* CloseBracketToken */);
- return finishNode(node);
+ function parseModuleReference() {
+ return isExternalModuleReference()
+ ? parseExternalModuleReference()
+ : parseEntityName(/*allowReservedWords*/ false);
}
- function isIdentifierOrPattern() {
- return token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */ || isIdentifier();
+ function parseExternalModuleReference() {
+ var node = createNode(232 /* ExternalModuleReference */);
+ parseExpected(127 /* RequireKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = parseModuleSpecifier();
+ parseExpected(18 /* CloseParenToken */);
+ return finishNode(node);
}
- function parseIdentifierOrPattern() {
- if (token === 19 /* OpenBracketToken */) {
- return parseArrayBindingPattern();
- }
- if (token === 15 /* OpenBraceToken */) {
- return parseObjectBindingPattern();
+ function parseModuleSpecifier() {
+ // We allow arbitrary expressions here, even though the grammar only allows string
+ // literals. We check to ensure that it is only a string literal later in the grammar
+ // walker.
+ var result = parseExpression();
+ // Ensure the string being required is in our 'identifier' table. This will ensure
+ // that features like 'find refs' will look inside this file when search for its name.
+ if (result.kind === 9 /* StringLiteral */) {
+ internIdentifier(result.text);
}
- return parseIdentifier();
+ return result;
}
- function parseVariableDeclaration() {
- var node = createNode(211 /* VariableDeclaration */);
- node.name = parseIdentifierOrPattern();
- node.type = parseTypeAnnotation();
- if (!isInOrOfKeyword(token)) {
- node.initializer = parseInitializer(/*inParameter*/ false);
- }
+ function parseNamespaceImport() {
+ // NameSpaceImport:
+ // * as ImportedBinding
+ var namespaceImport = createNode(224 /* NamespaceImport */);
+ parseExpected(37 /* AsteriskToken */);
+ parseExpected(116 /* AsKeyword */);
+ namespaceImport.name = parseIdentifier();
+ return finishNode(namespaceImport);
+ }
+ function parseNamedImportsOrExports(kind) {
+ var node = createNode(kind);
+ // NamedImports:
+ // { }
+ // { ImportsList }
+ // { ImportsList, }
+ // ImportsList:
+ // ImportSpecifier
+ // ImportsList, ImportSpecifier
+ node.elements = parseBracketedList(21 /* ImportOrExportSpecifiers */, kind === 225 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 15 /* OpenBraceToken */, 16 /* CloseBraceToken */);
return finishNode(node);
}
- function parseVariableDeclarationList(inForStatementInitializer) {
- var node = createNode(212 /* VariableDeclarationList */);
- switch (token) {
- case 102 /* VarKeyword */:
- break;
- case 108 /* LetKeyword */:
- node.flags |= 8192 /* Let */;
- break;
- case 74 /* ConstKeyword */:
- node.flags |= 16384 /* Const */;
- break;
- default:
- ts.Debug.fail();
- }
- nextToken();
- // The user may have written the following:
- //
- // for (let of X) { }
- //
- // In this case, we want to parse an empty declaration list, and then parse 'of'
- // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
- // So we need to look ahead to determine if 'of' should be treated as a keyword in
- // this context.
- // The checker will then give an error that there is an empty declaration list.
- if (token === 134 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
- node.declarations = createMissingList();
+ function parseExportSpecifier() {
+ return parseImportOrExportSpecifier(230 /* ExportSpecifier */);
+ }
+ function parseImportSpecifier() {
+ return parseImportOrExportSpecifier(226 /* ImportSpecifier */);
+ }
+ function parseImportOrExportSpecifier(kind) {
+ var node = createNode(kind);
+ // ImportSpecifier:
+ // BindingIdentifier
+ // IdentifierName as BindingIdentifier
+ // ExportSpecififer:
+ // IdentifierName
+ // IdentifierName as IdentifierName
+ var checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
+ var checkIdentifierStart = scanner.getTokenPos();
+ var checkIdentifierEnd = scanner.getTextPos();
+ var identifierName = parseIdentifierName();
+ if (token === 116 /* AsKeyword */) {
+ node.propertyName = identifierName;
+ parseExpected(116 /* AsKeyword */);
+ checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
+ checkIdentifierStart = scanner.getTokenPos();
+ checkIdentifierEnd = scanner.getTextPos();
+ node.name = parseIdentifierName();
}
else {
- var savedDisallowIn = inDisallowInContext();
- setDisallowInContext(inForStatementInitializer);
- node.declarations = parseDelimitedList(8 /* VariableDeclarations */, parseVariableDeclaration);
- setDisallowInContext(savedDisallowIn);
+ node.name = identifierName;
+ }
+ if (kind === 226 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
+ // Report error identifier expected
+ parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected);
}
return finishNode(node);
}
- function canFollowContextualOfKeyword() {
- return nextTokenIsIdentifier() && nextToken() === 18 /* CloseParenToken */;
- }
- function parseVariableStatement(fullStart, decorators, modifiers) {
- var node = createNode(193 /* VariableStatement */, fullStart);
+ function parseExportDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(228 /* ExportDeclaration */, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
- node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
+ if (parseOptional(37 /* AsteriskToken */)) {
+ parseExpected(133 /* FromKeyword */);
+ node.moduleSpecifier = parseModuleSpecifier();
+ }
+ else {
+ node.exportClause = parseNamedImportsOrExports(229 /* NamedExports */);
+ // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
+ // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
+ // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
+ if (token === 133 /* FromKeyword */ || (token === 9 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
+ parseExpected(133 /* FromKeyword */);
+ node.moduleSpecifier = parseModuleSpecifier();
+ }
+ }
parseSemicolon();
return finishNode(node);
}
- function parseFunctionDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(213 /* FunctionDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(87 /* FunctionKeyword */);
- node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
- node.name = node.flags & 512 /* Default */ ? parseOptionalIdentifier() : parseIdentifier();
- var isGenerator = !!node.asteriskToken;
- var isAsync = !!(node.flags & 256 /* Async */);
- fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
- node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, ts.Diagnostics.or_expected);
- return finishNode(node);
- }
- function parseConstructorDeclaration(pos, decorators, modifiers) {
- var node = createNode(144 /* Constructor */, pos);
+ function parseExportAssignment(fullStart, decorators, modifiers) {
+ var node = createNode(227 /* ExportAssignment */, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
- parseExpected(121 /* ConstructorKeyword */);
- fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
- node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false, ts.Diagnostics.or_expected);
- return finishNode(node);
- }
- function parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, diagnosticMessage) {
- var method = createNode(143 /* MethodDeclaration */, fullStart);
- method.decorators = decorators;
- setModifiers(method, modifiers);
- method.asteriskToken = asteriskToken;
- method.name = name;
- method.questionToken = questionToken;
- var isGenerator = !!asteriskToken;
- var isAsync = !!(method.flags & 256 /* Async */);
- fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, method);
- method.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage);
- return finishNode(method);
- }
- function parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken) {
- var property = createNode(141 /* PropertyDeclaration */, fullStart);
- property.decorators = decorators;
- setModifiers(property, modifiers);
- property.name = name;
- property.questionToken = questionToken;
- property.type = parseTypeAnnotation();
- // For instance properties specifically, since they are evaluated inside the constructor,
- // we do *not * want to parse yield expressions, so we specifically turn the yield context
- // off. The grammar would look something like this:
- //
- // MemberVariableDeclaration[Yield]:
- // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initialiser_opt[In];
- // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initialiser_opt[In, ?Yield];
- //
- // The checker may still error in the static case to explicitly disallow the yield expression.
- property.initializer = modifiers && modifiers.flags & 64 /* Static */
- ? allowInAnd(parseNonParameterInitializer)
- : doOutsideOfContext(2 /* Yield */ | 1 /* DisallowIn */, parseNonParameterInitializer);
- parseSemicolon();
- return finishNode(property);
- }
- function parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers) {
- var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
- var name = parsePropertyName();
- // Note: this is not legal as per the grammar. But we allow it in the parser and
- // report an error in the grammar checker.
- var questionToken = parseOptionalToken(53 /* QuestionToken */);
- if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
- return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, ts.Diagnostics.or_expected);
+ if (parseOptional(56 /* EqualsToken */)) {
+ node.isExportEquals = true;
}
else {
- return parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken);
+ parseExpected(77 /* DefaultKeyword */);
}
- }
- function parseNonParameterInitializer() {
- return parseInitializer(/*inParameter*/ false);
- }
- function parseAccessorDeclaration(kind, fullStart, decorators, modifiers) {
- var node = createNode(kind, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.name = parsePropertyName();
- fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
- node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false);
+ node.expression = parseAssignmentExpressionOrHigher();
+ parseSemicolon();
return finishNode(node);
}
- function isClassMemberModifier(idToken) {
- switch (idToken) {
- case 112 /* PublicKeyword */:
- case 110 /* PrivateKeyword */:
- case 111 /* ProtectedKeyword */:
- case 113 /* StaticKeyword */:
- return true;
- default:
- return false;
+ function processReferenceComments(sourceFile) {
+ var triviaScanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, 0 /* Standard */, sourceText);
+ var referencedFiles = [];
+ var amdDependencies = [];
+ var amdModuleName;
+ // Keep scanning all the leading trivia in the file until we get to something that
+ // isn't trivia. Any single line comment will be analyzed to see if it is a
+ // reference comment.
+ while (true) {
+ var kind = triviaScanner.scan();
+ if (kind === 5 /* WhitespaceTrivia */ || kind === 4 /* NewLineTrivia */ || kind === 3 /* MultiLineCommentTrivia */) {
+ continue;
+ }
+ if (kind !== 2 /* SingleLineCommentTrivia */) {
+ break;
+ }
+ var range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
+ var comment = sourceText.substring(range.pos, range.end);
+ var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range);
+ if (referencePathMatchResult) {
+ var fileReference = referencePathMatchResult.fileReference;
+ sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
+ var diagnosticMessage = referencePathMatchResult.diagnosticMessage;
+ if (fileReference) {
+ referencedFiles.push(fileReference);
+ }
+ if (diagnosticMessage) {
+ parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage));
+ }
+ }
+ else {
+ var amdModuleNameRegEx = /^\/\/\/\s*".length;
+ return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
}
+ }
+ function parseQualifiedName(left) {
+ var result = createNode(135 /* QualifiedName */, left.pos);
+ result.left = left;
+ result.right = parseIdentifierName();
+ return finishNode(result);
+ }
+ function parseJSDocRecordType() {
+ var result = createNode(257 /* JSDocRecordType */);
nextToken();
+ result.members = parseDelimitedList(24 /* JSDocRecordMembers */, parseJSDocRecordMember);
+ checkForTrailingComma(result.members);
+ parseExpected(16 /* CloseBraceToken */);
+ return finishNode(result);
}
- if (token === 37 /* AsteriskToken */) {
- return true;
+ function parseJSDocRecordMember() {
+ var result = createNode(258 /* JSDocRecordMember */);
+ result.name = parseSimplePropertyName();
+ if (token === 54 /* ColonToken */) {
+ nextToken();
+ result.type = parseJSDocType();
+ }
+ return finishNode(result);
}
- // Try to get the first property-like token following all modifiers.
- // This can either be an identifier or the 'get' or 'set' keywords.
- if (isLiteralPropertyName()) {
- idToken = token;
+ function parseJSDocNonNullableType() {
+ var result = createNode(256 /* JSDocNonNullableType */);
nextToken();
+ result.type = parseJSDocType();
+ return finishNode(result);
}
- // Index signatures and computed properties are class members; we can parse.
- if (token === 19 /* OpenBracketToken */) {
- return true;
+ function parseJSDocTupleType() {
+ var result = createNode(254 /* JSDocTupleType */);
+ nextToken();
+ result.types = parseDelimitedList(25 /* JSDocTupleTypes */, parseJSDocType);
+ checkForTrailingComma(result.types);
+ parseExpected(20 /* CloseBracketToken */);
+ return finishNode(result);
}
- // If we were able to get any potential identifier...
- if (idToken !== undefined) {
- // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
- if (!ts.isKeyword(idToken) || idToken === 129 /* SetKeyword */ || idToken === 123 /* GetKeyword */) {
- return true;
- }
- // If it *is* a keyword, but not an accessor, check a little farther along
- // to see if it should actually be parsed as a class member.
- switch (token) {
- case 17 /* OpenParenToken */: // Method declaration
- case 25 /* LessThanToken */: // Generic Method declaration
- case 54 /* ColonToken */: // Type Annotation for declaration
- case 56 /* EqualsToken */: // Initializer for declaration
- case 53 /* QuestionToken */:
- return true;
- default:
- // Covers
- // - Semicolons (declaration termination)
- // - Closing braces (end-of-class, must be declaration)
- // - End-of-files (not valid, but permitted so that it gets caught later on)
- // - Line-breaks (enabling *automatic semicolon insertion*)
- return canParseSemicolon();
+ function checkForTrailingComma(list) {
+ if (parseDiagnostics.length === 0 && list.hasTrailingComma) {
+ var start = list.end - ",".length;
+ parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed);
}
}
- return false;
- }
- function parseDecorators() {
- var decorators;
- while (true) {
- var decoratorStart = getNodePos();
- if (!parseOptional(55 /* AtToken */)) {
- break;
- }
- if (!decorators) {
- decorators = [];
- decorators.pos = scanner.getStartPos();
+ function parseJSDocUnionType() {
+ var result = createNode(253 /* JSDocUnionType */);
+ nextToken();
+ result.types = parseJSDocTypeList(parseJSDocType());
+ parseExpected(18 /* CloseParenToken */);
+ return finishNode(result);
+ }
+ function parseJSDocTypeList(firstType) {
+ ts.Debug.assert(!!firstType);
+ var types = [];
+ types.pos = firstType.pos;
+ types.push(firstType);
+ while (parseOptional(47 /* BarToken */)) {
+ types.push(parseJSDocType());
}
- var decorator = createNode(139 /* Decorator */, decoratorStart);
- decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
- decorators.push(finishNode(decorator));
+ types.end = scanner.getStartPos();
+ return types;
}
- if (decorators) {
- decorators.end = getNodeEnd();
+ function parseJSDocAllType() {
+ var result = createNode(250 /* JSDocAllType */);
+ nextToken();
+ return finishNode(result);
}
- return decorators;
- }
- function parseModifiers() {
- var flags = 0;
- var modifiers;
- while (true) {
- var modifierStart = scanner.getStartPos();
- var modifierKind = token;
- if (!parseAnyContextualModifier()) {
- break;
+ function parseJSDocUnknownOrNullableType() {
+ var pos = scanner.getStartPos();
+ // skip the ?
+ nextToken();
+ // Need to lookahead to decide if this is a nullable or unknown type.
+ // Here are cases where we'll pick the unknown type:
+ //
+ // Foo(?,
+ // { a: ? }
+ // Foo(?)
+ // Foo>
+ // Foo(?=
+ // (?|
+ if (token === 24 /* CommaToken */ ||
+ token === 16 /* CloseBraceToken */ ||
+ token === 18 /* CloseParenToken */ ||
+ token === 27 /* GreaterThanToken */ ||
+ token === 56 /* EqualsToken */ ||
+ token === 47 /* BarToken */) {
+ var result = createNode(251 /* JSDocUnknownType */, pos);
+ return finishNode(result);
}
- if (!modifiers) {
- modifiers = [];
- modifiers.pos = modifierStart;
+ else {
+ var result = createNode(255 /* JSDocNullableType */, pos);
+ result.type = parseJSDocType();
+ return finishNode(result);
}
- flags |= ts.modifierToFlag(modifierKind);
- modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
}
- if (modifiers) {
- modifiers.flags = flags;
- modifiers.end = scanner.getStartPos();
+ function parseIsolatedJSDocComment(content, start, length) {
+ initializeState("file.js", content, 2 /* Latest */, /*isJavaScriptFile*/ true, /*_syntaxCursor:*/ undefined);
+ var jsDocComment = parseJSDocComment(/*parent:*/ undefined, start, length);
+ var diagnostics = parseDiagnostics;
+ clearState();
+ return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined;
}
- return modifiers;
- }
- function parseModifiersForArrowFunction() {
- var flags = 0;
- var modifiers;
- if (token === 118 /* AsyncKeyword */) {
- var modifierStart = scanner.getStartPos();
- var modifierKind = token;
- nextToken();
- modifiers = [];
- modifiers.pos = modifierStart;
- flags |= ts.modifierToFlag(modifierKind);
- modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
- modifiers.flags = flags;
- modifiers.end = scanner.getStartPos();
+ JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
+ function parseJSDocComment(parent, start, length) {
+ var comment = parseJSDocCommentWorker(start, length);
+ if (comment) {
+ fixupParentReferences(comment);
+ comment.parent = parent;
+ }
+ return comment;
}
- return modifiers;
- }
- function parseClassElement() {
- if (token === 23 /* SemicolonToken */) {
- var result = createNode(191 /* SemicolonClassElement */);
- nextToken();
- return finishNode(result);
+ JSDocParser.parseJSDocComment = parseJSDocComment;
+ function parseJSDocCommentWorker(start, length) {
+ var content = sourceText;
+ start = start || 0;
+ var end = length === undefined ? content.length : start + length;
+ length = end - start;
+ ts.Debug.assert(start >= 0);
+ ts.Debug.assert(start <= end);
+ ts.Debug.assert(end <= content.length);
+ var tags;
+ var pos;
+ // NOTE(cyrusn): This is essentially a handwritten scanner for JSDocComments. I
+ // considered using an actual Scanner, but this would complicate things. The
+ // scanner would need to know it was in a Doc Comment. Otherwise, it would then
+ // produce comments *inside* the doc comment. In the end it was just easier to
+ // write a simple scanner rather than go that route.
+ if (length >= "/** */".length) {
+ if (content.charCodeAt(start) === 47 /* slash */ &&
+ content.charCodeAt(start + 1) === 42 /* asterisk */ &&
+ content.charCodeAt(start + 2) === 42 /* asterisk */ &&
+ content.charCodeAt(start + 3) !== 42 /* asterisk */) {
+ // Initially we can parse out a tag. We also have seen a starting asterisk.
+ // This is so that /** * @type */ doesn't parse.
+ var canParseTag = true;
+ var seenAsterisk = true;
+ for (pos = start + "/**".length; pos < end;) {
+ var ch = content.charCodeAt(pos);
+ pos++;
+ if (ch === 64 /* at */ && canParseTag) {
+ parseTag();
+ // Once we parse out a tag, we cannot keep parsing out tags on this line.
+ canParseTag = false;
+ continue;
+ }
+ if (ts.isLineBreak(ch)) {
+ // After a line break, we can parse a tag, and we haven't seen as asterisk
+ // on the next line yet.
+ canParseTag = true;
+ seenAsterisk = false;
+ continue;
+ }
+ if (ts.isWhiteSpace(ch)) {
+ // Whitespace doesn't affect any of our parsing.
+ continue;
+ }
+ // Ignore the first asterisk on a line.
+ if (ch === 42 /* asterisk */) {
+ if (seenAsterisk) {
+ // If we've already seen an asterisk, then we can no longer parse a tag
+ // on this line.
+ canParseTag = false;
+ }
+ seenAsterisk = true;
+ continue;
+ }
+ // Anything else is doc comment text. We can't do anything with it. Because it
+ // wasn't a tag, we can no longer parse a tag on this line until we hit the next
+ // line break.
+ canParseTag = false;
+ }
+ }
+ }
+ return createJSDocComment();
+ function createJSDocComment() {
+ if (!tags) {
+ return undefined;
+ }
+ var result = createNode(265 /* JSDocComment */, start);
+ result.tags = tags;
+ return finishNode(result, end);
+ }
+ function skipWhitespace() {
+ while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) {
+ pos++;
+ }
+ }
+ function parseTag() {
+ ts.Debug.assert(content.charCodeAt(pos - 1) === 64 /* at */);
+ var atToken = createNode(55 /* AtToken */, pos - 1);
+ atToken.end = pos;
+ var tagName = scanIdentifier();
+ if (!tagName) {
+ return;
+ }
+ var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName);
+ addTag(tag);
+ }
+ function handleTag(atToken, tagName) {
+ if (tagName) {
+ switch (tagName.text) {
+ case "param":
+ return handleParamTag(atToken, tagName);
+ case "return":
+ case "returns":
+ return handleReturnTag(atToken, tagName);
+ case "template":
+ return handleTemplateTag(atToken, tagName);
+ case "type":
+ return handleTypeTag(atToken, tagName);
+ }
+ }
+ return undefined;
+ }
+ function handleUnknownTag(atToken, tagName) {
+ var result = createNode(266 /* JSDocTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ return finishNode(result, pos);
+ }
+ function addTag(tag) {
+ if (tag) {
+ if (!tags) {
+ tags = [];
+ tags.pos = tag.pos;
+ }
+ tags.push(tag);
+ tags.end = tag.end;
+ }
+ }
+ function tryParseTypeExpression() {
+ skipWhitespace();
+ if (content.charCodeAt(pos) !== 123 /* openBrace */) {
+ return undefined;
+ }
+ var typeExpression = parseJSDocTypeExpression(pos, end - pos);
+ pos = typeExpression.end;
+ return typeExpression;
+ }
+ function handleParamTag(atToken, tagName) {
+ var typeExpression = tryParseTypeExpression();
+ skipWhitespace();
+ var name;
+ var isBracketed;
+ if (content.charCodeAt(pos) === 91 /* openBracket */) {
+ pos++;
+ skipWhitespace();
+ name = scanIdentifier();
+ isBracketed = true;
+ }
+ else {
+ name = scanIdentifier();
+ }
+ if (!name) {
+ parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected);
+ }
+ var preName, postName;
+ if (typeExpression) {
+ postName = name;
+ }
+ else {
+ preName = name;
+ }
+ if (!typeExpression) {
+ typeExpression = tryParseTypeExpression();
+ }
+ var result = createNode(267 /* JSDocParameterTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.preParameterName = preName;
+ result.typeExpression = typeExpression;
+ result.postParameterName = postName;
+ result.isBracketed = isBracketed;
+ return finishNode(result, pos);
+ }
+ function handleReturnTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 268 /* JSDocReturnTag */; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var result = createNode(268 /* JSDocReturnTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeExpression = tryParseTypeExpression();
+ return finishNode(result, pos);
+ }
+ function handleTypeTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 269 /* JSDocTypeTag */; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var result = createNode(269 /* JSDocTypeTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeExpression = tryParseTypeExpression();
+ return finishNode(result, pos);
+ }
+ function handleTemplateTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 270 /* JSDocTemplateTag */; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var typeParameters = [];
+ typeParameters.pos = pos;
+ while (true) {
+ skipWhitespace();
+ var startPos = pos;
+ var name_8 = scanIdentifier();
+ if (!name_8) {
+ parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected);
+ return undefined;
+ }
+ var typeParameter = createNode(137 /* TypeParameter */, name_8.pos);
+ typeParameter.name = name_8;
+ finishNode(typeParameter, pos);
+ typeParameters.push(typeParameter);
+ skipWhitespace();
+ if (content.charCodeAt(pos) !== 44 /* comma */) {
+ break;
+ }
+ pos++;
+ }
+ typeParameters.end = pos;
+ var result = createNode(270 /* JSDocTemplateTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeParameters = typeParameters;
+ return finishNode(result, pos);
+ }
+ function scanIdentifier() {
+ var startPos = pos;
+ for (; pos < end; pos++) {
+ var ch = content.charCodeAt(pos);
+ if (pos === startPos && ts.isIdentifierStart(ch, 2 /* Latest */)) {
+ continue;
+ }
+ else if (pos > startPos && ts.isIdentifierPart(ch, 2 /* Latest */)) {
+ continue;
+ }
+ break;
+ }
+ if (startPos === pos) {
+ return undefined;
+ }
+ var result = createNode(69 /* Identifier */, startPos);
+ result.text = content.substring(startPos, pos);
+ return finishNode(result, pos);
+ }
}
- var fullStart = getNodePos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
- if (accessor) {
- return accessor;
+ JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
+ })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
+ })(Parser || (Parser = {}));
+ var IncrementalParser;
+ (function (IncrementalParser) {
+ function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
+ aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
+ checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
+ if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
+ // if the text didn't change, then we can just return our current source file as-is.
+ return sourceFile;
}
- if (token === 121 /* ConstructorKeyword */) {
- return parseConstructorDeclaration(fullStart, decorators, modifiers);
+ if (sourceFile.statements.length === 0) {
+ // If we don't have any statements in the current source file, then there's no real
+ // way to incrementally parse. So just do a full parse instead.
+ return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setNodeParents*/ true);
+ }
+ // Make sure we're not trying to incrementally update a source file more than once. Once
+ // we do an update the original source file is considered unusbale from that point onwards.
+ //
+ // This is because we do incremental parsing in-place. i.e. we take nodes from the old
+ // tree and give them new positions and parents. From that point on, trusting the old
+ // tree at all is not possible as far too much of it may violate invariants.
+ var incrementalSourceFile = sourceFile;
+ ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
+ incrementalSourceFile.hasBeenIncrementallyParsed = true;
+ var oldText = sourceFile.text;
+ var syntaxCursor = createSyntaxCursor(sourceFile);
+ // Make the actual change larger so that we know to reparse anything whose lookahead
+ // might have intersected the change.
+ var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
+ checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
+ // Ensure that extending the affected range only moved the start of the change range
+ // earlier in the file.
+ ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
+ ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
+ ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
+ // The is the amount the nodes after the edit range need to be adjusted. It can be
+ // positive (if the edit added characters), negative (if the edit deleted characters)
+ // or zero (if this was a pure overwrite with nothing added/removed).
+ var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
+ // If we added or removed characters during the edit, then we need to go and adjust all
+ // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they
+ // may move backward (if we deleted chars).
+ //
+ // Doing this helps us out in two ways. First, it means that any nodes/tokens we want
+ // to reuse are already at the appropriate position in the new text. That way when we
+ // reuse them, we don't have to figure out if they need to be adjusted. Second, it makes
+ // it very easy to determine if we can reuse a node. If the node's position is at where
+ // we are in the text, then we can reuse it. Otherwise we can't. If the node's position
+ // is ahead of us, then we'll need to rescan tokens. If the node's position is behind
+ // us, then we'll need to skip it or crumble it as appropriate
+ //
+ // We will also adjust the positions of nodes that intersect the change range as well.
+ // By doing this, we ensure that all the positions in the old tree are consistent, not
+ // just the positions of nodes entirely before/after the change range. By being
+ // consistent, we can then easily map from positions to nodes in the old tree easily.
+ //
+ // Also, mark any syntax elements that intersect the changed span. We know, up front,
+ // that we cannot reuse these elements.
+ updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
+ // Now that we've set up our internal incremental state just proceed and parse the
+ // source file in the normal fashion. When possible the parser will retrieve and
+ // reuse nodes from the old tree.
+ //
+ // Note: passing in 'true' for setNodeParents is very important. When incrementally
+ // parsing, we will be reusing nodes from the old tree, and placing it into new
+ // parents. If we don't set the parents now, we'll end up with an observably
+ // inconsistent tree. Setting the parents on the new tree should be very fast. We
+ // will immediately bail out of walking any subtrees when we can see that their parents
+ // are already correct.
+ var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /* setParentNode */ true);
+ return result;
+ }
+ IncrementalParser.updateSourceFile = updateSourceFile;
+ function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
+ if (isArray) {
+ visitArray(element);
}
- if (isIndexSignature()) {
- return parseIndexSignatureDeclaration(fullStart, decorators, modifiers);
+ else {
+ visitNode(element);
}
- // It is very important that we check this *after* checking indexers because
- // the [ token can start an index signature or a computed property name
- if (ts.tokenIsIdentifierOrKeyword(token) ||
- token === 9 /* StringLiteral */ ||
- token === 8 /* NumericLiteral */ ||
- token === 37 /* AsteriskToken */ ||
- token === 19 /* OpenBracketToken */) {
- return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
+ return;
+ function visitNode(node) {
+ var text = "";
+ if (aggressiveChecks && shouldCheckNode(node)) {
+ text = oldText.substring(node.pos, node.end);
+ }
+ // Ditch any existing LS children we may have created. This way we can avoid
+ // moving them forward.
+ if (node._children) {
+ node._children = undefined;
+ }
+ if (node.jsDocComment) {
+ node.jsDocComment = undefined;
+ }
+ node.pos += delta;
+ node.end += delta;
+ if (aggressiveChecks && shouldCheckNode(node)) {
+ ts.Debug.assert(text === newText.substring(node.pos, node.end));
+ }
+ forEachChild(node, visitNode, visitArray);
+ checkNodePositions(node, aggressiveChecks);
}
- if (decorators || modifiers) {
- // treat this as a property declaration with a missing name.
- var name_7 = createMissingNode(69 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
- return parsePropertyDeclaration(fullStart, decorators, modifiers, name_7, /*questionToken*/ undefined);
+ function visitArray(array) {
+ array._children = undefined;
+ array.pos += delta;
+ array.end += delta;
+ for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
+ var node = array_7[_i];
+ visitNode(node);
+ }
}
- // 'isClassMemberStart' should have hinted not to attempt parsing.
- ts.Debug.fail("Should not have attempted to parse class member declaration.");
- }
- function parseClassExpression() {
- return parseClassDeclarationOrExpression(
- /*fullStart*/ scanner.getStartPos(),
- /*decorators*/ undefined,
- /*modifiers*/ undefined, 186 /* ClassExpression */);
}
- function parseClassDeclaration(fullStart, decorators, modifiers) {
- return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 214 /* ClassDeclaration */);
+ function shouldCheckNode(node) {
+ switch (node.kind) {
+ case 9 /* StringLiteral */:
+ case 8 /* NumericLiteral */:
+ case 69 /* Identifier */:
+ return true;
+ }
+ return false;
}
- function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
- var node = createNode(kind, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(73 /* ClassKeyword */);
- node.name = parseNameOfClassDeclarationOrExpression();
- node.typeParameters = parseTypeParameters();
- node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
- if (parseExpected(15 /* OpenBraceToken */)) {
- // ClassTail[Yield,Await] : (Modified) See 14.5
- // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
- node.members = parseClassMembers();
- parseExpected(16 /* CloseBraceToken */);
+ function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
+ ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
+ ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
+ ts.Debug.assert(element.pos <= element.end);
+ // We have an element that intersects the change range in some way. It may have its
+ // start, or its end (or both) in the changed range. We want to adjust any part
+ // that intersects such that the final tree is in a consistent state. i.e. all
+ // chlidren have spans within the span of their parent, and all siblings are ordered
+ // properly.
+ // We may need to update both the 'pos' and the 'end' of the element.
+ // If the 'pos' is before the start of the change, then we don't need to touch it.
+ // If it isn't, then the 'pos' must be inside the change. How we update it will
+ // depend if delta is positive or negative. If delta is positive then we have
+ // something like:
+ //
+ // -------------------AAA-----------------
+ // -------------------BBBCCCCCCC-----------------
+ //
+ // In this case, we consider any node that started in the change range to still be
+ // starting at the same position.
+ //
+ // however, if the delta is negative, then we instead have something like this:
+ //
+ // -------------------XXXYYYYYYY-----------------
+ // -------------------ZZZ-----------------
+ //
+ // In this case, any element that started in the 'X' range will keep its position.
+ // However any element htat started after that will have their pos adjusted to be
+ // at the end of the new range. i.e. any node that started in the 'Y' range will
+ // be adjusted to have their start at the end of the 'Z' range.
+ //
+ // The element will keep its position if possible. Or Move backward to the new-end
+ // if it's in the 'Y' range.
+ element.pos = Math.min(element.pos, changeRangeNewEnd);
+ // If the 'end' is after the change range, then we always adjust it by the delta
+ // amount. However, if the end is in the change range, then how we adjust it
+ // will depend on if delta is positive or negative. If delta is positive then we
+ // have something like:
+ //
+ // -------------------AAA-----------------
+ // -------------------BBBCCCCCCC-----------------
+ //
+ // In this case, we consider any node that ended inside the change range to keep its
+ // end position.
+ //
+ // however, if the delta is negative, then we instead have something like this:
+ //
+ // -------------------XXXYYYYYYY-----------------
+ // -------------------ZZZ-----------------
+ //
+ // In this case, any element that ended in the 'X' range will keep its position.
+ // However any element htat ended after that will have their pos adjusted to be
+ // at the end of the new range. i.e. any node that ended in the 'Y' range will
+ // be adjusted to have their end at the end of the 'Z' range.
+ if (element.end >= changeRangeOldEnd) {
+ // Element ends after the change range. Always adjust the end pos.
+ element.end += delta;
}
else {
- node.members = createMissingList();
+ // Element ends in the change range. The element will keep its position if
+ // possible. Or Move backward to the new-end if it's in the 'Y' range.
+ element.end = Math.min(element.end, changeRangeNewEnd);
}
- return finishNode(node);
- }
- function parseNameOfClassDeclarationOrExpression() {
- // implements is a future reserved word so
- // 'class implements' might mean either
- // - class expression with omitted name, 'implements' starts heritage clause
- // - class with name 'implements'
- // 'isImplementsClause' helps to disambiguate between these two cases
- return isIdentifier() && !isImplementsClause()
- ? parseIdentifier()
- : undefined;
- }
- function isImplementsClause() {
- return token === 106 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
- }
- function parseHeritageClauses(isClassHeritageClause) {
- // ClassTail[Yield,Await] : (Modified) See 14.5
- // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
- if (isHeritageClause()) {
- return parseList(20 /* HeritageClauses */, parseHeritageClause);
+ ts.Debug.assert(element.pos <= element.end);
+ if (element.parent) {
+ ts.Debug.assert(element.pos >= element.parent.pos);
+ ts.Debug.assert(element.end <= element.parent.end);
}
- return undefined;
- }
- function parseHeritageClausesWorker() {
- return parseList(20 /* HeritageClauses */, parseHeritageClause);
}
- function parseHeritageClause() {
- if (token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */) {
- var node = createNode(243 /* HeritageClause */);
- node.token = token;
- nextToken();
- node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
- return finishNode(node);
+ function checkNodePositions(node, aggressiveChecks) {
+ if (aggressiveChecks) {
+ var pos = node.pos;
+ forEachChild(node, function (child) {
+ ts.Debug.assert(child.pos >= pos);
+ pos = child.end;
+ });
+ ts.Debug.assert(pos <= node.end);
}
- return undefined;
}
- function parseExpressionWithTypeArguments() {
- var node = createNode(188 /* ExpressionWithTypeArguments */);
- node.expression = parseLeftHandSideExpressionOrHigher();
- if (token === 25 /* LessThanToken */) {
- node.typeArguments = parseBracketedList(18 /* TypeArguments */, parseType, 25 /* LessThanToken */, 27 /* GreaterThanToken */);
+ function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
+ visitNode(sourceFile);
+ return;
+ function visitNode(child) {
+ ts.Debug.assert(child.pos <= child.end);
+ if (child.pos > changeRangeOldEnd) {
+ // Node is entirely past the change range. We need to move both its pos and
+ // end, forward or backward appropriately.
+ moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
+ return;
+ }
+ // Check if the element intersects the change range. If it does, then it is not
+ // reusable. Also, we'll need to recurse to see what constituent portions we may
+ // be able to use.
+ var fullEnd = child.end;
+ if (fullEnd >= changeStart) {
+ child.intersectsChange = true;
+ child._children = undefined;
+ // Adjust the pos or end (or both) of the intersecting element accordingly.
+ adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
+ forEachChild(child, visitNode, visitArray);
+ checkNodePositions(child, aggressiveChecks);
+ return;
+ }
+ // Otherwise, the node is entirely before the change range. No need to do anything with it.
+ ts.Debug.assert(fullEnd < changeStart);
+ }
+ function visitArray(array) {
+ ts.Debug.assert(array.pos <= array.end);
+ if (array.pos > changeRangeOldEnd) {
+ // Array is entirely after the change range. We need to move it, and move any of
+ // its children.
+ moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
+ return;
+ }
+ // Check if the element intersects the change range. If it does, then it is not
+ // reusable. Also, we'll need to recurse to see what constituent portions we may
+ // be able to use.
+ var fullEnd = array.end;
+ if (fullEnd >= changeStart) {
+ array.intersectsChange = true;
+ array._children = undefined;
+ // Adjust the pos or end (or both) of the intersecting array accordingly.
+ adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
+ for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
+ var node = array_8[_i];
+ visitNode(node);
+ }
+ return;
+ }
+ // Otherwise, the array is entirely before the change range. No need to do anything with it.
+ ts.Debug.assert(fullEnd < changeStart);
}
- return finishNode(node);
- }
- function isHeritageClause() {
- return token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
- }
- function parseClassMembers() {
- return parseList(5 /* ClassMembers */, parseClassElement);
- }
- function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(215 /* InterfaceDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(107 /* InterfaceKeyword */);
- node.name = parseIdentifier();
- node.typeParameters = parseTypeParameters();
- node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false);
- node.members = parseObjectTypeMembers();
- return finishNode(node);
- }
- function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(216 /* TypeAliasDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(132 /* TypeKeyword */);
- node.name = parseIdentifier();
- node.typeParameters = parseTypeParameters();
- parseExpected(56 /* EqualsToken */);
- node.type = parseType();
- parseSemicolon();
- return finishNode(node);
}
- // In an ambient declaration, the grammar only allows integer literals as initializers.
- // In a non-ambient declaration, the grammar allows uninitialized members only in a
- // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
- // or any time an integer literal initializer is encountered.
- function parseEnumMember() {
- var node = createNode(247 /* EnumMember */, scanner.getStartPos());
- node.name = parsePropertyName();
- node.initializer = allowInAnd(parseNonParameterInitializer);
- return finishNode(node);
+ function extendToAffectedRange(sourceFile, changeRange) {
+ // Consider the following code:
+ // void foo() { /; }
+ //
+ // If the text changes with an insertion of / just before the semicolon then we end up with:
+ // void foo() { //; }
+ //
+ // If we were to just use the changeRange a is, then we would not rescan the { token
+ // (as it does not intersect the actual original change range). Because an edit may
+ // change the token touching it, we actually need to look back *at least* one token so
+ // that the prior token sees that change.
+ var maxLookahead = 1;
+ var start = changeRange.span.start;
+ // the first iteration aligns us with the change start. subsequent iteration move us to
+ // the left by maxLookahead tokens. We only need to do this as long as we're not at the
+ // start of the tree.
+ for (var i = 0; start > 0 && i <= maxLookahead; i++) {
+ var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
+ ts.Debug.assert(nearestNode.pos <= start);
+ var position = nearestNode.pos;
+ start = Math.max(0, position - 1);
+ }
+ var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
+ var finalLength = changeRange.newLength + (changeRange.span.start - start);
+ return ts.createTextChangeRange(finalSpan, finalLength);
}
- function parseEnumDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(217 /* EnumDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(81 /* EnumKeyword */);
- node.name = parseIdentifier();
- if (parseExpected(15 /* OpenBraceToken */)) {
- node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember);
- parseExpected(16 /* CloseBraceToken */);
+ function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
+ var bestResult = sourceFile;
+ var lastNodeEntirelyBeforePosition;
+ forEachChild(sourceFile, visit);
+ if (lastNodeEntirelyBeforePosition) {
+ var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition);
+ if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
+ bestResult = lastChildOfLastEntireNodeBeforePosition;
+ }
}
- else {
- node.members = createMissingList();
+ return bestResult;
+ function getLastChild(node) {
+ while (true) {
+ var lastChild = getLastChildWorker(node);
+ if (lastChild) {
+ node = lastChild;
+ }
+ else {
+ return node;
+ }
+ }
}
- return finishNode(node);
- }
- function parseModuleBlock() {
- var node = createNode(219 /* ModuleBlock */, scanner.getStartPos());
- if (parseExpected(15 /* OpenBraceToken */)) {
- node.statements = parseList(1 /* BlockStatements */, parseStatement);
- parseExpected(16 /* CloseBraceToken */);
+ function getLastChildWorker(node) {
+ var last = undefined;
+ forEachChild(node, function (child) {
+ if (ts.nodeIsPresent(child)) {
+ last = child;
+ }
+ });
+ return last;
}
- else {
- node.statements = createMissingList();
+ function visit(child) {
+ if (ts.nodeIsMissing(child)) {
+ // Missing nodes are effectively invisible to us. We never even consider them
+ // When trying to find the nearest node before us.
+ return;
+ }
+ // If the child intersects this position, then this node is currently the nearest
+ // node that starts before the position.
+ if (child.pos <= position) {
+ if (child.pos >= bestResult.pos) {
+ // This node starts before the position, and is closer to the position than
+ // the previous best node we found. It is now the new best node.
+ bestResult = child;
+ }
+ // Now, the node may overlap the position, or it may end entirely before the
+ // position. If it overlaps with the position, then either it, or one of its
+ // children must be the nearest node before the position. So we can just
+ // recurse into this child to see if we can find something better.
+ if (position < child.end) {
+ // The nearest node is either this child, or one of the children inside
+ // of it. We've already marked this child as the best so far. Recurse
+ // in case one of the children is better.
+ forEachChild(child, visit);
+ // Once we look at the children of this node, then there's no need to
+ // continue any further.
+ return true;
+ }
+ else {
+ ts.Debug.assert(child.end <= position);
+ // The child ends entirely before this position. Say you have the following
+ // (where $ is the position)
+ //
+ // ? $ : <...> <...>
+ //
+ // We would want to find the nearest preceding node in "complex expr 2".
+ // To support that, we keep track of this node, and once we're done searching
+ // for a best node, we recurse down this node to see if we can find a good
+ // result in it.
+ //
+ // This approach allows us to quickly skip over nodes that are entirely
+ // before the position, while still allowing us to find any nodes in the
+ // last one that might be what we want.
+ lastNodeEntirelyBeforePosition = child;
+ }
+ }
+ else {
+ ts.Debug.assert(child.pos > position);
+ // We're now at a node that is entirely past the position we're searching for.
+ // This node (and all following nodes) could never contribute to the result,
+ // so just skip them by returning 'true' here.
+ return true;
+ }
}
- return finishNode(node);
- }
- function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
- var node = createNode(218 /* ModuleDeclaration */, fullStart);
- // If we are parsing a dotted namespace name, we want to
- // propagate the 'Namespace' flag across the names if set.
- var namespaceFlag = flags & 65536 /* Namespace */;
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.flags |= flags;
- node.name = parseIdentifier();
- node.body = parseOptional(21 /* DotToken */)
- ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, 2 /* Export */ | namespaceFlag)
- : parseModuleBlock();
- return finishNode(node);
- }
- function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(218 /* ModuleDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.name = parseLiteralNode(/*internName*/ true);
- node.body = parseModuleBlock();
- return finishNode(node);
}
- function parseModuleDeclaration(fullStart, decorators, modifiers) {
- var flags = modifiers ? modifiers.flags : 0;
- if (parseOptional(126 /* NamespaceKeyword */)) {
- flags |= 65536 /* Namespace */;
+ function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
+ var oldText = sourceFile.text;
+ if (textChangeRange) {
+ ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
+ if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
+ var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
+ var newTextPrefix = newText.substr(0, textChangeRange.span.start);
+ ts.Debug.assert(oldTextPrefix === newTextPrefix);
+ var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
+ var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
+ ts.Debug.assert(oldTextSuffix === newTextSuffix);
+ }
}
- else {
- parseExpected(125 /* ModuleKeyword */);
- if (token === 9 /* StringLiteral */) {
- return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
+ }
+ function createSyntaxCursor(sourceFile) {
+ var currentArray = sourceFile.statements;
+ var currentArrayIndex = 0;
+ ts.Debug.assert(currentArrayIndex < currentArray.length);
+ var current = currentArray[currentArrayIndex];
+ var lastQueriedPosition = -1 /* Value */;
+ return {
+ currentNode: function (position) {
+ // Only compute the current node if the position is different than the last time
+ // we were asked. The parser commonly asks for the node at the same position
+ // twice. Once to know if can read an appropriate list element at a certain point,
+ // and then to actually read and consume the node.
+ if (position !== lastQueriedPosition) {
+ // Much of the time the parser will need the very next node in the array that
+ // we just returned a node from.So just simply check for that case and move
+ // forward in the array instead of searching for the node again.
+ if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
+ currentArrayIndex++;
+ current = currentArray[currentArrayIndex];
+ }
+ // If we don't have a node, or the node we have isn't in the right position,
+ // then try to find a viable node at the position requested.
+ if (!current || current.pos !== position) {
+ findHighestListElementThatStartsAtPosition(position);
+ }
+ }
+ // Cache this query so that we don't do any extra work if the parser calls back
+ // into us. Note: this is very common as the parser will make pairs of calls like
+ // 'isListElement -> parseListElement'. If we were unable to find a node when
+ // called with 'isListElement', we don't want to redo the work when parseListElement
+ // is called immediately after.
+ lastQueriedPosition = position;
+ // Either we don'd have a node, or we have a node at the position being asked for.
+ ts.Debug.assert(!current || current.pos === position);
+ return current;
+ }
+ };
+ // Finds the highest element in the tree we can find that starts at the provided position.
+ // The element must be a direct child of some node list in the tree. This way after we
+ // return it, we can easily return its next sibling in the list.
+ function findHighestListElementThatStartsAtPosition(position) {
+ // Clear out any cached state about the last node we found.
+ currentArray = undefined;
+ currentArrayIndex = -1 /* Value */;
+ current = undefined;
+ // Recurse into the source file to find the highest node at this position.
+ forEachChild(sourceFile, visitNode, visitArray);
+ return;
+ function visitNode(node) {
+ if (position >= node.pos && position < node.end) {
+ // Position was within this node. Keep searching deeper to find the node.
+ forEachChild(node, visitNode, visitArray);
+ // don't procede any futher in the search.
+ return true;
+ }
+ // position wasn't in this node, have to keep searching.
+ return false;
+ }
+ function visitArray(array) {
+ if (position >= array.pos && position < array.end) {
+ // position was in this array. Search through this array to see if we find a
+ // viable element.
+ for (var i = 0, n = array.length; i < n; i++) {
+ var child = array[i];
+ if (child) {
+ if (child.pos === position) {
+ // Found the right node. We're done.
+ currentArray = array;
+ currentArrayIndex = i;
+ current = child;
+ return true;
+ }
+ else {
+ if (child.pos < position && position < child.end) {
+ // Position in somewhere within this child. Search in it and
+ // stop searching in this array.
+ forEachChild(child, visitNode, visitArray);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ // position wasn't in this array, have to keep searching.
+ return false;
}
}
- return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
- }
- function isExternalModuleReference() {
- return token === 127 /* RequireKeyword */ &&
- lookAhead(nextTokenIsOpenParen);
}
- function nextTokenIsOpenParen() {
- return nextToken() === 17 /* OpenParenToken */;
+ var InvalidPosition;
+ (function (InvalidPosition) {
+ InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
+ })(InvalidPosition || (InvalidPosition = {}));
+ })(IncrementalParser || (IncrementalParser = {}));
+})(ts || (ts = {}));
+///
+///
+/* @internal */
+var ts;
+(function (ts) {
+ ts.bindTime = 0;
+ (function (ModuleInstanceState) {
+ ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
+ ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
+ ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
+ })(ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
+ var ModuleInstanceState = ts.ModuleInstanceState;
+ var Reachability;
+ (function (Reachability) {
+ Reachability[Reachability["Unintialized"] = 1] = "Unintialized";
+ Reachability[Reachability["Reachable"] = 2] = "Reachable";
+ Reachability[Reachability["Unreachable"] = 4] = "Unreachable";
+ Reachability[Reachability["ReportedUnreachable"] = 8] = "ReportedUnreachable";
+ })(Reachability || (Reachability = {}));
+ function or(state1, state2) {
+ return (state1 | state2) & 2 /* Reachable */
+ ? 2 /* Reachable */
+ : (state1 & state2) & 8 /* ReportedUnreachable */
+ ? 8 /* ReportedUnreachable */
+ : 4 /* Unreachable */;
+ }
+ function getModuleInstanceState(node) {
+ // A module is uninstantiated if it contains only
+ // 1. interface declarations, type alias declarations
+ if (node.kind === 215 /* InterfaceDeclaration */ || node.kind === 216 /* TypeAliasDeclaration */) {
+ return 0 /* NonInstantiated */;
}
- function nextTokenIsSlash() {
- return nextToken() === 39 /* SlashToken */;
+ else if (ts.isConstEnumDeclaration(node)) {
+ return 2 /* ConstEnumOnly */;
}
- function nextTokenIsCommaOrFromKeyword() {
- nextToken();
- return token === 24 /* CommaToken */ ||
- token === 133 /* FromKeyword */;
+ else if ((node.kind === 222 /* ImportDeclaration */ || node.kind === 221 /* ImportEqualsDeclaration */) && !(node.flags & 2 /* Export */)) {
+ return 0 /* NonInstantiated */;
}
- function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
- parseExpected(89 /* ImportKeyword */);
- var afterImportPos = scanner.getStartPos();
- var identifier;
- if (isIdentifier()) {
- identifier = parseIdentifier();
- if (token !== 24 /* CommaToken */ && token !== 133 /* FromKeyword */) {
- // ImportEquals declaration of type:
- // import x = require("mod"); or
- // import x = M.x;
- var importEqualsDeclaration = createNode(221 /* ImportEqualsDeclaration */, fullStart);
- importEqualsDeclaration.decorators = decorators;
- setModifiers(importEqualsDeclaration, modifiers);
- importEqualsDeclaration.name = identifier;
- parseExpected(56 /* EqualsToken */);
- importEqualsDeclaration.moduleReference = parseModuleReference();
- parseSemicolon();
- return finishNode(importEqualsDeclaration);
+ else if (node.kind === 219 /* ModuleBlock */) {
+ var state = 0 /* NonInstantiated */;
+ ts.forEachChild(node, function (n) {
+ switch (getModuleInstanceState(n)) {
+ case 0 /* NonInstantiated */:
+ // child is non-instantiated - continue searching
+ return false;
+ case 2 /* ConstEnumOnly */:
+ // child is const enum only - record state and continue searching
+ state = 2 /* ConstEnumOnly */;
+ return false;
+ case 1 /* Instantiated */:
+ // child is instantiated - record state and stop
+ state = 1 /* Instantiated */;
+ return true;
}
- }
- // Import statement
- var importDeclaration = createNode(222 /* ImportDeclaration */, fullStart);
- importDeclaration.decorators = decorators;
- setModifiers(importDeclaration, modifiers);
- // ImportDeclaration:
- // import ImportClause from ModuleSpecifier ;
- // import ModuleSpecifier;
- if (identifier ||
- token === 37 /* AsteriskToken */ ||
- token === 15 /* OpenBraceToken */) {
- importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
- parseExpected(133 /* FromKeyword */);
- }
- importDeclaration.moduleSpecifier = parseModuleSpecifier();
- parseSemicolon();
- return finishNode(importDeclaration);
- }
- function parseImportClause(identifier, fullStart) {
- // ImportClause:
- // ImportedDefaultBinding
- // NameSpaceImport
- // NamedImports
- // ImportedDefaultBinding, NameSpaceImport
- // ImportedDefaultBinding, NamedImports
- var importClause = createNode(223 /* ImportClause */, fullStart);
- if (identifier) {
- // ImportedDefaultBinding:
- // ImportedBinding
- importClause.name = identifier;
- }
- // If there was no default import or if there is comma token after default import
- // parse namespace or named imports
- if (!importClause.name ||
- parseOptional(24 /* CommaToken */)) {
- importClause.namedBindings = token === 37 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(225 /* NamedImports */);
- }
- return finishNode(importClause);
+ });
+ return state;
}
- function parseModuleReference() {
- return isExternalModuleReference()
- ? parseExternalModuleReference()
- : parseEntityName(/*allowReservedWords*/ false);
+ else if (node.kind === 218 /* ModuleDeclaration */) {
+ return getModuleInstanceState(node.body);
}
- function parseExternalModuleReference() {
- var node = createNode(232 /* ExternalModuleReference */);
- parseExpected(127 /* RequireKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = parseModuleSpecifier();
- parseExpected(18 /* CloseParenToken */);
- return finishNode(node);
+ else {
+ return 1 /* Instantiated */;
}
- function parseModuleSpecifier() {
- // We allow arbitrary expressions here, even though the grammar only allows string
- // literals. We check to ensure that it is only a string literal later in the grammar
- // walker.
- var result = parseExpression();
- // Ensure the string being required is in our 'identifier' table. This will ensure
- // that features like 'find refs' will look inside this file when search for its name.
- if (result.kind === 9 /* StringLiteral */) {
- internIdentifier(result.text);
+ }
+ ts.getModuleInstanceState = getModuleInstanceState;
+ var ContainerFlags;
+ (function (ContainerFlags) {
+ // The current node is not a container, and no container manipulation should happen before
+ // recursing into it.
+ ContainerFlags[ContainerFlags["None"] = 0] = "None";
+ // The current node is a container. It should be set as the current container (and block-
+ // container) before recursing into it. The current node does not have locals. Examples:
+ //
+ // Classes, ObjectLiterals, TypeLiterals, Interfaces...
+ ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
+ // The current node is a block-scoped-container. It should be set as the current block-
+ // container before recursing into it. Examples:
+ //
+ // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
+ ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
+ ContainerFlags[ContainerFlags["HasLocals"] = 4] = "HasLocals";
+ // If the current node is a container that also container that also contains locals. Examples:
+ //
+ // Functions, Methods, Modules, Source-files.
+ ContainerFlags[ContainerFlags["IsContainerWithLocals"] = 5] = "IsContainerWithLocals";
+ })(ContainerFlags || (ContainerFlags = {}));
+ var binder = createBinder();
+ function bindSourceFile(file, options) {
+ var start = new Date().getTime();
+ binder(file, options);
+ ts.bindTime += new Date().getTime() - start;
+ }
+ ts.bindSourceFile = bindSourceFile;
+ function createBinder() {
+ var file;
+ var options;
+ var parent;
+ var container;
+ var blockScopeContainer;
+ var lastContainer;
+ var seenThisKeyword;
+ // state used by reachability checks
+ var hasExplicitReturn;
+ var currentReachabilityState;
+ var labelStack;
+ var labelIndexMap;
+ var implicitLabels;
+ // If this file is an external module, then it is automatically in strict-mode according to
+ // ES6. If it is not an external module, then we'll determine if it is in strict mode or
+ // not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
+ var inStrictMode;
+ var symbolCount = 0;
+ var Symbol;
+ var classifiableNames;
+ function bindSourceFile(f, opts) {
+ file = f;
+ options = opts;
+ inStrictMode = !!file.externalModuleIndicator;
+ classifiableNames = {};
+ Symbol = ts.objectAllocator.getSymbolConstructor();
+ if (!file.locals) {
+ bind(file);
+ file.symbolCount = symbolCount;
+ file.classifiableNames = classifiableNames;
}
- return result;
- }
- function parseNamespaceImport() {
- // NameSpaceImport:
- // * as ImportedBinding
- var namespaceImport = createNode(224 /* NamespaceImport */);
- parseExpected(37 /* AsteriskToken */);
- parseExpected(116 /* AsKeyword */);
- namespaceImport.name = parseIdentifier();
- return finishNode(namespaceImport);
- }
- function parseNamedImportsOrExports(kind) {
- var node = createNode(kind);
- // NamedImports:
- // { }
- // { ImportsList }
- // { ImportsList, }
- // ImportsList:
- // ImportSpecifier
- // ImportsList, ImportSpecifier
- node.elements = parseBracketedList(21 /* ImportOrExportSpecifiers */, kind === 225 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 15 /* OpenBraceToken */, 16 /* CloseBraceToken */);
- return finishNode(node);
- }
- function parseExportSpecifier() {
- return parseImportOrExportSpecifier(230 /* ExportSpecifier */);
- }
- function parseImportSpecifier() {
- return parseImportOrExportSpecifier(226 /* ImportSpecifier */);
+ parent = undefined;
+ container = undefined;
+ blockScopeContainer = undefined;
+ lastContainer = undefined;
+ seenThisKeyword = false;
+ hasExplicitReturn = false;
+ labelStack = undefined;
+ labelIndexMap = undefined;
+ implicitLabels = undefined;
}
- function parseImportOrExportSpecifier(kind) {
- var node = createNode(kind);
- // ImportSpecifier:
- // BindingIdentifier
- // IdentifierName as BindingIdentifier
- // ExportSpecififer:
- // IdentifierName
- // IdentifierName as IdentifierName
- var checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
- var checkIdentifierStart = scanner.getTokenPos();
- var checkIdentifierEnd = scanner.getTextPos();
- var identifierName = parseIdentifierName();
- if (token === 116 /* AsKeyword */) {
- node.propertyName = identifierName;
- parseExpected(116 /* AsKeyword */);
- checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
- checkIdentifierStart = scanner.getTokenPos();
- checkIdentifierEnd = scanner.getTextPos();
- node.name = parseIdentifierName();
- }
- else {
- node.name = identifierName;
- }
- if (kind === 226 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
- // Report error identifier expected
- parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected);
- }
- return finishNode(node);
+ return bindSourceFile;
+ function createSymbol(flags, name) {
+ symbolCount++;
+ return new Symbol(flags, name);
}
- function parseExportDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(228 /* ExportDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- if (parseOptional(37 /* AsteriskToken */)) {
- parseExpected(133 /* FromKeyword */);
- node.moduleSpecifier = parseModuleSpecifier();
+ function addDeclarationToSymbol(symbol, node, symbolFlags) {
+ symbol.flags |= symbolFlags;
+ node.symbol = symbol;
+ if (!symbol.declarations) {
+ symbol.declarations = [];
}
- else {
- node.exportClause = parseNamedImportsOrExports(229 /* NamedExports */);
- // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
- // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
- // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
- if (token === 133 /* FromKeyword */ || (token === 9 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
- parseExpected(133 /* FromKeyword */);
- node.moduleSpecifier = parseModuleSpecifier();
- }
+ symbol.declarations.push(node);
+ if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) {
+ symbol.exports = {};
}
- parseSemicolon();
- return finishNode(node);
- }
- function parseExportAssignment(fullStart, decorators, modifiers) {
- var node = createNode(227 /* ExportAssignment */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- if (parseOptional(56 /* EqualsToken */)) {
- node.isExportEquals = true;
+ if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) {
+ symbol.members = {};
}
- else {
- parseExpected(77 /* DefaultKeyword */);
+ if (symbolFlags & 107455 /* Value */ && !symbol.valueDeclaration) {
+ symbol.valueDeclaration = node;
}
- node.expression = parseAssignmentExpressionOrHigher();
- parseSemicolon();
- return finishNode(node);
}
- function processReferenceComments(sourceFile) {
- var triviaScanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, 0 /* Standard */, sourceText);
- var referencedFiles = [];
- var amdDependencies = [];
- var amdModuleName;
- // Keep scanning all the leading trivia in the file until we get to something that
- // isn't trivia. Any single line comment will be analyzed to see if it is a
- // reference comment.
- while (true) {
- var kind = triviaScanner.scan();
- if (kind === 5 /* WhitespaceTrivia */ || kind === 4 /* NewLineTrivia */ || kind === 3 /* MultiLineCommentTrivia */) {
- continue;
- }
- if (kind !== 2 /* SingleLineCommentTrivia */) {
- break;
- }
- var range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
- var comment = sourceText.substring(range.pos, range.end);
- var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range);
- if (referencePathMatchResult) {
- var fileReference = referencePathMatchResult.fileReference;
- sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
- var diagnosticMessage = referencePathMatchResult.diagnosticMessage;
- if (fileReference) {
- referencedFiles.push(fileReference);
- }
- if (diagnosticMessage) {
- parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage));
- }
+ // Should not be called on a declaration with a computed property name,
+ // unless it is a well known Symbol.
+ function getDeclarationName(node) {
+ if (node.name) {
+ if (node.kind === 218 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */) {
+ return "\"" + node.name.text + "\"";
}
- else {
- var amdModuleNameRegEx = /^\/\/\/\s*".length;
- return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
- }
+ container = saveContainer;
+ parent = saveParent;
+ blockScopeContainer = savedBlockScopeContainer;
+ }
+ /**
+ * Returns true if node and its subnodes were successfully traversed.
+ * Returning false means that node was not examined and caller needs to dive into the node himself.
+ */
+ function bindReachableStatement(node) {
+ if (checkUnreachable(node)) {
+ ts.forEachChild(node, bind);
+ return;
}
- function parseQualifiedName(left) {
- var result = createNode(135 /* QualifiedName */, left.pos);
- result.left = left;
- result.right = parseIdentifierName();
- return finishNode(result);
+ switch (node.kind) {
+ case 198 /* WhileStatement */:
+ bindWhileStatement(node);
+ break;
+ case 197 /* DoStatement */:
+ bindDoStatement(node);
+ break;
+ case 199 /* ForStatement */:
+ bindForStatement(node);
+ break;
+ case 200 /* ForInStatement */:
+ case 201 /* ForOfStatement */:
+ bindForInOrForOfStatement(node);
+ break;
+ case 196 /* IfStatement */:
+ bindIfStatement(node);
+ break;
+ case 204 /* ReturnStatement */:
+ case 208 /* ThrowStatement */:
+ bindReturnOrThrow(node);
+ break;
+ case 203 /* BreakStatement */:
+ case 202 /* ContinueStatement */:
+ bindBreakOrContinueStatement(node);
+ break;
+ case 209 /* TryStatement */:
+ bindTryStatement(node);
+ break;
+ case 206 /* SwitchStatement */:
+ bindSwitchStatement(node);
+ break;
+ case 220 /* CaseBlock */:
+ bindCaseBlock(node);
+ break;
+ case 207 /* LabeledStatement */:
+ bindLabeledStatement(node);
+ break;
+ default:
+ ts.forEachChild(node, bind);
+ break;
}
- function parseJSDocRecordType() {
- var result = createNode(257 /* JSDocRecordType */);
- nextToken();
- result.members = parseDelimitedList(24 /* JSDocRecordMembers */, parseJSDocRecordMember);
- checkForTrailingComma(result.members);
- parseExpected(16 /* CloseBraceToken */);
- return finishNode(result);
+ }
+ function bindWhileStatement(n) {
+ var preWhileState = n.expression.kind === 84 /* FalseKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
+ var postWhileState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
+ // bind expressions (don't affect reachability)
+ bind(n.expression);
+ currentReachabilityState = preWhileState;
+ var postWhileLabel = pushImplicitLabel();
+ bind(n.statement);
+ popImplicitLabel(postWhileLabel, postWhileState);
+ }
+ function bindDoStatement(n) {
+ var preDoState = currentReachabilityState;
+ var postDoLabel = pushImplicitLabel();
+ bind(n.statement);
+ var postDoState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : preDoState;
+ popImplicitLabel(postDoLabel, postDoState);
+ // bind expressions (don't affect reachability)
+ bind(n.expression);
+ }
+ function bindForStatement(n) {
+ var preForState = currentReachabilityState;
+ var postForLabel = pushImplicitLabel();
+ // bind expressions (don't affect reachability)
+ bind(n.initializer);
+ bind(n.condition);
+ bind(n.incrementor);
+ bind(n.statement);
+ // for statement is considered infinite when it condition is either omitted or is true keyword
+ // - for(..;;..)
+ // - for(..;true;..)
+ var isInfiniteLoop = (!n.condition || n.condition.kind === 99 /* TrueKeyword */);
+ var postForState = isInfiniteLoop ? 4 /* Unreachable */ : preForState;
+ popImplicitLabel(postForLabel, postForState);
+ }
+ function bindForInOrForOfStatement(n) {
+ var preStatementState = currentReachabilityState;
+ var postStatementLabel = pushImplicitLabel();
+ // bind expressions (don't affect reachability)
+ bind(n.initializer);
+ bind(n.expression);
+ bind(n.statement);
+ popImplicitLabel(postStatementLabel, preStatementState);
+ }
+ function bindIfStatement(n) {
+ // denotes reachability state when entering 'thenStatement' part of the if statement:
+ // i.e. if condition is false then thenStatement is unreachable
+ var ifTrueState = n.expression.kind === 84 /* FalseKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
+ // denotes reachability state when entering 'elseStatement':
+ // i.e. if condition is true then elseStatement is unreachable
+ var ifFalseState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
+ currentReachabilityState = ifTrueState;
+ // bind expression (don't affect reachability)
+ bind(n.expression);
+ bind(n.thenStatement);
+ if (n.elseStatement) {
+ var preElseState = currentReachabilityState;
+ currentReachabilityState = ifFalseState;
+ bind(n.elseStatement);
+ currentReachabilityState = or(currentReachabilityState, preElseState);
}
- function parseJSDocRecordMember() {
- var result = createNode(258 /* JSDocRecordMember */);
- result.name = parseSimplePropertyName();
- if (token === 54 /* ColonToken */) {
- nextToken();
- result.type = parseJSDocType();
- }
- return finishNode(result);
+ else {
+ currentReachabilityState = or(currentReachabilityState, ifFalseState);
}
- function parseJSDocNonNullableType() {
- var result = createNode(256 /* JSDocNonNullableType */);
- nextToken();
- result.type = parseJSDocType();
- return finishNode(result);
+ }
+ function bindReturnOrThrow(n) {
+ // bind expression (don't affect reachability)
+ bind(n.expression);
+ if (n.kind === 204 /* ReturnStatement */) {
+ hasExplicitReturn = true;
}
- function parseJSDocTupleType() {
- var result = createNode(254 /* JSDocTupleType */);
- nextToken();
- result.types = parseDelimitedList(25 /* JSDocTupleTypes */, parseJSDocType);
- checkForTrailingComma(result.types);
- parseExpected(20 /* CloseBracketToken */);
- return finishNode(result);
+ currentReachabilityState = 4 /* Unreachable */;
+ }
+ function bindBreakOrContinueStatement(n) {
+ // call bind on label (don't affect reachability)
+ bind(n.label);
+ // for continue case touch label so it will be marked a used
+ var isValidJump = jumpToLabel(n.label, n.kind === 203 /* BreakStatement */ ? currentReachabilityState : 4 /* Unreachable */);
+ if (isValidJump) {
+ currentReachabilityState = 4 /* Unreachable */;
}
- function checkForTrailingComma(list) {
- if (parseDiagnostics.length === 0 && list.hasTrailingComma) {
- var start = list.end - ",".length;
- parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed);
+ }
+ function bindTryStatement(n) {
+ // catch\finally blocks has the same reachability as try block
+ var preTryState = currentReachabilityState;
+ bind(n.tryBlock);
+ var postTryState = currentReachabilityState;
+ currentReachabilityState = preTryState;
+ bind(n.catchClause);
+ var postCatchState = currentReachabilityState;
+ currentReachabilityState = preTryState;
+ bind(n.finallyBlock);
+ // post catch/finally state is reachable if
+ // - post try state is reachable - control flow can fall out of try block
+ // - post catch state is reachable - control flow can fall out of catch block
+ currentReachabilityState = or(postTryState, postCatchState);
+ }
+ function bindSwitchStatement(n) {
+ var preSwitchState = currentReachabilityState;
+ var postSwitchLabel = pushImplicitLabel();
+ // bind expression (don't affect reachability)
+ bind(n.expression);
+ bind(n.caseBlock);
+ var hasDefault = ts.forEach(n.caseBlock.clauses, function (c) { return c.kind === 242 /* DefaultClause */; });
+ // post switch state is unreachable if switch is exaustive (has a default case ) and does not have fallthrough from the last case
+ var postSwitchState = hasDefault && currentReachabilityState !== 2 /* Reachable */ ? 4 /* Unreachable */ : preSwitchState;
+ popImplicitLabel(postSwitchLabel, postSwitchState);
+ }
+ function bindCaseBlock(n) {
+ var startState = currentReachabilityState;
+ for (var _i = 0, _a = n.clauses; _i < _a.length; _i++) {
+ var clause = _a[_i];
+ currentReachabilityState = startState;
+ bind(clause);
+ if (clause.statements.length && currentReachabilityState === 2 /* Reachable */ && options.noFallthroughCasesInSwitch) {
+ errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
}
}
- function parseJSDocUnionType() {
- var result = createNode(253 /* JSDocUnionType */);
- nextToken();
- result.types = parseJSDocTypeList(parseJSDocType());
- parseExpected(18 /* CloseParenToken */);
- return finishNode(result);
+ }
+ function bindLabeledStatement(n) {
+ // call bind on label (don't affect reachability)
+ bind(n.label);
+ var ok = pushNamedLabel(n.label);
+ bind(n.statement);
+ if (ok) {
+ popNamedLabel(n.label, currentReachabilityState);
}
- function parseJSDocTypeList(firstType) {
- ts.Debug.assert(!!firstType);
- var types = [];
- types.pos = firstType.pos;
- types.push(firstType);
- while (parseOptional(47 /* BarToken */)) {
- types.push(parseJSDocType());
- }
- types.end = scanner.getStartPos();
- return types;
+ }
+ function getContainerFlags(node) {
+ switch (node.kind) {
+ case 186 /* ClassExpression */:
+ case 214 /* ClassDeclaration */:
+ case 215 /* InterfaceDeclaration */:
+ case 217 /* EnumDeclaration */:
+ case 155 /* TypeLiteral */:
+ case 165 /* ObjectLiteralExpression */:
+ return 1 /* IsContainer */;
+ case 147 /* CallSignature */:
+ case 148 /* ConstructSignature */:
+ case 149 /* IndexSignature */:
+ case 143 /* MethodDeclaration */:
+ case 142 /* MethodSignature */:
+ case 213 /* FunctionDeclaration */:
+ case 144 /* Constructor */:
+ case 145 /* GetAccessor */:
+ case 146 /* SetAccessor */:
+ case 152 /* FunctionType */:
+ case 153 /* ConstructorType */:
+ case 173 /* FunctionExpression */:
+ case 174 /* ArrowFunction */:
+ case 218 /* ModuleDeclaration */:
+ case 248 /* SourceFile */:
+ case 216 /* TypeAliasDeclaration */:
+ return 5 /* IsContainerWithLocals */;
+ case 244 /* CatchClause */:
+ case 199 /* ForStatement */:
+ case 200 /* ForInStatement */:
+ case 201 /* ForOfStatement */:
+ case 220 /* CaseBlock */:
+ return 2 /* IsBlockScopedContainer */;
+ case 192 /* Block */:
+ // do not treat blocks directly inside a function as a block-scoped-container.
+ // Locals that reside in this block should go to the function locals. Othewise 'x'
+ // would not appear to be a redeclaration of a block scoped local in the following
+ // example:
+ //
+ // function foo() {
+ // var x;
+ // let x;
+ // }
+ //
+ // If we placed 'var x' into the function locals and 'let x' into the locals of
+ // the block, then there would be no collision.
+ //
+ // By not creating a new block-scoped-container here, we ensure that both 'var x'
+ // and 'let x' go into the Function-container's locals, and we do get a collision
+ // conflict.
+ return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
}
- function parseJSDocAllType() {
- var result = createNode(250 /* JSDocAllType */);
- nextToken();
- return finishNode(result);
+ return 0 /* None */;
+ }
+ function addToContainerChain(next) {
+ if (lastContainer) {
+ lastContainer.nextContainer = next;
}
- function parseJSDocUnknownOrNullableType() {
- var pos = scanner.getStartPos();
- // skip the ?
- nextToken();
- // Need to lookahead to decide if this is a nullable or unknown type.
- // Here are cases where we'll pick the unknown type:
- //
- // Foo(?,
- // { a: ? }
- // Foo(?)
- // Foo>
- // Foo(?=
- // (?|
- if (token === 24 /* CommaToken */ ||
- token === 16 /* CloseBraceToken */ ||
- token === 18 /* CloseParenToken */ ||
- token === 27 /* GreaterThanToken */ ||
- token === 56 /* EqualsToken */ ||
- token === 47 /* BarToken */) {
- var result = createNode(251 /* JSDocUnknownType */, pos);
- return finishNode(result);
- }
- else {
- var result = createNode(255 /* JSDocNullableType */, pos);
- result.type = parseJSDocType();
- return finishNode(result);
+ lastContainer = next;
+ }
+ function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
+ // Just call this directly so that the return type of this function stays "void".
+ declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes);
+ }
+ function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) {
+ switch (container.kind) {
+ // Modules, source files, and classes need specialized handling for how their
+ // members are declared (for example, a member of a class will go into a specific
+ // symbol table depending on if it is static or not). We defer to specialized
+ // handlers to take care of declaring these child members.
+ case 218 /* ModuleDeclaration */:
+ return declareModuleMember(node, symbolFlags, symbolExcludes);
+ case 248 /* SourceFile */:
+ return declareSourceFileMember(node, symbolFlags, symbolExcludes);
+ case 186 /* ClassExpression */:
+ case 214 /* ClassDeclaration */:
+ return declareClassMember(node, symbolFlags, symbolExcludes);
+ case 217 /* EnumDeclaration */:
+ return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
+ case 155 /* TypeLiteral */:
+ case 165 /* ObjectLiteralExpression */:
+ case 215 /* InterfaceDeclaration */:
+ // Interface/Object-types always have their children added to the 'members' of
+ // their container. They are only accessible through an instance of their
+ // container, and are never in scope otherwise (even inside the body of the
+ // object / type / interface declaring them). An exception is type parameters,
+ // which are in scope without qualification (similar to 'locals').
+ return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
+ case 152 /* FunctionType */:
+ case 153 /* ConstructorType */:
+ case 147 /* CallSignature */:
+ case 148 /* ConstructSignature */:
+ case 149 /* IndexSignature */:
+ case 143 /* MethodDeclaration */:
+ case 142 /* MethodSignature */:
+ case 144 /* Constructor */:
+ case 145 /* GetAccessor */:
+ case 146 /* SetAccessor */:
+ case 213 /* FunctionDeclaration */:
+ case 173 /* FunctionExpression */:
+ case 174 /* ArrowFunction */:
+ case 216 /* TypeAliasDeclaration */:
+ // All the children of these container types are never visible through another
+ // symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
+ // they're only accessed 'lexically' (i.e. from code that exists underneath
+ // their container in the tree. To accomplish this, we simply add their declared
+ // symbol to the 'locals' of the container. These symbols can then be found as
+ // the type checker walks up the containers, checking them for matching names.
+ return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ }
+ function declareClassMember(node, symbolFlags, symbolExcludes) {
+ return node.flags & 64 /* Static */
+ ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
+ : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
+ }
+ function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
+ return ts.isExternalModule(file)
+ ? declareModuleMember(node, symbolFlags, symbolExcludes)
+ : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ function hasExportDeclarations(node) {
+ var body = node.kind === 248 /* SourceFile */ ? node : node.body;
+ if (body.kind === 248 /* SourceFile */ || body.kind === 219 /* ModuleBlock */) {
+ for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
+ var stat = _a[_i];
+ if (stat.kind === 228 /* ExportDeclaration */ || stat.kind === 227 /* ExportAssignment */) {
+ return true;
+ }
}
}
- function parseIsolatedJSDocComment(content, start, length) {
- initializeState("file.js", content, 2 /* Latest */, /*_syntaxCursor:*/ undefined);
- var jsDocComment = parseJSDocComment(/*parent:*/ undefined, start, length);
- var diagnostics = parseDiagnostics;
- clearState();
- return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined;
+ return false;
+ }
+ function setExportContextFlag(node) {
+ // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
+ // declarations with export modifiers) is an export context in which declarations are implicitly exported.
+ if (ts.isInAmbientContext(node) && !hasExportDeclarations(node)) {
+ node.flags |= 131072 /* ExportContext */;
}
- JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
- function parseJSDocComment(parent, start, length) {
- var comment = parseJSDocCommentWorker(start, length);
- if (comment) {
- fixupParentReferences(comment);
- comment.parent = parent;
- }
- return comment;
+ else {
+ node.flags &= ~131072 /* ExportContext */;
}
- JSDocParser.parseJSDocComment = parseJSDocComment;
- function parseJSDocCommentWorker(start, length) {
- var content = sourceText;
- start = start || 0;
- var end = length === undefined ? content.length : start + length;
- length = end - start;
- ts.Debug.assert(start >= 0);
- ts.Debug.assert(start <= end);
- ts.Debug.assert(end <= content.length);
- var tags;
- var pos;
- // NOTE(cyrusn): This is essentially a handwritten scanner for JSDocComments. I
- // considered using an actual Scanner, but this would complicate things. The
- // scanner would need to know it was in a Doc Comment. Otherwise, it would then
- // produce comments *inside* the doc comment. In the end it was just easier to
- // write a simple scanner rather than go that route.
- if (length >= "/** */".length) {
- if (content.charCodeAt(start) === 47 /* slash */ &&
- content.charCodeAt(start + 1) === 42 /* asterisk */ &&
- content.charCodeAt(start + 2) === 42 /* asterisk */ &&
- content.charCodeAt(start + 3) !== 42 /* asterisk */) {
- // Initially we can parse out a tag. We also have seen a starting asterisk.
- // This is so that /** * @type */ doesn't parse.
- var canParseTag = true;
- var seenAsterisk = true;
- for (pos = start + "/**".length; pos < end;) {
- var ch = content.charCodeAt(pos);
- pos++;
- if (ch === 64 /* at */ && canParseTag) {
- parseTag();
- // Once we parse out a tag, we cannot keep parsing out tags on this line.
- canParseTag = false;
- continue;
- }
- if (ts.isLineBreak(ch)) {
- // After a line break, we can parse a tag, and we haven't seen as asterisk
- // on the next line yet.
- canParseTag = true;
- seenAsterisk = false;
- continue;
- }
- if (ts.isWhiteSpace(ch)) {
- // Whitespace doesn't affect any of our parsing.
- continue;
- }
- // Ignore the first asterisk on a line.
- if (ch === 42 /* asterisk */) {
- if (seenAsterisk) {
- // If we've already seen an asterisk, then we can no longer parse a tag
- // on this line.
- canParseTag = false;
- }
- seenAsterisk = true;
- continue;
- }
- // Anything else is doc comment text. We can't do anything with it. Because it
- // wasn't a tag, we can no longer parse a tag on this line until we hit the next
- // line break.
- canParseTag = false;
- }
- }
- }
- return createJSDocComment();
- function createJSDocComment() {
- if (!tags) {
- return undefined;
- }
- var result = createNode(265 /* JSDocComment */, start);
- result.tags = tags;
- return finishNode(result, end);
- }
- function skipWhitespace() {
- while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) {
- pos++;
- }
+ }
+ function bindModuleDeclaration(node) {
+ setExportContextFlag(node);
+ if (node.name.kind === 9 /* StringLiteral */) {
+ declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
+ }
+ else {
+ var state = getModuleInstanceState(node);
+ if (state === 0 /* NonInstantiated */) {
+ declareSymbolAndAddToSymbolTable(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */);
}
- function parseTag() {
- ts.Debug.assert(content.charCodeAt(pos - 1) === 64 /* at */);
- var atToken = createNode(55 /* AtToken */, pos - 1);
- atToken.end = pos;
- var tagName = scanIdentifier();
- if (!tagName) {
- return;
+ else {
+ declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
+ if (node.symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)) {
+ // if module was already merged with some function, class or non-const enum
+ // treat is a non-const-enum-only
+ node.symbol.constEnumOnlyModule = false;
}
- var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName);
- addTag(tag);
- }
- function handleTag(atToken, tagName) {
- if (tagName) {
- switch (tagName.text) {
- case "param":
- return handleParamTag(atToken, tagName);
- case "return":
- case "returns":
- return handleReturnTag(atToken, tagName);
- case "template":
- return handleTemplateTag(atToken, tagName);
- case "type":
- return handleTypeTag(atToken, tagName);
+ else {
+ var currentModuleIsConstEnumOnly = state === 2 /* ConstEnumOnly */;
+ if (node.symbol.constEnumOnlyModule === undefined) {
+ // non-merged case - use the current state
+ node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
}
- }
- return undefined;
- }
- function handleUnknownTag(atToken, tagName) {
- var result = createNode(266 /* JSDocTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- return finishNode(result, pos);
- }
- function addTag(tag) {
- if (tag) {
- if (!tags) {
- tags = [];
- tags.pos = tag.pos;
+ else {
+ // merged case: module is const enum only if all its pieces are non-instantiated or const enum
+ node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
}
- tags.push(tag);
- tags.end = tag.end;
- }
- }
- function tryParseTypeExpression() {
- skipWhitespace();
- if (content.charCodeAt(pos) !== 123 /* openBrace */) {
- return undefined;
- }
- var typeExpression = parseJSDocTypeExpression(pos, end - pos);
- pos = typeExpression.end;
- return typeExpression;
- }
- function handleParamTag(atToken, tagName) {
- var typeExpression = tryParseTypeExpression();
- skipWhitespace();
- var name;
- var isBracketed;
- if (content.charCodeAt(pos) === 91 /* openBracket */) {
- pos++;
- skipWhitespace();
- name = scanIdentifier();
- isBracketed = true;
- }
- else {
- name = scanIdentifier();
- }
- if (!name) {
- parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected);
- }
- var preName, postName;
- if (typeExpression) {
- postName = name;
- }
- else {
- preName = name;
- }
- if (!typeExpression) {
- typeExpression = tryParseTypeExpression();
- }
- var result = createNode(267 /* JSDocParameterTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.preParameterName = preName;
- result.typeExpression = typeExpression;
- result.postParameterName = postName;
- result.isBracketed = isBracketed;
- return finishNode(result, pos);
- }
- function handleReturnTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 268 /* JSDocReturnTag */; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
}
- var result = createNode(268 /* JSDocReturnTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeExpression = tryParseTypeExpression();
- return finishNode(result, pos);
}
- function handleTypeTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 269 /* JSDocTypeTag */; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ }
+ function bindFunctionOrConstructorType(node) {
+ // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
+ // to the one we would get for: { <...>(...): T }
+ //
+ // We do that by making an anonymous type literal symbol, and then setting the function
+ // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
+ // from an actual type literal symbol you would have gotten had you used the long form.
+ var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node));
+ addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
+ var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type");
+ addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
+ typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a);
+ var _a;
+ }
+ function bindObjectLiteralExpression(node) {
+ var ElementKind;
+ (function (ElementKind) {
+ ElementKind[ElementKind["Property"] = 1] = "Property";
+ ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
+ })(ElementKind || (ElementKind = {}));
+ if (inStrictMode) {
+ var seen = {};
+ for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
+ var prop = _a[_i];
+ if (prop.name.kind !== 69 /* Identifier */) {
+ continue;
}
- var result = createNode(269 /* JSDocTypeTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeExpression = tryParseTypeExpression();
- return finishNode(result, pos);
- }
- function handleTemplateTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 270 /* JSDocTemplateTag */; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ var identifier = prop.name;
+ // ECMA-262 11.1.5 Object Initialiser
+ // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
+ // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
+ // IsDataDescriptor(propId.descriptor) is true.
+ // b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
+ // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
+ // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
+ // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
+ var currentKind = prop.kind === 245 /* PropertyAssignment */ || prop.kind === 246 /* ShorthandPropertyAssignment */ || prop.kind === 143 /* MethodDeclaration */
+ ? 1 /* Property */
+ : 2 /* Accessor */;
+ var existingKind = seen[identifier.text];
+ if (!existingKind) {
+ seen[identifier.text] = currentKind;
+ continue;
}
- var typeParameters = [];
- typeParameters.pos = pos;
- while (true) {
- skipWhitespace();
- var startPos = pos;
- var name_8 = scanIdentifier();
- if (!name_8) {
- parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected);
- return undefined;
- }
- var typeParameter = createNode(137 /* TypeParameter */, name_8.pos);
- typeParameter.name = name_8;
- finishNode(typeParameter, pos);
- typeParameters.push(typeParameter);
- skipWhitespace();
- if (content.charCodeAt(pos) !== 44 /* comma */) {
- break;
- }
- pos++;
+ if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
+ var span = ts.getErrorSpanForNode(file, identifier);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
}
- typeParameters.end = pos;
- var result = createNode(270 /* JSDocTemplateTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeParameters = typeParameters;
- return finishNode(result, pos);
}
- function scanIdentifier() {
- var startPos = pos;
- for (; pos < end; pos++) {
- var ch = content.charCodeAt(pos);
- if (pos === startPos && ts.isIdentifierStart(ch, 2 /* Latest */)) {
- continue;
- }
- else if (pos > startPos && ts.isIdentifierPart(ch, 2 /* Latest */)) {
- continue;
- }
+ }
+ return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object");
+ }
+ function bindAnonymousDeclaration(node, symbolFlags, name) {
+ var symbol = createSymbol(symbolFlags, name);
+ addDeclarationToSymbol(symbol, node, symbolFlags);
+ }
+ function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
+ switch (blockScopeContainer.kind) {
+ case 218 /* ModuleDeclaration */:
+ declareModuleMember(node, symbolFlags, symbolExcludes);
+ break;
+ case 248 /* SourceFile */:
+ if (ts.isExternalModule(container)) {
+ declareModuleMember(node, symbolFlags, symbolExcludes);
break;
}
- if (startPos === pos) {
- return undefined;
- }
- var result = createNode(69 /* Identifier */, startPos);
- result.text = content.substring(startPos, pos);
- return finishNode(result, pos);
+ // fall through.
+ default:
+ if (!blockScopeContainer.locals) {
+ blockScopeContainer.locals = {};
+ addToContainerChain(blockScopeContainer);
+ }
+ declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ }
+ function bindBlockScopedVariableDeclaration(node) {
+ bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
+ }
+ // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
+ // check for reserved words used as identifiers in strict mode code.
+ function checkStrictModeIdentifier(node) {
+ if (inStrictMode &&
+ node.originalKeywordKind >= 106 /* FirstFutureReservedWord */ &&
+ node.originalKeywordKind <= 114 /* LastFutureReservedWord */ &&
+ !ts.isIdentifierName(node)) {
+ // Report error only if there are no parse errors in file
+ if (!file.parseDiagnostics.length) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
}
}
- JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
- })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
- })(Parser || (Parser = {}));
- var IncrementalParser;
- (function (IncrementalParser) {
- function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
- aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
- checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
- if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
- // if the text didn't change, then we can just return our current source file as-is.
- return sourceFile;
+ }
+ function getStrictModeIdentifierMessage(node) {
+ // Provide specialized messages to help the user understand why we think they're in
+ // strict mode.
+ if (ts.getContainingClass(node)) {
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
}
- if (sourceFile.statements.length === 0) {
- // If we don't have any statements in the current source file, then there's no real
- // way to incrementally parse. So just do a full parse instead.
- return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setNodeParents*/ true);
+ if (file.externalModuleIndicator) {
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
}
- // Make sure we're not trying to incrementally update a source file more than once. Once
- // we do an update the original source file is considered unusbale from that point onwards.
- //
- // This is because we do incremental parsing in-place. i.e. we take nodes from the old
- // tree and give them new positions and parents. From that point on, trusting the old
- // tree at all is not possible as far too much of it may violate invariants.
- var incrementalSourceFile = sourceFile;
- ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
- incrementalSourceFile.hasBeenIncrementallyParsed = true;
- var oldText = sourceFile.text;
- var syntaxCursor = createSyntaxCursor(sourceFile);
- // Make the actual change larger so that we know to reparse anything whose lookahead
- // might have intersected the change.
- var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
- checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
- // Ensure that extending the affected range only moved the start of the change range
- // earlier in the file.
- ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
- ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
- ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
- // The is the amount the nodes after the edit range need to be adjusted. It can be
- // positive (if the edit added characters), negative (if the edit deleted characters)
- // or zero (if this was a pure overwrite with nothing added/removed).
- var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
- // If we added or removed characters during the edit, then we need to go and adjust all
- // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they
- // may move backward (if we deleted chars).
- //
- // Doing this helps us out in two ways. First, it means that any nodes/tokens we want
- // to reuse are already at the appropriate position in the new text. That way when we
- // reuse them, we don't have to figure out if they need to be adjusted. Second, it makes
- // it very easy to determine if we can reuse a node. If the node's position is at where
- // we are in the text, then we can reuse it. Otherwise we can't. If the node's position
- // is ahead of us, then we'll need to rescan tokens. If the node's position is behind
- // us, then we'll need to skip it or crumble it as appropriate
- //
- // We will also adjust the positions of nodes that intersect the change range as well.
- // By doing this, we ensure that all the positions in the old tree are consistent, not
- // just the positions of nodes entirely before/after the change range. By being
- // consistent, we can then easily map from positions to nodes in the old tree easily.
- //
- // Also, mark any syntax elements that intersect the changed span. We know, up front,
- // that we cannot reuse these elements.
- updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
- // Now that we've set up our internal incremental state just proceed and parse the
- // source file in the normal fashion. When possible the parser will retrieve and
- // reuse nodes from the old tree.
- //
- // Note: passing in 'true' for setNodeParents is very important. When incrementally
- // parsing, we will be reusing nodes from the old tree, and placing it into new
- // parents. If we don't set the parents now, we'll end up with an observably
- // inconsistent tree. Setting the parents on the new tree should be very fast. We
- // will immediately bail out of walking any subtrees when we can see that their parents
- // are already correct.
- var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /* setParentNode */ true);
- return result;
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
}
- IncrementalParser.updateSourceFile = updateSourceFile;
- function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
- if (isArray) {
- visitArray(element);
+ function checkStrictModeBinaryExpression(node) {
+ if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
+ // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
+ // Assignment operator(11.13) or of a PostfixExpression(11.3)
+ checkStrictModeEvalOrArguments(node, node.left);
}
- else {
- visitNode(element);
+ }
+ function checkStrictModeCatchClause(node) {
+ // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
+ // Catch production is eval or arguments
+ if (inStrictMode && node.variableDeclaration) {
+ checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
}
- return;
- function visitNode(node) {
- var text = "";
- if (aggressiveChecks && shouldCheckNode(node)) {
- text = oldText.substring(node.pos, node.end);
- }
- // Ditch any existing LS children we may have created. This way we can avoid
- // moving them forward.
- if (node._children) {
- node._children = undefined;
- }
- if (node.jsDocComment) {
- node.jsDocComment = undefined;
- }
- node.pos += delta;
- node.end += delta;
- if (aggressiveChecks && shouldCheckNode(node)) {
- ts.Debug.assert(text === newText.substring(node.pos, node.end));
- }
- forEachChild(node, visitNode, visitArray);
- checkNodePositions(node, aggressiveChecks);
+ }
+ function checkStrictModeDeleteExpression(node) {
+ // Grammar checking
+ if (inStrictMode && node.expression.kind === 69 /* Identifier */) {
+ // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
+ // UnaryExpression is a direct reference to a variable, function argument, or function name
+ var span = ts.getErrorSpanForNode(file, node.expression);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
}
- function visitArray(array) {
- array._children = undefined;
- array.pos += delta;
- array.end += delta;
- for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
- var node = array_7[_i];
- visitNode(node);
+ }
+ function isEvalOrArgumentsIdentifier(node) {
+ return node.kind === 69 /* Identifier */ &&
+ (node.text === "eval" || node.text === "arguments");
+ }
+ function checkStrictModeEvalOrArguments(contextNode, name) {
+ if (name && name.kind === 69 /* Identifier */) {
+ var identifier = name;
+ if (isEvalOrArgumentsIdentifier(identifier)) {
+ // We check first if the name is inside class declaration or class expression; if so give explicit message
+ // otherwise report generic error message.
+ var span = ts.getErrorSpanForNode(file, name);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
}
}
}
- function shouldCheckNode(node) {
- switch (node.kind) {
- case 9 /* StringLiteral */:
- case 8 /* NumericLiteral */:
- case 69 /* Identifier */:
- return true;
+ function getStrictModeEvalOrArgumentsMessage(node) {
+ // Provide specialized messages to help the user understand why we think they're in
+ // strict mode.
+ if (ts.getContainingClass(node)) {
+ return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
}
- return false;
+ if (file.externalModuleIndicator) {
+ return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
+ }
+ return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
}
- function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
- ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
- ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
- ts.Debug.assert(element.pos <= element.end);
- // We have an element that intersects the change range in some way. It may have its
- // start, or its end (or both) in the changed range. We want to adjust any part
- // that intersects such that the final tree is in a consistent state. i.e. all
- // chlidren have spans within the span of their parent, and all siblings are ordered
- // properly.
- // We may need to update both the 'pos' and the 'end' of the element.
- // If the 'pos' is before the start of the change, then we don't need to touch it.
- // If it isn't, then the 'pos' must be inside the change. How we update it will
- // depend if delta is positive or negative. If delta is positive then we have
- // something like:
- //
- // -------------------AAA-----------------
- // -------------------BBBCCCCCCC-----------------
- //
- // In this case, we consider any node that started in the change range to still be
- // starting at the same position.
- //
- // however, if the delta is negative, then we instead have something like this:
- //
- // -------------------XXXYYYYYYY-----------------
- // -------------------ZZZ-----------------
- //
- // In this case, any element that started in the 'X' range will keep its position.
- // However any element htat started after that will have their pos adjusted to be
- // at the end of the new range. i.e. any node that started in the 'Y' range will
- // be adjusted to have their start at the end of the 'Z' range.
- //
- // The element will keep its position if possible. Or Move backward to the new-end
- // if it's in the 'Y' range.
- element.pos = Math.min(element.pos, changeRangeNewEnd);
- // If the 'end' is after the change range, then we always adjust it by the delta
- // amount. However, if the end is in the change range, then how we adjust it
- // will depend on if delta is positive or negative. If delta is positive then we
- // have something like:
- //
- // -------------------AAA-----------------
- // -------------------BBBCCCCCCC-----------------
- //
- // In this case, we consider any node that ended inside the change range to keep its
- // end position.
- //
- // however, if the delta is negative, then we instead have something like this:
- //
- // -------------------XXXYYYYYYY-----------------
- // -------------------ZZZ-----------------
- //
- // In this case, any element that ended in the 'X' range will keep its position.
- // However any element htat ended after that will have their pos adjusted to be
- // at the end of the new range. i.e. any node that ended in the 'Y' range will
- // be adjusted to have their end at the end of the 'Z' range.
- if (element.end >= changeRangeOldEnd) {
- // Element ends after the change range. Always adjust the end pos.
- element.end += delta;
+ function checkStrictModeFunctionName(node) {
+ if (inStrictMode) {
+ // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
+ checkStrictModeEvalOrArguments(node, node.name);
}
- else {
- // Element ends in the change range. The element will keep its position if
- // possible. Or Move backward to the new-end if it's in the 'Y' range.
- element.end = Math.min(element.end, changeRangeNewEnd);
+ }
+ function checkStrictModeNumericLiteral(node) {
+ if (inStrictMode && node.flags & 32768 /* OctalLiteral */) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
}
- ts.Debug.assert(element.pos <= element.end);
- if (element.parent) {
- ts.Debug.assert(element.pos >= element.parent.pos);
- ts.Debug.assert(element.end <= element.parent.end);
+ }
+ function checkStrictModePostfixUnaryExpression(node) {
+ // Grammar checking
+ // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
+ // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
+ // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
+ if (inStrictMode) {
+ checkStrictModeEvalOrArguments(node, node.operand);
}
}
- function checkNodePositions(node, aggressiveChecks) {
- if (aggressiveChecks) {
- var pos = node.pos;
- forEachChild(node, function (child) {
- ts.Debug.assert(child.pos >= pos);
- pos = child.end;
- });
- ts.Debug.assert(pos <= node.end);
+ function checkStrictModePrefixUnaryExpression(node) {
+ // Grammar checking
+ if (inStrictMode) {
+ if (node.operator === 41 /* PlusPlusToken */ || node.operator === 42 /* MinusMinusToken */) {
+ checkStrictModeEvalOrArguments(node, node.operand);
+ }
}
}
- function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
- visitNode(sourceFile);
- return;
- function visitNode(child) {
- ts.Debug.assert(child.pos <= child.end);
- if (child.pos > changeRangeOldEnd) {
- // Node is entirely past the change range. We need to move both its pos and
- // end, forward or backward appropriately.
- moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
+ function checkStrictModeWithStatement(node) {
+ // Grammar checking for withStatement
+ if (inStrictMode) {
+ errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
+ }
+ }
+ function errorOnFirstToken(node, message, arg0, arg1, arg2) {
+ var span = ts.getSpanOfTokenAtPosition(file, node.pos);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
+ }
+ function getDestructuringParameterName(node) {
+ return "__" + ts.indexOf(node.parent.parameters, node);
+ }
+ function bind(node) {
+ if (!node) {
+ return;
+ }
+ node.parent = parent;
+ var savedInStrictMode = inStrictMode;
+ if (!savedInStrictMode) {
+ updateStrictMode(node);
+ }
+ // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
+ // and then potentially add the symbol to an appropriate symbol table. Possible
+ // destination symbol tables are:
+ //
+ // 1) The 'exports' table of the current container's symbol.
+ // 2) The 'members' table of the current container's symbol.
+ // 3) The 'locals' table of the current container.
+ //
+ // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
+ // (like TypeLiterals for example) will not be put in any table.
+ bindWorker(node);
+ // Then we recurse into the children of the node to bind them as well. For certain
+ // symbols we do specialized work when we recurse. For example, we'll keep track of
+ // the current 'container' node when it changes. This helps us know which symbol table
+ // a local should go into for example.
+ bindChildren(node);
+ inStrictMode = savedInStrictMode;
+ }
+ function updateStrictMode(node) {
+ switch (node.kind) {
+ case 248 /* SourceFile */:
+ case 219 /* ModuleBlock */:
+ updateStrictModeStatementList(node.statements);
return;
- }
- // Check if the element intersects the change range. If it does, then it is not
- // reusable. Also, we'll need to recurse to see what constituent portions we may
- // be able to use.
- var fullEnd = child.end;
- if (fullEnd >= changeStart) {
- child.intersectsChange = true;
- child._children = undefined;
- // Adjust the pos or end (or both) of the intersecting element accordingly.
- adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
- forEachChild(child, visitNode, visitArray);
- checkNodePositions(child, aggressiveChecks);
+ case 192 /* Block */:
+ if (ts.isFunctionLike(node.parent)) {
+ updateStrictModeStatementList(node.statements);
+ }
+ return;
+ case 214 /* ClassDeclaration */:
+ case 186 /* ClassExpression */:
+ // All classes are automatically in strict mode in ES6.
+ inStrictMode = true;
return;
- }
- // Otherwise, the node is entirely before the change range. No need to do anything with it.
- ts.Debug.assert(fullEnd < changeStart);
}
- function visitArray(array) {
- ts.Debug.assert(array.pos <= array.end);
- if (array.pos > changeRangeOldEnd) {
- // Array is entirely after the change range. We need to move it, and move any of
- // its children.
- moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
+ }
+ function updateStrictModeStatementList(statements) {
+ for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
+ var statement = statements_1[_i];
+ if (!ts.isPrologueDirective(statement)) {
return;
}
- // Check if the element intersects the change range. If it does, then it is not
- // reusable. Also, we'll need to recurse to see what constituent portions we may
- // be able to use.
- var fullEnd = array.end;
- if (fullEnd >= changeStart) {
- array.intersectsChange = true;
- array._children = undefined;
- // Adjust the pos or end (or both) of the intersecting array accordingly.
- adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
- for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
- var node = array_8[_i];
- visitNode(node);
- }
+ if (isUseStrictPrologueDirective(statement)) {
+ inStrictMode = true;
return;
}
- // Otherwise, the array is entirely before the change range. No need to do anything with it.
- ts.Debug.assert(fullEnd < changeStart);
}
}
- function extendToAffectedRange(sourceFile, changeRange) {
- // Consider the following code:
- // void foo() { /; }
- //
- // If the text changes with an insertion of / just before the semicolon then we end up with:
- // void foo() { //; }
- //
- // If we were to just use the changeRange a is, then we would not rescan the { token
- // (as it does not intersect the actual original change range). Because an edit may
- // change the token touching it, we actually need to look back *at least* one token so
- // that the prior token sees that change.
- var maxLookahead = 1;
- var start = changeRange.span.start;
- // the first iteration aligns us with the change start. subsequent iteration move us to
- // the left by maxLookahead tokens. We only need to do this as long as we're not at the
- // start of the tree.
- for (var i = 0; start > 0 && i <= maxLookahead; i++) {
- var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
- ts.Debug.assert(nearestNode.pos <= start);
- var position = nearestNode.pos;
- start = Math.max(0, position - 1);
+ /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
+ function isUseStrictPrologueDirective(node) {
+ var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression);
+ // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
+ // string to contain unicode escapes (as per ES5).
+ return nodeText === "\"use strict\"" || nodeText === "'use strict'";
+ }
+ function bindWorker(node) {
+ switch (node.kind) {
+ /* Strict mode checks */
+ case 69 /* Identifier */:
+ return checkStrictModeIdentifier(node);
+ case 181 /* BinaryExpression */:
+ if (ts.isInJavaScriptFile(node)) {
+ if (ts.isExportsPropertyAssignment(node)) {
+ bindExportsPropertyAssignment(node);
+ }
+ else if (ts.isModuleExportsAssignment(node)) {
+ bindModuleExportsAssignment(node);
+ }
+ }
+ return checkStrictModeBinaryExpression(node);
+ case 244 /* CatchClause */:
+ return checkStrictModeCatchClause(node);
+ case 175 /* DeleteExpression */:
+ return checkStrictModeDeleteExpression(node);
+ case 8 /* NumericLiteral */:
+ return checkStrictModeNumericLiteral(node);
+ case 180 /* PostfixUnaryExpression */:
+ return checkStrictModePostfixUnaryExpression(node);
+ case 179 /* PrefixUnaryExpression */:
+ return checkStrictModePrefixUnaryExpression(node);
+ case 205 /* WithStatement */:
+ return checkStrictModeWithStatement(node);
+ case 97 /* ThisKeyword */:
+ seenThisKeyword = true;
+ return;
+ case 137 /* TypeParameter */:
+ return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */);
+ case 138 /* Parameter */:
+ return bindParameter(node);
+ case 211 /* VariableDeclaration */:
+ case 163 /* BindingElement */:
+ return bindVariableDeclarationOrBindingElement(node);
+ case 141 /* PropertyDeclaration */:
+ case 140 /* PropertySignature */:
+ return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 107455 /* PropertyExcludes */);
+ case 245 /* PropertyAssignment */:
+ case 246 /* ShorthandPropertyAssignment */:
+ return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */);
+ case 247 /* EnumMember */:
+ return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */);
+ case 147 /* CallSignature */:
+ case 148 /* ConstructSignature */:
+ case 149 /* IndexSignature */:
+ return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
+ case 143 /* MethodDeclaration */:
+ case 142 /* MethodSignature */:
+ // If this is an ObjectLiteralExpression method, then it sits in the same space
+ // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes
+ // so that it will conflict with any other object literal members with the same
+ // name.
+ return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */);
+ case 213 /* FunctionDeclaration */:
+ checkStrictModeFunctionName(node);
+ return declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */);
+ case 144 /* Constructor */:
+ return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
+ case 145 /* GetAccessor */:
+ return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */);
+ case 146 /* SetAccessor */:
+ return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */);
+ case 152 /* FunctionType */:
+ case 153 /* ConstructorType */:
+ return bindFunctionOrConstructorType(node);
+ case 155 /* TypeLiteral */:
+ return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type");
+ case 165 /* ObjectLiteralExpression */:
+ return bindObjectLiteralExpression(node);
+ case 173 /* FunctionExpression */:
+ case 174 /* ArrowFunction */:
+ checkStrictModeFunctionName(node);
+ var bindingName = node.name ? node.name.text : "__function";
+ return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
+ case 168 /* CallExpression */:
+ if (ts.isInJavaScriptFile(node)) {
+ bindCallExpression(node);
+ }
+ break;
+ // Members of classes, interfaces, and modules
+ case 186 /* ClassExpression */:
+ case 214 /* ClassDeclaration */:
+ return bindClassLikeDeclaration(node);
+ case 215 /* InterfaceDeclaration */:
+ return bindBlockScopedDeclaration(node, 64 /* Interface */, 792960 /* InterfaceExcludes */);
+ case 216 /* TypeAliasDeclaration */:
+ return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */);
+ case 217 /* EnumDeclaration */:
+ return bindEnumDeclaration(node);
+ case 218 /* ModuleDeclaration */:
+ return bindModuleDeclaration(node);
+ // Imports and exports
+ case 221 /* ImportEqualsDeclaration */:
+ case 224 /* NamespaceImport */:
+ case 226 /* ImportSpecifier */:
+ case 230 /* ExportSpecifier */:
+ return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
+ case 223 /* ImportClause */:
+ return bindImportClause(node);
+ case 228 /* ExportDeclaration */:
+ return bindExportDeclaration(node);
+ case 227 /* ExportAssignment */:
+ return bindExportAssignment(node);
+ case 248 /* SourceFile */:
+ return bindSourceFileIfExternalModule();
+ }
+ }
+ function bindSourceFileIfExternalModule() {
+ setExportContextFlag(file);
+ if (ts.isExternalModule(file)) {
+ bindSourceFileAsExternalModule();
+ }
+ }
+ function bindSourceFileAsExternalModule() {
+ bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
+ }
+ function bindExportAssignment(node) {
+ var boundExpression = node.kind === 227 /* ExportAssignment */ ? node.expression : node.right;
+ if (!container.symbol || !container.symbol.exports) {
+ // Export assignment in some sort of block construct
+ bindAnonymousDeclaration(node, 8388608 /* Alias */, getDeclarationName(node));
+ }
+ else if (boundExpression.kind === 69 /* Identifier */) {
+ // An export default clause with an identifier exports all meanings of that identifier
+ declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
+ }
+ else {
+ // An export default clause with an expression exports a value
+ declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
+ }
+ }
+ function bindExportDeclaration(node) {
+ if (!container.symbol || !container.symbol.exports) {
+ // Export * in some sort of block construct
+ bindAnonymousDeclaration(node, 1073741824 /* ExportStar */, getDeclarationName(node));
+ }
+ else if (!node.exportClause) {
+ // All export * declarations are collected in an __export symbol
+ declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0 /* None */);
}
- var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
- var finalLength = changeRange.newLength + (changeRange.span.start - start);
- return ts.createTextChangeRange(finalSpan, finalLength);
}
- function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
- var bestResult = sourceFile;
- var lastNodeEntirelyBeforePosition;
- forEachChild(sourceFile, visit);
- if (lastNodeEntirelyBeforePosition) {
- var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition);
- if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
- bestResult = lastChildOfLastEntireNodeBeforePosition;
+ function bindImportClause(node) {
+ if (node.name) {
+ declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
+ }
+ }
+ function setCommonJsModuleIndicator(node) {
+ if (!file.commonJsModuleIndicator) {
+ file.commonJsModuleIndicator = node;
+ bindSourceFileAsExternalModule();
+ }
+ }
+ function bindExportsPropertyAssignment(node) {
+ // When we create a property via 'exports.foo = bar', the 'exports.foo' property access
+ // expression is the declaration
+ setCommonJsModuleIndicator(node);
+ declareSymbol(file.symbol.exports, file.symbol, node.left, 4 /* Property */ | 7340032 /* Export */, 0 /* None */);
+ }
+ function bindModuleExportsAssignment(node) {
+ // 'module.exports = expr' assignment
+ setCommonJsModuleIndicator(node);
+ bindExportAssignment(node);
+ }
+ function bindCallExpression(node) {
+ // We're only inspecting call expressions to detect CommonJS modules, so we can skip
+ // this check if we've already seen the module indicator
+ if (!file.commonJsModuleIndicator && ts.isRequireCall(node)) {
+ setCommonJsModuleIndicator(node);
+ }
+ }
+ function bindClassLikeDeclaration(node) {
+ if (node.kind === 214 /* ClassDeclaration */) {
+ bindBlockScopedDeclaration(node, 32 /* Class */, 899519 /* ClassExcludes */);
+ }
+ else {
+ var bindingName = node.name ? node.name.text : "__class";
+ bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
+ // Add name of class expression into the map for semantic classifier
+ if (node.name) {
+ classifiableNames[node.name.text] = node.name.text;
}
}
- return bestResult;
- function getLastChild(node) {
- while (true) {
- var lastChild = getLastChildWorker(node);
- if (lastChild) {
- node = lastChild;
- }
- else {
- return node;
- }
+ var symbol = node.symbol;
+ // TypeScript 1.0 spec (April 2014): 8.4
+ // Every class automatically contains a static property member named 'prototype', the
+ // type of which is an instantiation of the class type with type Any supplied as a type
+ // argument for each type parameter. It is an error to explicitly declare a static
+ // property member with the name 'prototype'.
+ //
+ // Note: we check for this here because this class may be merging into a module. The
+ // module might have an exported variable called 'prototype'. We can't allow that as
+ // that would clash with the built-in 'prototype' for the class.
+ var prototypeSymbol = createSymbol(4 /* Property */ | 134217728 /* Prototype */, "prototype");
+ if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) {
+ if (node.name) {
+ node.name.parent = node;
}
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
}
- function getLastChildWorker(node) {
- var last = undefined;
- forEachChild(node, function (child) {
- if (ts.nodeIsPresent(child)) {
- last = child;
- }
- });
- return last;
+ symbol.exports[prototypeSymbol.name] = prototypeSymbol;
+ prototypeSymbol.parent = symbol;
+ }
+ function bindEnumDeclaration(node) {
+ return ts.isConst(node)
+ ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */)
+ : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */);
+ }
+ function bindVariableDeclarationOrBindingElement(node) {
+ if (inStrictMode) {
+ checkStrictModeEvalOrArguments(node, node.name);
}
- function visit(child) {
- if (ts.nodeIsMissing(child)) {
- // Missing nodes are effectively invisible to us. We never even consider them
- // When trying to find the nearest node before us.
- return;
+ if (!ts.isBindingPattern(node.name)) {
+ if (ts.isBlockOrCatchScoped(node)) {
+ bindBlockScopedVariableDeclaration(node);
}
- // If the child intersects this position, then this node is currently the nearest
- // node that starts before the position.
- if (child.pos <= position) {
- if (child.pos >= bestResult.pos) {
- // This node starts before the position, and is closer to the position than
- // the previous best node we found. It is now the new best node.
- bestResult = child;
- }
- // Now, the node may overlap the position, or it may end entirely before the
- // position. If it overlaps with the position, then either it, or one of its
- // children must be the nearest node before the position. So we can just
- // recurse into this child to see if we can find something better.
- if (position < child.end) {
- // The nearest node is either this child, or one of the children inside
- // of it. We've already marked this child as the best so far. Recurse
- // in case one of the children is better.
- forEachChild(child, visit);
- // Once we look at the children of this node, then there's no need to
- // continue any further.
- return true;
- }
- else {
- ts.Debug.assert(child.end <= position);
- // The child ends entirely before this position. Say you have the following
- // (where $ is the position)
- //
- // ? $ : <...> <...>
- //
- // We would want to find the nearest preceding node in "complex expr 2".
- // To support that, we keep track of this node, and once we're done searching
- // for a best node, we recurse down this node to see if we can find a good
- // result in it.
- //
- // This approach allows us to quickly skip over nodes that are entirely
- // before the position, while still allowing us to find any nodes in the
- // last one that might be what we want.
- lastNodeEntirelyBeforePosition = child;
- }
+ else if (ts.isParameterDeclaration(node)) {
+ // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
+ // because its parent chain has already been set up, since parents are set before descending into children.
+ //
+ // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
+ // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
+ // For example:
+ // function foo([a,a]) {} // Duplicate Identifier error
+ // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
+ // // which correctly set excluded symbols
+ declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
}
else {
- ts.Debug.assert(child.pos > position);
- // We're now at a node that is entirely past the position we're searching for.
- // This node (and all following nodes) could never contribute to the result,
- // so just skip them by returning 'true' here.
- return true;
+ declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */);
}
}
}
- function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
- var oldText = sourceFile.text;
- if (textChangeRange) {
- ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
- if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
- var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
- var newTextPrefix = newText.substr(0, textChangeRange.span.start);
- ts.Debug.assert(oldTextPrefix === newTextPrefix);
- var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
- var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
- ts.Debug.assert(oldTextSuffix === newTextSuffix);
- }
+ function bindParameter(node) {
+ if (inStrictMode) {
+ // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
+ // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
+ checkStrictModeEvalOrArguments(node, node.name);
+ }
+ if (ts.isBindingPattern(node.name)) {
+ bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, getDestructuringParameterName(node));
+ }
+ else {
+ declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
+ }
+ // If this is a property-parameter, then also declare the property symbol into the
+ // containing class.
+ if (node.flags & 56 /* AccessibilityModifier */ &&
+ node.parent.kind === 144 /* Constructor */ &&
+ ts.isClassLike(node.parent.parent)) {
+ var classDeclaration = node.parent.parent;
+ declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */);
}
}
- function createSyntaxCursor(sourceFile) {
- var currentArray = sourceFile.statements;
- var currentArrayIndex = 0;
- ts.Debug.assert(currentArrayIndex < currentArray.length);
- var current = currentArray[currentArrayIndex];
- var lastQueriedPosition = -1 /* Value */;
- return {
- currentNode: function (position) {
- // Only compute the current node if the position is different than the last time
- // we were asked. The parser commonly asks for the node at the same position
- // twice. Once to know if can read an appropriate list element at a certain point,
- // and then to actually read and consume the node.
- if (position !== lastQueriedPosition) {
- // Much of the time the parser will need the very next node in the array that
- // we just returned a node from.So just simply check for that case and move
- // forward in the array instead of searching for the node again.
- if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
- currentArrayIndex++;
- current = currentArray[currentArrayIndex];
- }
- // If we don't have a node, or the node we have isn't in the right position,
- // then try to find a viable node at the position requested.
- if (!current || current.pos !== position) {
- findHighestListElementThatStartsAtPosition(position);
- }
- }
- // Cache this query so that we don't do any extra work if the parser calls back
- // into us. Note: this is very common as the parser will make pairs of calls like
- // 'isListElement -> parseListElement'. If we were unable to find a node when
- // called with 'isListElement', we don't want to redo the work when parseListElement
- // is called immediately after.
- lastQueriedPosition = position;
- // Either we don'd have a node, or we have a node at the position being asked for.
- ts.Debug.assert(!current || current.pos === position);
- return current;
- }
- };
- // Finds the highest element in the tree we can find that starts at the provided position.
- // The element must be a direct child of some node list in the tree. This way after we
- // return it, we can easily return its next sibling in the list.
- function findHighestListElementThatStartsAtPosition(position) {
- // Clear out any cached state about the last node we found.
- currentArray = undefined;
- currentArrayIndex = -1 /* Value */;
- current = undefined;
- // Recurse into the source file to find the highest node at this position.
- forEachChild(sourceFile, visitNode, visitArray);
- return;
- function visitNode(node) {
- if (position >= node.pos && position < node.end) {
- // Position was within this node. Keep searching deeper to find the node.
- forEachChild(node, visitNode, visitArray);
- // don't procede any futher in the search.
- return true;
- }
- // position wasn't in this node, have to keep searching.
- return false;
+ function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
+ return ts.hasDynamicName(node)
+ ? bindAnonymousDeclaration(node, symbolFlags, "__computed")
+ : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
+ }
+ // reachability checks
+ function pushNamedLabel(name) {
+ initializeReachabilityStateIfNecessary();
+ if (ts.hasProperty(labelIndexMap, name.text)) {
+ return false;
+ }
+ labelIndexMap[name.text] = labelStack.push(1 /* Unintialized */) - 1;
+ return true;
+ }
+ function pushImplicitLabel() {
+ initializeReachabilityStateIfNecessary();
+ var index = labelStack.push(1 /* Unintialized */) - 1;
+ implicitLabels.push(index);
+ return index;
+ }
+ function popNamedLabel(label, outerState) {
+ var index = labelIndexMap[label.text];
+ ts.Debug.assert(index !== undefined);
+ ts.Debug.assert(labelStack.length == index + 1);
+ labelIndexMap[label.text] = undefined;
+ setCurrentStateAtLabel(labelStack.pop(), outerState, label);
+ }
+ function popImplicitLabel(implicitLabelIndex, outerState) {
+ if (labelStack.length !== implicitLabelIndex + 1) {
+ ts.Debug.assert(false, "Label stack: " + labelStack.length + ", index:" + implicitLabelIndex);
+ }
+ var i = implicitLabels.pop();
+ if (implicitLabelIndex !== i) {
+ ts.Debug.assert(false, "i: " + i + ", index: " + implicitLabelIndex);
+ }
+ setCurrentStateAtLabel(labelStack.pop(), outerState, /*name*/ undefined);
+ }
+ function setCurrentStateAtLabel(innerMergedState, outerState, label) {
+ if (innerMergedState === 1 /* Unintialized */) {
+ if (label && !options.allowUnusedLabels) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(label, ts.Diagnostics.Unused_label));
}
- function visitArray(array) {
- if (position >= array.pos && position < array.end) {
- // position was in this array. Search through this array to see if we find a
- // viable element.
- for (var i = 0, n = array.length; i < n; i++) {
- var child = array[i];
- if (child) {
- if (child.pos === position) {
- // Found the right node. We're done.
- currentArray = array;
- currentArrayIndex = i;
- current = child;
- return true;
- }
- else {
- if (child.pos < position && position < child.end) {
- // Position in somewhere within this child. Search in it and
- // stop searching in this array.
- forEachChild(child, visitNode, visitArray);
- return true;
- }
- }
- }
+ currentReachabilityState = outerState;
+ }
+ else {
+ currentReachabilityState = or(innerMergedState, outerState);
+ }
+ }
+ function jumpToLabel(label, outerState) {
+ initializeReachabilityStateIfNecessary();
+ var index = label ? labelIndexMap[label.text] : ts.lastOrUndefined(implicitLabels);
+ if (index === undefined) {
+ // reference to unknown label or
+ // break/continue used outside of loops
+ return false;
+ }
+ var stateAtLabel = labelStack[index];
+ labelStack[index] = stateAtLabel === 1 /* Unintialized */ ? outerState : or(stateAtLabel, outerState);
+ return true;
+ }
+ function checkUnreachable(node) {
+ switch (currentReachabilityState) {
+ case 4 /* Unreachable */:
+ var reportError =
+ // report error on all statements except empty ones
+ (ts.isStatement(node) && node.kind !== 194 /* EmptyStatement */) ||
+ // report error on class declarations
+ node.kind === 214 /* ClassDeclaration */ ||
+ // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
+ (node.kind === 218 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node)) ||
+ // report error on regular enums and const enums if preserveConstEnums is set
+ (node.kind === 217 /* EnumDeclaration */ && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
+ if (reportError) {
+ currentReachabilityState = 8 /* ReportedUnreachable */;
+ // unreachable code is reported if
+ // - user has explicitly asked about it AND
+ // - statement is in not ambient context (statements in ambient context is already an error
+ // so we should not report extras) AND
+ // - node is not variable statement OR
+ // - node is block scoped variable statement OR
+ // - node is not block scoped variable statement and at least one variable declaration has initializer
+ // Rationale: we don't want to report errors on non-initialized var's since they are hoisted
+ // On the other side we do want to report errors on non-initialized 'lets' because of TDZ
+ var reportUnreachableCode = !options.allowUnreachableCode &&
+ !ts.isInAmbientContext(node) &&
+ (node.kind !== 193 /* VariableStatement */ ||
+ ts.getCombinedNodeFlags(node.declarationList) & 24576 /* BlockScoped */ ||
+ ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
+ if (reportUnreachableCode) {
+ errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
}
}
- // position wasn't in this array, have to keep searching.
+ case 8 /* ReportedUnreachable */:
+ return true;
+ default:
return false;
- }
+ }
+ function shouldReportErrorOnModuleDeclaration(node) {
+ var instanceState = getModuleInstanceState(node);
+ return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && options.preserveConstEnums);
}
}
- var InvalidPosition;
- (function (InvalidPosition) {
- InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
- })(InvalidPosition || (InvalidPosition = {}));
- })(IncrementalParser || (IncrementalParser = {}));
+ function initializeReachabilityStateIfNecessary() {
+ if (labelIndexMap) {
+ return;
+ }
+ currentReachabilityState = 2 /* Reachable */;
+ labelIndexMap = {};
+ labelStack = [];
+ implicitLabels = [];
+ }
+ }
})(ts || (ts = {}));
///
/* @internal */
@@ -13755,7 +13918,7 @@ var ts;
symbolToString: symbolToString,
getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
getRootSymbols: getRootSymbols,
- getContextualType: getContextualType,
+ getContextualType: getApparentTypeOfContextualType,
getFullyQualifiedName: getFullyQualifiedName,
getResolvedSignature: getResolvedSignature,
getConstantValue: getConstantValue,
@@ -14025,7 +14188,7 @@ var ts;
return ts.getAncestor(node, 248 /* SourceFile */);
}
function isGlobalSourceFile(node) {
- return node.kind === 248 /* SourceFile */ && !ts.isExternalModule(node);
+ return node.kind === 248 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node);
}
function getSymbol(symbols, name, meaning) {
if (meaning && ts.hasProperty(symbols, name)) {
@@ -14127,15 +14290,24 @@ var ts;
}
switch (location.kind) {
case 248 /* SourceFile */:
- if (!ts.isExternalModule(location))
+ if (!ts.isExternalOrCommonJsModule(location))
break;
case 218 /* ModuleDeclaration */:
var moduleExports = getSymbolOfNode(location).exports;
if (location.kind === 248 /* SourceFile */ ||
(location.kind === 218 /* ModuleDeclaration */ && location.name.kind === 9 /* StringLiteral */)) {
- // It's an external module. Because of module/namespace merging, a module's exports are in scope,
- // yet we never want to treat an export specifier as putting a member in scope. Therefore,
- // if the name we find is purely an export specifier, it is not actually considered in scope.
+ // It's an external module. First see if the module has an export default and if the local
+ // name of that export default matches.
+ if (result = moduleExports["default"]) {
+ var localSymbol = ts.getLocalSymbolForExportDefault(result);
+ if (localSymbol && (result.flags & meaning) && localSymbol.name === name) {
+ break loop;
+ }
+ result = undefined;
+ }
+ // Because of module/namespace merging, a module's exports are in scope,
+ // yet we never want to treat an export specifier as putting a member in scope.
+ // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
// Two things to note about this:
// 1. We have to check this without calling getSymbol. The problem with calling getSymbol
// on an export specifier is that it might find the export specifier itself, and try to
@@ -14149,12 +14321,6 @@ var ts;
ts.getDeclarationOfKind(moduleExports[name], 230 /* ExportSpecifier */)) {
break;
}
- result = moduleExports["default"];
- var localSymbol = ts.getLocalSymbolForExportDefault(result);
- if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
- break loop;
- }
- result = undefined;
}
if (result = getSymbol(moduleExports, name, meaning & 8914931 /* ModuleMember */)) {
break loop;
@@ -14297,7 +14463,7 @@ var ts;
// declare module foo {
// interface bar {}
// }
- // let foo/*1*/: foo/*2*/.bar;
+ // const foo/*1*/: foo/*2*/.bar;
// The foo at /*1*/ and /*2*/ will share same symbol with two meaning
// block - scope variable and namespace module. However, only when we
// try to resolve name in /*1*/ which is used in variable position,
@@ -14601,6 +14767,9 @@ var ts;
if (moduleName === undefined) {
return;
}
+ if (moduleName.indexOf("!") >= 0) {
+ moduleName = moduleName.substr(0, moduleName.indexOf("!"));
+ }
var isRelative = ts.isExternalModuleNameRelative(moduleName);
if (!isRelative) {
var symbol = getSymbol(globals, "\"" + moduleName + "\"", 512 /* ValueModule */);
@@ -14788,7 +14957,7 @@ var ts;
}
switch (location_1.kind) {
case 248 /* SourceFile */:
- if (!ts.isExternalModule(location_1)) {
+ if (!ts.isExternalOrCommonJsModule(location_1)) {
break;
}
case 218 /* ModuleDeclaration */:
@@ -14910,7 +15079,7 @@ var ts;
// export class c {
// }
// }
- // let x: typeof m.c
+ // const x: typeof m.c
// In the above example when we start with checking if typeof m.c symbol is accessible,
// we are going to see if c can be accessed in scope directly.
// But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
@@ -14949,7 +15118,7 @@ var ts;
}
function hasExternalModuleSymbol(declaration) {
return (declaration.kind === 218 /* ModuleDeclaration */ && declaration.name.kind === 9 /* StringLiteral */) ||
- (declaration.kind === 248 /* SourceFile */ && ts.isExternalModule(declaration));
+ (declaration.kind === 248 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
}
function hasVisibleDeclarations(symbol) {
var aliasesToMakeVisible;
@@ -15100,7 +15269,7 @@ var ts;
parentSymbol = symbol;
appendSymbolNameOnly(symbol, writer);
}
- // Let the writer know we just wrote out a symbol. The declaration emitter writer uses
+ // const the writer know we just wrote out a symbol. The declaration emitter writer uses
// this to determine if an import it has previously seen (and not written out) needs
// to be written to the file once the walk of the tree is complete.
//
@@ -15181,7 +15350,7 @@ var ts;
writeAnonymousType(type, flags);
}
else if (type.flags & 256 /* StringLiteral */) {
- writer.writeStringLiteral(type.text);
+ writer.writeStringLiteral("\"" + ts.escapeString(type.text) + "\"");
}
else {
// Should never get here
@@ -15568,7 +15737,7 @@ var ts;
}
}
else if (node.kind === 248 /* SourceFile */) {
- return ts.isExternalModule(node) ? node : undefined;
+ return ts.isExternalOrCommonJsModule(node) ? node : undefined;
}
}
ts.Debug.fail("getContainingModule cant reach here");
@@ -15650,7 +15819,7 @@ var ts;
// Private/protected properties/methods are not visible
return false;
}
- // Public properties/methods are visible if its parents are visible, so let it fall into next case statement
+ // Public properties/methods are visible if its parents are visible, so const it fall into next case statement
case 144 /* Constructor */:
case 148 /* ConstructSignature */:
case 147 /* CallSignature */:
@@ -15678,7 +15847,7 @@ var ts;
// Source file is always visible
case 248 /* SourceFile */:
return true;
- // Export assignements do not create name bindings outside the module
+ // Export assignments do not create name bindings outside the module
case 227 /* ExportAssignment */:
return false;
default:
@@ -15814,6 +15983,23 @@ var ts;
var symbol = getSymbolOfNode(node);
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
}
+ function getTextOfPropertyName(name) {
+ switch (name.kind) {
+ case 69 /* Identifier */:
+ return name.text;
+ case 9 /* StringLiteral */:
+ case 8 /* NumericLiteral */:
+ return name.text;
+ case 136 /* ComputedPropertyName */:
+ if (ts.isStringOrNumericLiteral(name.expression.kind)) {
+ return name.expression.text;
+ }
+ }
+ return undefined;
+ }
+ function isComputedNonLiteralName(name) {
+ return name.kind === 136 /* ComputedPropertyName */ && !ts.isStringOrNumericLiteral(name.expression.kind);
+ }
// Return the inferred type for a binding element
function getTypeForBindingElement(declaration) {
var pattern = declaration.parent;
@@ -15835,10 +16021,15 @@ var ts;
if (pattern.kind === 161 /* ObjectBindingPattern */) {
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
var name_10 = declaration.propertyName || declaration.name;
+ if (isComputedNonLiteralName(name_10)) {
+ // computed properties with non-literal names are treated as 'any'
+ return anyType;
+ }
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
// or otherwise the type of the string index signature.
- type = getTypeOfPropertyOfType(parentType, name_10.text) ||
- isNumericLiteralName(name_10.text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
+ var text = getTextOfPropertyName(name_10);
+ type = getTypeOfPropertyOfType(parentType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
getIndexTypeOfType(parentType, 0 /* String */);
if (!type) {
error(name_10, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_10));
@@ -15938,10 +16129,17 @@ var ts;
// Return the type implied by an object binding pattern
function getTypeFromObjectBindingPattern(pattern, includePatternInType) {
var members = {};
+ var hasComputedProperties = false;
ts.forEach(pattern.elements, function (e) {
- var flags = 4 /* Property */ | 67108864 /* Transient */ | (e.initializer ? 536870912 /* Optional */ : 0);
var name = e.propertyName || e.name;
- var symbol = createSymbol(flags, name.text);
+ if (isComputedNonLiteralName(name)) {
+ // do not include computed properties in the implied type
+ hasComputedProperties = true;
+ return;
+ }
+ var text = getTextOfPropertyName(name);
+ var flags = 4 /* Property */ | 67108864 /* Transient */ | (e.initializer ? 536870912 /* Optional */ : 0);
+ var symbol = createSymbol(flags, text);
symbol.type = getTypeFromBindingElement(e, includePatternInType);
symbol.bindingElement = e;
members[symbol.name] = symbol;
@@ -15950,6 +16148,9 @@ var ts;
if (includePatternInType) {
result.pattern = pattern;
}
+ if (hasComputedProperties) {
+ result.flags |= 67108864 /* ObjectLiteralPatternWithComputedProperties */;
+ }
return result;
}
// Return the type implied by an array binding pattern
@@ -16026,6 +16227,14 @@ var ts;
if (declaration.kind === 227 /* ExportAssignment */) {
return links.type = checkExpression(declaration.expression);
}
+ // Handle module.exports = expr
+ if (declaration.kind === 181 /* BinaryExpression */) {
+ return links.type = checkExpression(declaration.right);
+ }
+ // Handle exports.p = expr
+ if (declaration.kind === 166 /* PropertyAccessExpression */) {
+ return checkExpressionCached(declaration.parent.right);
+ }
// Handle variable, parameter or property
if (!pushTypeResolution(symbol, 0 /* Type */)) {
return unknownType;
@@ -16304,23 +16513,25 @@ var ts;
}
function resolveBaseTypesOfClass(type) {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
- var baseContructorType = getBaseConstructorTypeOfClass(type);
- if (!(baseContructorType.flags & 80896 /* ObjectType */)) {
+ var baseConstructorType = getBaseConstructorTypeOfClass(type);
+ if (!(baseConstructorType.flags & 80896 /* ObjectType */)) {
return;
}
var baseTypeNode = getBaseTypeNodeOfClass(type);
var baseType;
- if (baseContructorType.symbol && baseContructorType.symbol.flags & 32 /* Class */) {
- // When base constructor type is a class we know that the constructors all have the same type parameters as the
+ var originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
+ if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 /* Class */ &&
+ areAllOuterTypeParametersApplied(originalBaseType)) {
+ // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
// class and all return the instance type of the class. There is no need for further checks and we can apply the
// type arguments in the same manner as a type reference to get the same error reporting experience.
- baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseContructorType.symbol);
+ baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
}
else {
// The class derives from a "class-like" constructor function, check that we have at least one construct signature
// with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
// we check that all instantiated signatures return the same type.
- var constructors = getInstantiatedConstructorsForTypeArguments(baseContructorType, baseTypeNode.typeArguments);
+ var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments);
if (!constructors.length) {
error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
return;
@@ -16345,6 +16556,17 @@ var ts;
type.resolvedBaseTypes.push(baseType);
}
}
+ function areAllOuterTypeParametersApplied(type) {
+ // An unapplied type parameter has its symbol still the same as the matching argument symbol.
+ // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
+ var outerTypeParameters = type.outerTypeParameters;
+ if (outerTypeParameters) {
+ var last = outerTypeParameters.length - 1;
+ var typeArguments = type.typeArguments;
+ return outerTypeParameters[last].symbol !== typeArguments[last].symbol;
+ }
+ return true;
+ }
function resolveBaseTypesOfInterface(type) {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
@@ -16424,7 +16646,7 @@ var ts;
type.typeArguments = type.typeParameters;
type.thisType = createType(512 /* TypeParameter */ | 33554432 /* ThisType */);
type.thisType.symbol = symbol;
- type.thisType.constraint = getTypeWithThisArgument(type);
+ type.thisType.constraint = type;
}
}
return links.declaredType;
@@ -16939,6 +17161,20 @@ var ts;
type = getApparentType(type);
return type.flags & 49152 /* UnionOrIntersection */ ? getPropertiesOfUnionOrIntersectionType(type) : getPropertiesOfObjectType(type);
}
+ /**
+ * The apparent type of a type parameter is the base constraint instantiated with the type parameter
+ * as the type argument for the 'this' type.
+ */
+ function getApparentTypeOfTypeParameter(type) {
+ if (!type.resolvedApparentType) {
+ var constraintType = getConstraintOfTypeParameter(type);
+ while (constraintType && constraintType.flags & 512 /* TypeParameter */) {
+ constraintType = getConstraintOfTypeParameter(constraintType);
+ }
+ type.resolvedApparentType = getTypeWithThisArgument(constraintType || emptyObjectType, type);
+ }
+ return type.resolvedApparentType;
+ }
/**
* For a type parameter, return the base constraint of the type parameter. For the string, number,
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
@@ -16946,12 +17182,7 @@ var ts;
*/
function getApparentType(type) {
if (type.flags & 512 /* TypeParameter */) {
- do {
- type = getConstraintOfTypeParameter(type);
- } while (type && type.flags & 512 /* TypeParameter */);
- if (!type) {
- type = emptyObjectType;
- }
+ type = getApparentTypeOfTypeParameter(type);
}
if (type.flags & 258 /* StringLike */) {
type = globalStringType;
@@ -17116,7 +17347,7 @@ var ts;
if (node.initializer) {
var signatureDeclaration = node.parent;
var signature = getSignatureFromDeclaration(signatureDeclaration);
- var parameterIndex = signatureDeclaration.parameters.indexOf(node);
+ var parameterIndex = ts.indexOf(signatureDeclaration.parameters, node);
ts.Debug.assert(parameterIndex >= 0);
return parameterIndex >= signature.minArgumentCount;
}
@@ -17217,6 +17448,16 @@ var ts;
}
return result;
}
+ function resolveExternalModuleTypeByLiteral(name) {
+ var moduleSym = resolveExternalModuleName(name, name);
+ if (moduleSym) {
+ var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
+ if (resolvedModuleSymbol) {
+ return getTypeOfSymbol(resolvedModuleSymbol);
+ }
+ }
+ return anyType;
+ }
function getReturnTypeOfSignature(signature) {
if (!signature.resolvedReturnType) {
if (!pushTypeResolution(signature, 3 /* ResolvedReturnType */)) {
@@ -17740,11 +17981,12 @@ var ts;
return links.resolvedType;
}
function getStringLiteralType(node) {
- if (ts.hasProperty(stringLiteralTypes, node.text)) {
- return stringLiteralTypes[node.text];
+ var text = node.text;
+ if (ts.hasProperty(stringLiteralTypes, text)) {
+ return stringLiteralTypes[text];
}
- var type = stringLiteralTypes[node.text] = createType(256 /* StringLiteral */);
- type.text = ts.getTextOfNode(node);
+ var type = stringLiteralTypes[text] = createType(256 /* StringLiteral */);
+ type.text = text;
return type;
}
function getTypeFromStringLiteral(node) {
@@ -18265,7 +18507,7 @@ var ts;
return false;
}
function hasExcessProperties(source, target, reportErrors) {
- if (someConstituentTypeHasKind(target, 80896 /* ObjectType */)) {
+ if (!(target.flags & 67108864 /* ObjectLiteralPatternWithComputedProperties */) && someConstituentTypeHasKind(target, 80896 /* ObjectType */)) {
for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
var prop = _a[_i];
if (!isKnownProperty(target, prop.name)) {
@@ -18358,9 +18600,6 @@ var ts;
return result;
}
function typeParameterIdenticalTo(source, target) {
- if (source.symbol.name !== target.symbol.name) {
- return 0 /* False */;
- }
// covers case when both type parameters does not have constraint (both equal to noConstraintType)
if (source.constraint === target.constraint) {
return -1 /* True */;
@@ -18852,18 +19091,29 @@ var ts;
}
return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
}
+ function isMatchingSignature(source, target, partialMatch) {
+ // A source signature matches a target signature if the two signatures have the same number of required,
+ // optional, and rest parameters.
+ if (source.parameters.length === target.parameters.length &&
+ source.minArgumentCount === target.minArgumentCount &&
+ source.hasRestParameter === target.hasRestParameter) {
+ return true;
+ }
+ // A source signature partially matches a target signature if the target signature has no fewer required
+ // parameters and no more overall parameters than the source signature (where a signature with a rest
+ // parameter is always considered to have more overall parameters than one without).
+ if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (source.hasRestParameter && !target.hasRestParameter ||
+ source.hasRestParameter === target.hasRestParameter && source.parameters.length >= target.parameters.length)) {
+ return true;
+ }
+ return false;
+ }
function compareSignatures(source, target, partialMatch, ignoreReturnTypes, compareTypes) {
if (source === target) {
return -1 /* True */;
}
- if (source.parameters.length !== target.parameters.length ||
- source.minArgumentCount !== target.minArgumentCount ||
- source.hasRestParameter !== target.hasRestParameter) {
- if (!partialMatch ||
- source.parameters.length < target.parameters.length && !source.hasRestParameter ||
- source.minArgumentCount > target.minArgumentCount) {
- return 0 /* False */;
- }
+ if (!(isMatchingSignature(source, target, partialMatch))) {
+ return 0 /* False */;
}
var result = -1 /* True */;
if (source.typeParameters && target.typeParameters) {
@@ -18957,6 +19207,9 @@ var ts;
function isTupleLikeType(type) {
return !!getPropertyOfType(type, "0");
}
+ function isStringLiteralType(type) {
+ return type.flags & 256 /* StringLiteral */;
+ }
/**
* Check if a Type was written as a tuple type literal.
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
@@ -19629,7 +19882,7 @@ var ts;
}
function narrowTypeByInstanceof(type, expr, assumeTrue) {
// Check that type is not any, assumed result is true, and we have variable symbol on the left
- if (isTypeAny(type) || !assumeTrue || expr.left.kind !== 69 /* Identifier */ || getResolvedSymbol(expr.left) !== symbol) {
+ if (isTypeAny(type) || expr.left.kind !== 69 /* Identifier */ || getResolvedSymbol(expr.left) !== symbol) {
return type;
}
// Check that right operand is a function type with a prototype property
@@ -19660,6 +19913,12 @@ var ts;
}
}
if (targetType) {
+ if (!assumeTrue) {
+ if (type.flags & 16384 /* Union */) {
+ return getUnionType(ts.filter(type.types, function (t) { return !isTypeSubtypeOf(t, targetType); }));
+ }
+ return type;
+ }
return getNarrowedType(type, targetType);
}
return type;
@@ -20129,6 +20388,9 @@ var ts;
function getIndexTypeOfContextualType(type, kind) {
return applyToContextualType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); });
}
+ function contextualTypeIsStringLiteralType(type) {
+ return !!(type.flags & 16384 /* Union */ ? ts.forEach(type.types, isStringLiteralType) : isStringLiteralType(type));
+ }
// Return true if the given contextual type is a tuple-like type
function contextualTypeIsTupleLikeType(type) {
return !!(type.flags & 16384 /* Union */ ? ts.forEach(type.types, isTupleLikeType) : isTupleLikeType(type));
@@ -20150,7 +20412,7 @@ var ts;
}
function getContextualTypeForObjectLiteralElement(element) {
var objectLiteral = element.parent;
- var type = getContextualType(objectLiteral);
+ var type = getApparentTypeOfContextualType(objectLiteral);
if (type) {
if (!ts.hasDynamicName(element)) {
// For a (non-symbol) computed property, there is no reason to look up the name
@@ -20173,7 +20435,7 @@ var ts;
// type of T.
function getContextualTypeForElementExpression(node) {
var arrayLiteral = node.parent;
- var type = getContextualType(arrayLiteral);
+ var type = getApparentTypeOfContextualType(arrayLiteral);
if (type) {
var index = ts.indexOf(arrayLiteral.elements, node);
return getTypeOfPropertyOfContextualType(type, "" + index)
@@ -20206,11 +20468,28 @@ var ts;
}
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
- function getContextualType(node) {
- var type = getContextualTypeWorker(node);
+ function getApparentTypeOfContextualType(node) {
+ var type = getContextualType(node);
return type && getApparentType(type);
}
- function getContextualTypeWorker(node) {
+ /**
+ * Woah! Do you really want to use this function?
+ *
+ * Unless you're trying to get the *non-apparent* type for a
+ * value-literal type or you're authoring relevant portions of this algorithm,
+ * you probably meant to use 'getApparentTypeOfContextualType'.
+ * Otherwise this may not be very useful.
+ *
+ * In cases where you *are* working on this function, you should understand
+ * when it is appropriate to use 'getContextualType' and 'getApparentTypeOfContetxualType'.
+ *
+ * - Use 'getContextualType' when you are simply going to propagate the result to the expression.
+ * - Use 'getApparentTypeOfContextualType' when you're going to need the members of the type.
+ *
+ * @param node the expression whose contextual type will be returned.
+ * @returns the contextual type of an expression.
+ */
+ function getContextualType(node) {
if (isInsideWithStatementBody(node)) {
// We cannot answer semantic questions within a with block, do not proceed any further
return undefined;
@@ -20285,7 +20564,7 @@ var ts;
ts.Debug.assert(node.kind !== 143 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
var type = ts.isObjectLiteralMethod(node)
? getContextualTypeForObjectLiteralMethod(node)
- : getContextualType(node);
+ : getApparentTypeOfContextualType(node);
if (!type) {
return undefined;
}
@@ -20411,7 +20690,7 @@ var ts;
type.pattern = node;
return type;
}
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
var pattern = contextualType.pattern;
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
@@ -20494,10 +20773,11 @@ var ts;
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
var propertiesTable = {};
var propertiesArray = [];
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
var contextualTypeHasPattern = contextualType && contextualType.pattern &&
(contextualType.pattern.kind === 161 /* ObjectBindingPattern */ || contextualType.pattern.kind === 165 /* ObjectLiteralExpression */);
var typeFlags = 0;
+ var patternWithComputedProperties = false;
for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
var memberDecl = _a[_i];
var member = memberDecl.symbol;
@@ -20525,8 +20805,11 @@ var ts;
if (isOptional) {
prop.flags |= 536870912 /* Optional */;
}
+ if (ts.hasDynamicName(memberDecl)) {
+ patternWithComputedProperties = true;
+ }
}
- else if (contextualTypeHasPattern) {
+ else if (contextualTypeHasPattern && !(contextualType.flags & 67108864 /* ObjectLiteralPatternWithComputedProperties */)) {
// If object literal is contextually typed by the implied type of a binding pattern, and if the
// binding pattern specifies a default value for the property, make the property optional.
var impliedProp = getPropertyOfType(contextualType, member.name);
@@ -20578,7 +20861,7 @@ var ts;
var numberIndexType = getIndexType(1 /* Number */);
var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576 /* FreshObjectLiteral */;
- result.flags |= 524288 /* ObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */);
+ result.flags |= 524288 /* ObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */) | (patternWithComputedProperties ? 67108864 /* ObjectLiteralPatternWithComputedProperties */ : 0);
if (inDestructuringPattern) {
result.pattern = node;
}
@@ -21289,7 +21572,7 @@ var ts;
// so order how inherited signatures are processed is still preserved.
// interface A { (x: string): void }
// interface B extends A { (x: 'foo'): string }
- // let b: B;
+ // const b: B;
// b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
function reorderCandidates(signatures, result) {
var lastParent;
@@ -22247,6 +22530,10 @@ var ts;
return anyType;
}
}
+ // In JavaScript files, calls to any identifier 'require' are treated as external module imports
+ if (ts.isInJavaScriptFile(node) && ts.isRequireCall(node)) {
+ return resolveExternalModuleTypeByLiteral(node.arguments[0]);
+ }
return getReturnTypeOfSignature(signature);
}
function checkTaggedTemplateExpression(node) {
@@ -22257,7 +22544,10 @@ var ts;
var targetType = getTypeFromTypeNode(node.type);
if (produceDiagnostics && targetType !== unknownType) {
var widenedType = getWidenedType(exprType);
- if (!(isTypeAssignableTo(targetType, widenedType))) {
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ var bothAreStringLike = someConstituentTypeHasKind(targetType, 258 /* StringLike */) &&
+ someConstituentTypeHasKind(widenedType, 258 /* StringLike */);
+ if (!bothAreStringLike && !(isTypeAssignableTo(targetType, widenedType))) {
checkTypeAssignableTo(exprType, targetType, node, ts.Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
}
}
@@ -22801,19 +23091,26 @@ var ts;
for (var _i = 0, properties_3 = properties; _i < properties_3.length; _i++) {
var p = properties_3[_i];
if (p.kind === 245 /* PropertyAssignment */ || p.kind === 246 /* ShorthandPropertyAssignment */) {
- // TODO(andersh): Computed property support
var name_13 = p.name;
+ if (name_13.kind === 136 /* ComputedPropertyName */) {
+ checkComputedPropertyName(name_13);
+ }
+ if (isComputedNonLiteralName(name_13)) {
+ continue;
+ }
+ var text = getTextOfPropertyName(name_13);
var type = isTypeAny(sourceType)
? sourceType
- : getTypeOfPropertyOfType(sourceType, name_13.text) ||
- isNumericLiteralName(name_13.text) && getIndexTypeOfType(sourceType, 1 /* Number */) ||
+ : getTypeOfPropertyOfType(sourceType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(sourceType, 1 /* Number */) ||
getIndexTypeOfType(sourceType, 0 /* String */);
if (type) {
if (p.kind === 246 /* ShorthandPropertyAssignment */) {
checkDestructuringAssignment(p, type);
}
else {
- checkDestructuringAssignment(p.initializer || name_13, type);
+ // non-shorthand property assignments should always have initializers
+ checkDestructuringAssignment(p.initializer, type);
}
}
else {
@@ -23014,6 +23311,10 @@ var ts;
case 31 /* ExclamationEqualsToken */:
case 32 /* EqualsEqualsEqualsToken */:
case 33 /* ExclamationEqualsEqualsToken */:
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ if (someConstituentTypeHasKind(leftType, 258 /* StringLike */) && someConstituentTypeHasKind(rightType, 258 /* StringLike */)) {
+ return booleanType;
+ }
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
reportOperatorError();
}
@@ -23137,6 +23438,13 @@ var ts;
var type2 = checkExpression(node.whenFalse, contextualMapper);
return getUnionType([type1, type2]);
}
+ function checkStringLiteralExpression(node) {
+ var contextualType = getContextualType(node);
+ if (contextualType && contextualTypeIsStringLiteralType(contextualType)) {
+ return getStringLiteralType(node);
+ }
+ return stringType;
+ }
function checkTemplateExpression(node) {
// We just want to check each expressions, but we are unconcerned with
// the type of each expression, as any value may be coerced into a string.
@@ -23187,7 +23495,7 @@ var ts;
if (isInferentialContext(contextualMapper)) {
var signature = getSingleCallSignature(type);
if (signature && signature.typeParameters) {
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
if (contextualType) {
var contextualSignature = getSingleCallSignature(contextualType);
if (contextualSignature && !contextualSignature.typeParameters) {
@@ -23251,6 +23559,7 @@ var ts;
case 183 /* TemplateExpression */:
return checkTemplateExpression(node);
case 9 /* StringLiteral */:
+ return checkStringLiteralExpression(node);
case 11 /* NoSubstitutionTemplateLiteral */:
return stringType;
case 10 /* RegularExpressionLiteral */:
@@ -24580,7 +24889,7 @@ var ts;
}
// In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
var parent = getDeclarationContainer(node);
- if (parent.kind === 248 /* SourceFile */ && ts.isExternalModule(parent)) {
+ if (parent.kind === 248 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent)) {
// If the declaration happens to be in external module, report error that require and exports are reserved keywords
error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
}
@@ -24598,15 +24907,15 @@ var ts;
// A non-initialized declaration is a no-op as the block declaration will resolve before the var
// declaration. the problem is if the declaration has an initializer. this will act as a write to the
// block declared value. this is fine for let, but not const.
- // Only consider declarations with initializers, uninitialized let declarations will not
+ // Only consider declarations with initializers, uninitialized const declarations will not
// step on a let/const variable.
- // Do not consider let and const declarations, as duplicate block-scoped declarations
+ // Do not consider const and const declarations, as duplicate block-scoped declarations
// are handled by the binder.
- // We are only looking for let declarations that step on let\const declarations from a
+ // We are only looking for const declarations that step on let\const declarations from a
// different scope. e.g.:
// {
// const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
- // let x = 0; // symbol for this declaration will be 'symbol'
+ // const x = 0; // symbol for this declaration will be 'symbol'
// }
// skip block-scoped variables and parameters
if ((ts.getCombinedNodeFlags(node) & 24576 /* BlockScoped */) !== 0 || ts.isParameterDeclaration(node)) {
@@ -24693,6 +25002,12 @@ var ts;
checkExpressionCached(node.initializer);
}
}
+ if (node.kind === 163 /* BindingElement */) {
+ // check computed properties inside property names of binding elements
+ if (node.propertyName && node.propertyName.kind === 136 /* ComputedPropertyName */) {
+ checkComputedPropertyName(node.propertyName);
+ }
+ }
// For a binding pattern, check contained binding elements
if (ts.isBindingPattern(node.name)) {
ts.forEach(node.name.elements, checkSourceElement);
@@ -25176,6 +25491,7 @@ var ts;
var firstDefaultClause;
var hasDuplicateDefaultClause = false;
var expressionType = checkExpression(node.expression);
+ var expressionTypeIsStringLike = someConstituentTypeHasKind(expressionType, 258 /* StringLike */);
ts.forEach(node.caseBlock.clauses, function (clause) {
// Grammar check for duplicate default clauses, skip if we already report duplicate default clause
if (clause.kind === 242 /* DefaultClause */ && !hasDuplicateDefaultClause) {
@@ -25195,6 +25511,10 @@ var ts;
// TypeScript 1.0 spec (April 2014):5.9
// In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression.
var caseType = checkExpression(caseClause.expression);
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ if (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, 258 /* StringLike */)) {
+ return;
+ }
if (!isTypeAssignableTo(expressionType, caseType)) {
// check 'expressionType isAssignableTo caseType' failed, try the reversed check and report errors if it fails
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
@@ -25659,11 +25979,14 @@ var ts;
var enumIsConst = ts.isConst(node);
for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
var member = _a[_i];
- if (member.name.kind === 136 /* ComputedPropertyName */) {
+ if (isComputedNonLiteralName(member.name)) {
error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
- else if (isNumericLiteralName(member.name.text)) {
- error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ else {
+ var text = getTextOfPropertyName(member.name);
+ if (isNumericLiteralName(text)) {
+ error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ }
}
var previousEnumMemberIsNonConstant = autoValue === undefined;
var initializer = member.initializer;
@@ -26305,8 +26628,8 @@ var ts;
}
// Function and class expression bodies are checked after all statements in the enclosing body. This is
// to ensure constructs like the following are permitted:
- // let foo = function () {
- // let s = foo();
+ // const foo = function () {
+ // const s = foo();
// return "hello";
// }
// Here, performing a full type check of the body of the function expression whilst in the process of
@@ -26421,8 +26744,12 @@ var ts;
if (!(links.flags & 1 /* TypeChecked */)) {
// Check whether the file has declared it is the default lib,
// and whether the user has specifically chosen to avoid checking it.
- if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) {
- return;
+ if (compilerOptions.skipDefaultLibCheck) {
+ // If the user specified '--noLib' and a file has a '/// ',
+ // then we should treat that file as a default lib.
+ if (node.hasNoDefaultLib) {
+ return;
+ }
}
// Grammar checking
checkGrammarSourceFile(node);
@@ -26432,7 +26759,7 @@ var ts;
potentialThisCollisions.length = 0;
ts.forEach(node.statements, checkSourceElement);
checkFunctionAndClassExpressionBodies(node);
- if (ts.isExternalModule(node)) {
+ if (ts.isExternalOrCommonJsModule(node)) {
checkExternalModuleExports(node);
}
if (potentialThisCollisions.length) {
@@ -26515,7 +26842,7 @@ var ts;
}
switch (location.kind) {
case 248 /* SourceFile */:
- if (!ts.isExternalModule(location)) {
+ if (!ts.isExternalOrCommonJsModule(location)) {
break;
}
case 218 /* ModuleDeclaration */:
@@ -27153,9 +27480,18 @@ var ts;
getReferencedValueDeclaration: getReferencedValueDeclaration,
getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
isOptionalParameter: isOptionalParameter,
- isArgumentsLocalBinding: isArgumentsLocalBinding
+ isArgumentsLocalBinding: isArgumentsLocalBinding,
+ getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration
};
}
+ function getExternalModuleFileFromDeclaration(declaration) {
+ var specifier = ts.getExternalModuleName(declaration);
+ var moduleSymbol = getSymbolAtLocation(specifier);
+ if (!moduleSymbol) {
+ return undefined;
+ }
+ return ts.getDeclarationOfKind(moduleSymbol, 248 /* SourceFile */);
+ }
function initializeTypeChecker() {
// Bind all source files and propagate errors
ts.forEach(host.getSourceFiles(), function (file) {
@@ -27163,11 +27499,10 @@ var ts;
});
// Initialize global symbol table
ts.forEach(host.getSourceFiles(), function (file) {
- if (!ts.isExternalModule(file)) {
+ if (!ts.isExternalOrCommonJsModule(file)) {
mergeSymbolTable(globals, file.locals);
}
});
- // Initialize special symbols
getSymbolLinks(undefinedSymbol).type = undefinedType;
getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments");
getSymbolLinks(unknownSymbol).type = unknownType;
@@ -27866,7 +28201,7 @@ var ts;
}
}
function checkGrammarForNonSymbolComputedProperty(node, message) {
- if (node.kind === 136 /* ComputedPropertyName */ && !ts.isWellKnownSymbolSyntactically(node.expression)) {
+ if (ts.isDynamicName(node)) {
return grammarErrorOnNode(node, message);
}
}
@@ -28225,11 +28560,15 @@ var ts;
var writeTextOfNode;
var writer = createAndSetNewTextWriterWithSymbolWriter();
var enclosingDeclaration;
- var currentSourceFile;
+ var currentText;
+ var currentLineMap;
+ var currentIdentifiers;
+ var isCurrentFileExternalModule;
var reportedDeclarationError = false;
var errorNameNode;
var emitJsDocComments = compilerOptions.removeComments ? function (declaration) { } : writeJsDocComments;
var emit = compilerOptions.stripInternal ? stripInternal : emitNode;
+ var noDeclare = !root;
var moduleElementDeclarationEmitInfo = [];
var asynchronousSubModuleDeclarationEmitInfo;
// Contains the reference paths that needs to go in the declaration file.
@@ -28272,23 +28611,56 @@ var ts;
else {
// Emit references corresponding to this file
var emittedReferencedFiles = [];
+ var prevModuleElementDeclarationEmitInfo = [];
ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
+ if (!ts.isDeclarationFile(sourceFile)) {
// Check what references need to be added
if (!compilerOptions.noResolve) {
ts.forEach(sourceFile.referencedFiles, function (fileReference) {
var referencedFile = ts.tryResolveScriptReference(host, sourceFile, fileReference);
- // If the reference file is a declaration file or an external module, emit that reference
- if (referencedFile && (ts.isExternalModuleOrDeclarationFile(referencedFile) &&
+ // If the reference file is a declaration file, emit that reference
+ if (referencedFile && (ts.isDeclarationFile(referencedFile) &&
!ts.contains(emittedReferencedFiles, referencedFile))) {
writeReferencePath(referencedFile);
emittedReferencedFiles.push(referencedFile);
}
});
}
+ }
+ if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
+ noDeclare = false;
+ emitSourceFile(sourceFile);
+ }
+ else if (ts.isExternalModule(sourceFile)) {
+ noDeclare = true;
+ write("declare module \"" + ts.getResolvedExternalModuleName(host, sourceFile) + "\" {");
+ writeLine();
+ increaseIndent();
emitSourceFile(sourceFile);
+ decreaseIndent();
+ write("}");
+ writeLine();
+ // create asynchronous output for the importDeclarations
+ if (moduleElementDeclarationEmitInfo.length) {
+ var oldWriter = writer;
+ ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) {
+ if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
+ ts.Debug.assert(aliasEmitInfo.node.kind === 222 /* ImportDeclaration */);
+ createAndSetNewTextWriterWithSymbolWriter();
+ ts.Debug.assert(aliasEmitInfo.indent === 1);
+ increaseIndent();
+ writeImportDeclaration(aliasEmitInfo.node);
+ aliasEmitInfo.asynchronousOutput = writer.getText();
+ decreaseIndent();
+ }
+ });
+ setWriter(oldWriter);
+ }
+ prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
+ moduleElementDeclarationEmitInfo = [];
}
});
+ moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo);
}
return {
reportedDeclarationError: reportedDeclarationError,
@@ -28297,13 +28669,12 @@ var ts;
referencePathsOutput: referencePathsOutput
};
function hasInternalAnnotation(range) {
- var text = currentSourceFile.text;
- var comment = text.substring(range.pos, range.end);
+ var comment = currentText.substring(range.pos, range.end);
return comment.indexOf("@internal") >= 0;
}
function stripInternal(node) {
if (node) {
- var leadingCommentRanges = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
+ var leadingCommentRanges = ts.getLeadingCommentRanges(currentText, node.pos);
if (ts.forEach(leadingCommentRanges, hasInternalAnnotation)) {
return;
}
@@ -28395,7 +28766,7 @@ var ts;
var errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
if (errorInfo) {
if (errorInfo.typeName) {
- diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
+ diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNodeFromSourceText(currentText, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
}
else {
diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
@@ -28461,10 +28832,10 @@ var ts;
}
function writeJsDocComments(declaration) {
if (declaration) {
- var jsDocComments = ts.getJsDocComments(declaration, currentSourceFile);
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, declaration, jsDocComments);
+ var jsDocComments = ts.getJsDocCommentsFromText(declaration, currentText);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
// jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
- ts.emitComments(currentSourceFile, writer, jsDocComments, /*trailingSeparator*/ true, newLine, ts.writeCommentRange);
+ ts.emitComments(currentText, currentLineMap, writer, jsDocComments, /*trailingSeparator*/ true, newLine, ts.writeCommentRange);
}
}
function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type, getSymbolAccessibilityDiagnostic) {
@@ -28481,7 +28852,7 @@ var ts;
case 103 /* VoidKeyword */:
case 97 /* ThisKeyword */:
case 9 /* StringLiteral */:
- return writeTextOfNode(currentSourceFile, type);
+ return writeTextOfNode(currentText, type);
case 188 /* ExpressionWithTypeArguments */:
return emitExpressionWithTypeArguments(type);
case 151 /* TypeReference */:
@@ -28512,14 +28883,14 @@ var ts;
}
function writeEntityName(entityName) {
if (entityName.kind === 69 /* Identifier */) {
- writeTextOfNode(currentSourceFile, entityName);
+ writeTextOfNode(currentText, entityName);
}
else {
var left = entityName.kind === 135 /* QualifiedName */ ? entityName.left : entityName.expression;
var right = entityName.kind === 135 /* QualifiedName */ ? entityName.right : entityName.name;
writeEntityName(left);
write(".");
- writeTextOfNode(currentSourceFile, right);
+ writeTextOfNode(currentText, right);
}
}
function emitEntityName(entityName) {
@@ -28549,7 +28920,7 @@ var ts;
}
}
function emitTypePredicate(type) {
- writeTextOfNode(currentSourceFile, type.parameterName);
+ writeTextOfNode(currentText, type.parameterName);
write(" is ");
emitType(type.type);
}
@@ -28590,9 +28961,12 @@ var ts;
}
}
function emitSourceFile(node) {
- currentSourceFile = node;
+ currentText = node.text;
+ currentLineMap = ts.getLineStarts(node);
+ currentIdentifiers = node.identifiers;
+ isCurrentFileExternalModule = ts.isExternalModule(node);
enclosingDeclaration = node;
- ts.emitDetachedComments(currentSourceFile, writer, ts.writeCommentRange, node, newLine, true /* remove comments */);
+ ts.emitDetachedComments(currentText, currentLineMap, writer, ts.writeCommentRange, node, newLine, true /* remove comments */);
emitLines(node.statements);
}
// Return a temp variable name to be used in `export default` statements.
@@ -28601,13 +28975,13 @@ var ts;
// do not need to keep track of created temp names.
function getExportDefaultTempVariableName() {
var baseName = "_default";
- if (!ts.hasProperty(currentSourceFile.identifiers, baseName)) {
+ if (!ts.hasProperty(currentIdentifiers, baseName)) {
return baseName;
}
var count = 0;
while (true) {
var name_18 = baseName + "_" + (++count);
- if (!ts.hasProperty(currentSourceFile.identifiers, name_18)) {
+ if (!ts.hasProperty(currentIdentifiers, name_18)) {
return name_18;
}
}
@@ -28615,7 +28989,7 @@ var ts;
function emitExportAssignment(node) {
if (node.expression.kind === 69 /* Identifier */) {
write(node.isExportEquals ? "export = " : "export default ");
- writeTextOfNode(currentSourceFile, node.expression);
+ writeTextOfNode(currentText, node.expression);
}
else {
// Expression
@@ -28653,7 +29027,7 @@ var ts;
writeModuleElement(node);
}
else if (node.kind === 221 /* ImportEqualsDeclaration */ ||
- (node.parent.kind === 248 /* SourceFile */ && ts.isExternalModule(currentSourceFile))) {
+ (node.parent.kind === 248 /* SourceFile */ && isCurrentFileExternalModule)) {
var isVisible;
if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== 248 /* SourceFile */) {
// Import declaration of another module that is visited async so lets put it in right spot
@@ -28707,7 +29081,7 @@ var ts;
}
function emitModuleElementDeclarationFlags(node) {
// If the node is parented in the current source file we need to emit export declare or just export
- if (node.parent === currentSourceFile) {
+ if (node.parent.kind === 248 /* SourceFile */) {
// If the node is exported
if (node.flags & 2 /* Export */) {
write("export ");
@@ -28715,7 +29089,7 @@ var ts;
if (node.flags & 512 /* Default */) {
write("default ");
}
- else if (node.kind !== 215 /* InterfaceDeclaration */) {
+ else if (node.kind !== 215 /* InterfaceDeclaration */ && !noDeclare) {
write("declare ");
}
}
@@ -28742,7 +29116,7 @@ var ts;
write("export ");
}
write("import ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
write(" = ");
if (ts.isInternalModuleImportEqualsDeclaration(node)) {
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError);
@@ -28750,7 +29124,7 @@ var ts;
}
else {
write("require(");
- writeTextOfNode(currentSourceFile, ts.getExternalModuleImportEqualsDeclarationExpression(node));
+ writeTextOfNode(currentText, ts.getExternalModuleImportEqualsDeclarationExpression(node));
write(");");
}
writer.writeLine();
@@ -28785,7 +29159,7 @@ var ts;
if (node.importClause) {
var currentWriterPos = writer.getTextPos();
if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
- writeTextOfNode(currentSourceFile, node.importClause.name);
+ writeTextOfNode(currentText, node.importClause.name);
}
if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
if (currentWriterPos !== writer.getTextPos()) {
@@ -28794,7 +29168,7 @@ var ts;
}
if (node.importClause.namedBindings.kind === 224 /* NamespaceImport */) {
write("* as ");
- writeTextOfNode(currentSourceFile, node.importClause.namedBindings.name);
+ writeTextOfNode(currentText, node.importClause.namedBindings.name);
}
else {
write("{ ");
@@ -28804,16 +29178,28 @@ var ts;
}
write(" from ");
}
- writeTextOfNode(currentSourceFile, node.moduleSpecifier);
+ emitExternalModuleSpecifier(node.moduleSpecifier);
write(";");
writer.writeLine();
}
+ function emitExternalModuleSpecifier(moduleSpecifier) {
+ if (moduleSpecifier.kind === 9 /* StringLiteral */ && (!root) && (compilerOptions.out || compilerOptions.outFile)) {
+ var moduleName = ts.getExternalModuleNameFromDeclaration(host, resolver, moduleSpecifier.parent);
+ if (moduleName) {
+ write("\"");
+ write(moduleName);
+ write("\"");
+ return;
+ }
+ }
+ writeTextOfNode(currentText, moduleSpecifier);
+ }
function emitImportOrExportSpecifier(node) {
if (node.propertyName) {
- writeTextOfNode(currentSourceFile, node.propertyName);
+ writeTextOfNode(currentText, node.propertyName);
write(" as ");
}
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
function emitExportSpecifier(node) {
emitImportOrExportSpecifier(node);
@@ -28835,7 +29221,7 @@ var ts;
}
if (node.moduleSpecifier) {
write(" from ");
- writeTextOfNode(currentSourceFile, node.moduleSpecifier);
+ emitExternalModuleSpecifier(node.moduleSpecifier);
}
write(";");
writer.writeLine();
@@ -28849,11 +29235,11 @@ var ts;
else {
write("module ");
}
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
while (node.body.kind !== 219 /* ModuleBlock */) {
node = node.body;
write(".");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
@@ -28872,7 +29258,7 @@ var ts;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("type ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
emitTypeParameters(node.typeParameters);
write(" = ");
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
@@ -28894,7 +29280,7 @@ var ts;
write("const ");
}
write("enum ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
write(" {");
writeLine();
increaseIndent();
@@ -28905,7 +29291,7 @@ var ts;
}
function emitEnumMemberDeclaration(node) {
emitJsDocComments(node);
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var enumMemberValue = resolver.getConstantValue(node);
if (enumMemberValue !== undefined) {
write(" = ");
@@ -28922,7 +29308,7 @@ var ts;
increaseIndent();
emitJsDocComments(node);
decreaseIndent();
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
// If there is constraint present and this is not a type parameter of the private method emit the constraint
if (node.constraint && !isPrivateMethodTypeParameter(node)) {
write(" extends ");
@@ -29037,7 +29423,7 @@ var ts;
write("abstract ");
}
write("class ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitTypeParameters(node.typeParameters);
@@ -29060,7 +29446,7 @@ var ts;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("interface ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitTypeParameters(node.typeParameters);
@@ -29095,7 +29481,7 @@ var ts;
// If this node is a computed name, it can only be a symbol, because we've already skipped
// it if it's not a well known symbol. In that case, the text of the name will be exactly
// what we want, namely the name expression enclosed in brackets.
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
// If optional property emit ?
if ((node.kind === 141 /* PropertyDeclaration */ || node.kind === 140 /* PropertySignature */) && ts.hasQuestionToken(node)) {
write("?");
@@ -29177,7 +29563,7 @@ var ts;
emitBindingPattern(bindingElement.name);
}
else {
- writeTextOfNode(currentSourceFile, bindingElement.name);
+ writeTextOfNode(currentText, bindingElement.name);
writeTypeOfDeclaration(bindingElement, /*type*/ undefined, getBindingElementTypeVisibilityError);
}
}
@@ -29221,7 +29607,7 @@ var ts;
emitJsDocComments(accessors.getAccessor);
emitJsDocComments(accessors.setAccessor);
emitClassMemberDeclarationFlags(node);
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (!(node.flags & 16 /* Private */)) {
accessorWithTypeAnnotation = node;
var type = getTypeAnnotationFromAccessor(node);
@@ -29307,13 +29693,13 @@ var ts;
}
if (node.kind === 213 /* FunctionDeclaration */) {
write("function ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
else if (node.kind === 144 /* Constructor */) {
write("constructor");
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (ts.hasQuestionToken(node)) {
write("?");
}
@@ -29437,7 +29823,7 @@ var ts;
emitBindingPattern(node.name);
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
if (resolver.isOptionalParameter(node)) {
write("?");
@@ -29552,7 +29938,7 @@ var ts;
// Example:
// original: function foo({y: [a,b,c]}) {}
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
- writeTextOfNode(currentSourceFile, bindingElement.propertyName);
+ writeTextOfNode(currentText, bindingElement.propertyName);
write(": ");
}
if (bindingElement.name) {
@@ -29575,7 +29961,7 @@ var ts;
if (bindingElement.dotDotDotToken) {
write("...");
}
- writeTextOfNode(currentSourceFile, bindingElement.name);
+ writeTextOfNode(currentText, bindingElement.name);
}
}
}
@@ -29667,6 +30053,18 @@ var ts;
return ts.isExternalModule(sourceFile) || ts.isDeclarationFile(sourceFile);
}
ts.isExternalModuleOrDeclarationFile = isExternalModuleOrDeclarationFile;
+ function getResolvedExternalModuleName(host, file) {
+ return file.moduleName || ts.getExternalModuleNameFromPath(host, file.fileName);
+ }
+ ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
+ function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
+ var file = resolver.getExternalModuleFileFromDeclaration(declaration);
+ if (!file || ts.isDeclarationFile(file)) {
+ return undefined;
+ }
+ return getResolvedExternalModuleName(host, file);
+ }
+ ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
var Jump;
(function (Jump) {
Jump[Jump["Break"] = 2] = "Break";
@@ -29954,15 +30352,19 @@ var ts;
var newLine = host.getNewLine();
var jsxDesugaring = host.getCompilerOptions().jsx !== 1 /* Preserve */;
var shouldEmitJsx = function (s) { return (s.languageVariant === 1 /* JSX */ && !jsxDesugaring); };
+ var outFile = compilerOptions.outFile || compilerOptions.out;
+ var emitJavaScript = createFileEmitter();
if (targetSourceFile === undefined) {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
- var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
- emitFile(jsFilePath, sourceFile);
- }
- });
- if (compilerOptions.outFile || compilerOptions.out) {
- emitFile(compilerOptions.outFile || compilerOptions.out);
+ if (outFile) {
+ emitFile(outFile);
+ }
+ else {
+ ts.forEach(host.getSourceFiles(), function (sourceFile) {
+ if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
+ var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
+ emitFile(jsFilePath, sourceFile);
+ }
+ });
}
}
else {
@@ -29971,8 +30373,8 @@ var ts;
var jsFilePath = ts.getOwnEmitOutputFilePath(targetSourceFile, host, shouldEmitJsx(targetSourceFile) ? ".jsx" : ".js");
emitFile(jsFilePath, targetSourceFile);
}
- else if (!ts.isDeclarationFile(targetSourceFile) && (compilerOptions.outFile || compilerOptions.out)) {
- emitFile(compilerOptions.outFile || compilerOptions.out);
+ else if (!ts.isDeclarationFile(targetSourceFile) && outFile) {
+ emitFile(outFile);
}
}
// Sort and make the unique list of diagnostics
@@ -30024,10 +30426,16 @@ var ts;
}
}
}
- function emitJavaScript(jsFilePath, root) {
+ function createFileEmitter() {
var writer = ts.createTextWriter(newLine);
var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent;
var currentSourceFile;
+ var currentText;
+ var currentLineMap;
+ var currentFileIdentifiers;
+ var renamedDependencies;
+ var isEs6Module;
+ var isCurrentFileExternalModule;
// name of an exporter function if file is a System external module
// System.register([...], function () {...})
// exporting in System modules looks like:
@@ -30035,15 +30443,15 @@ var ts;
// =>
// var x;... exporter("x", x = 1)
var exportFunctionForFile;
- var generatedNameSet = {};
- var nodeToGeneratedName = [];
+ var generatedNameSet;
+ var nodeToGeneratedName;
var computedPropertyNamesToGeneratedNames;
var convertedLoopState;
- var extendsEmitted = false;
- var decorateEmitted = false;
- var paramEmitted = false;
- var awaiterEmitted = false;
- var tempFlags = 0;
+ var extendsEmitted;
+ var decorateEmitted;
+ var paramEmitted;
+ var awaiterEmitted;
+ var tempFlags;
var tempVariables;
var tempParameters;
var externalImports;
@@ -30075,6 +30483,8 @@ var ts;
var scopeEmitEnd = function () { };
/** Sourcemap data that will get encoded */
var sourceMapData;
+ /** The root file passed to the emit function (if present) */
+ var root;
/** If removeComments is true, no leading-comments needed to be emitted **/
var emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos) { } : emitLeadingCommentsOfPositionWorker;
var moduleEmitDelegates = (_a = {},
@@ -30085,31 +30495,77 @@ var ts;
_a[1 /* CommonJS */] = emitCommonJSModule,
_a
);
- if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
- initializeEmitterWithSourceMaps();
- }
- if (root) {
- // Do not call emit directly. It does not set the currentSourceFile.
- emitSourceFile(root);
- }
- else {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!isExternalModuleOrDeclarationFile(sourceFile)) {
- emitSourceFile(sourceFile);
+ var bundleEmitDelegates = (_b = {},
+ _b[5 /* ES6 */] = function () { },
+ _b[2 /* AMD */] = emitAMDModule,
+ _b[4 /* System */] = emitSystemModule,
+ _b[3 /* UMD */] = function () { },
+ _b[1 /* CommonJS */] = function () { },
+ _b
+ );
+ return doEmit;
+ function doEmit(jsFilePath, rootFile) {
+ // reset the state
+ writer.reset();
+ currentSourceFile = undefined;
+ currentText = undefined;
+ currentLineMap = undefined;
+ exportFunctionForFile = undefined;
+ generatedNameSet = {};
+ nodeToGeneratedName = [];
+ computedPropertyNamesToGeneratedNames = undefined;
+ convertedLoopState = undefined;
+ extendsEmitted = false;
+ decorateEmitted = false;
+ paramEmitted = false;
+ awaiterEmitted = false;
+ tempFlags = 0;
+ tempVariables = undefined;
+ tempParameters = undefined;
+ externalImports = undefined;
+ exportSpecifiers = undefined;
+ exportEquals = undefined;
+ hasExportStars = undefined;
+ detachedCommentsInfo = undefined;
+ sourceMapData = undefined;
+ isEs6Module = false;
+ renamedDependencies = undefined;
+ isCurrentFileExternalModule = false;
+ root = rootFile;
+ if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
+ initializeEmitterWithSourceMaps(jsFilePath, root);
+ }
+ if (root) {
+ // Do not call emit directly. It does not set the currentSourceFile.
+ emitSourceFile(root);
+ }
+ else {
+ if (modulekind) {
+ ts.forEach(host.getSourceFiles(), emitEmitHelpers);
}
- });
+ ts.forEach(host.getSourceFiles(), function (sourceFile) {
+ if ((!isExternalModuleOrDeclarationFile(sourceFile)) || (modulekind && ts.isExternalModule(sourceFile))) {
+ emitSourceFile(sourceFile);
+ }
+ });
+ }
+ writeLine();
+ writeEmittedFiles(writer.getText(), jsFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM);
}
- writeLine();
- writeEmittedFiles(writer.getText(), /*writeByteOrderMark*/ compilerOptions.emitBOM);
- return;
function emitSourceFile(sourceFile) {
currentSourceFile = sourceFile;
+ currentText = sourceFile.text;
+ currentLineMap = ts.getLineStarts(sourceFile);
exportFunctionForFile = undefined;
+ isEs6Module = sourceFile.symbol && sourceFile.symbol.exports && !!sourceFile.symbol.exports["___esModule"];
+ renamedDependencies = sourceFile.renamedDependencies;
+ currentFileIdentifiers = sourceFile.identifiers;
+ isCurrentFileExternalModule = ts.isExternalModule(sourceFile);
emit(sourceFile);
}
function isUniqueName(name) {
return !resolver.hasGlobalName(name) &&
- !ts.hasProperty(currentSourceFile.identifiers, name) &&
+ !ts.hasProperty(currentFileIdentifiers, name) &&
!ts.hasProperty(generatedNameSet, name);
}
// Return the next available name in the pattern _a ... _z, _0, _1, ...
@@ -30192,7 +30648,7 @@ var ts;
var id = ts.getNodeId(node);
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = ts.unescapeIdentifier(generateNameForNode(node)));
}
- function initializeEmitterWithSourceMaps() {
+ function initializeEmitterWithSourceMaps(jsFilePath, root) {
var sourceMapDir; // The directory in which sourcemap will be
// Current source map file and its index in the sources list
var sourceMapSourceIndex = -1;
@@ -30280,7 +30736,7 @@ var ts;
}
}
function recordSourceMapSpan(pos) {
- var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSourceFile, pos);
+ var sourceLinePos = ts.computeLineAndCharacterOfPosition(currentLineMap, pos);
// Convert the location to be one-based.
sourceLinePos.line++;
sourceLinePos.character++;
@@ -30314,13 +30770,13 @@ var ts;
}
function recordEmitNodeStartSpan(node) {
// Get the token pos after skipping to the token (ignoring the leading trivia)
- recordSourceMapSpan(ts.skipTrivia(currentSourceFile.text, node.pos));
+ recordSourceMapSpan(ts.skipTrivia(currentText, node.pos));
}
function recordEmitNodeEndSpan(node) {
recordSourceMapSpan(node.end);
}
function writeTextWithSpanRecord(tokenKind, startPos, emitFn) {
- var tokenStartPos = ts.skipTrivia(currentSourceFile.text, startPos);
+ var tokenStartPos = ts.skipTrivia(currentText, startPos);
recordSourceMapSpan(tokenStartPos);
var tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
recordSourceMapSpan(tokenEndPos);
@@ -30402,9 +30858,9 @@ var ts;
sourceMapNameIndices.pop();
}
;
- function writeCommentRangeWithMap(curentSourceFile, writer, comment, newLine) {
+ function writeCommentRangeWithMap(currentText, currentLineMap, writer, comment, newLine) {
recordSourceMapSpan(comment.pos);
- ts.writeCommentRange(currentSourceFile, writer, comment, newLine);
+ ts.writeCommentRange(currentText, currentLineMap, writer, comment, newLine);
recordSourceMapSpan(comment.end);
}
function serializeSourceMapContents(version, file, sourceRoot, sources, names, mappings, sourcesContent) {
@@ -30434,7 +30890,7 @@ var ts;
return output;
}
}
- function writeJavaScriptAndSourceMapFile(emitOutput, writeByteOrderMark) {
+ function writeJavaScriptAndSourceMapFile(emitOutput, jsFilePath, writeByteOrderMark) {
encodeLastRecordedSourceMapSpan();
var sourceMapText = serializeSourceMapContents(3, sourceMapData.sourceMapFile, sourceMapData.sourceMapSourceRoot, sourceMapData.sourceMapSources, sourceMapData.sourceMapNames, sourceMapData.sourceMapMappings, sourceMapData.sourceMapSourcesContent);
sourceMapDataList.push(sourceMapData);
@@ -30450,7 +30906,7 @@ var ts;
sourceMapUrl = "//# sourceMappingURL=" + sourceMapData.jsSourceMappingURL;
}
// Write sourcemap url to the js file and write the js file
- writeJavaScriptFile(emitOutput + sourceMapUrl, writeByteOrderMark);
+ writeJavaScriptFile(emitOutput + sourceMapUrl, jsFilePath, writeByteOrderMark);
}
// Initialize source map data
var sourceMapJsFile = ts.getBaseFileName(ts.normalizeSlashes(jsFilePath));
@@ -30522,7 +30978,7 @@ var ts;
scopeEmitEnd = recordScopeNameEnd;
writeComment = writeCommentRangeWithMap;
}
- function writeJavaScriptFile(emitOutput, writeByteOrderMark) {
+ function writeJavaScriptFile(emitOutput, jsFilePath, writeByteOrderMark) {
ts.writeFile(host, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
}
// Create a temporary variable with a unique unused name.
@@ -30702,7 +31158,7 @@ var ts;
// If we don't need to downlevel and we can reach the original source text using
// the node's parent reference, then simply get the text as it was originally written.
if (node.parent) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+ return ts.getTextOfNodeFromSourceText(currentText, node);
}
// If we can't reach the original source text, use the canonical form if it's a number,
// or an escaped quoted form of the original text if it's string-like.
@@ -30729,7 +31185,7 @@ var ts;
// Find original source text, since we need to emit the raw strings of the tagged template.
// The raw strings contain the (escaped) strings of what the user wrote.
// Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+ var text = ts.getTextOfNodeFromSourceText(currentText, node);
// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
// thus we need to remove those characters.
// First template piece starts with "`", others with "}"
@@ -31146,7 +31602,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
write("\"");
}
@@ -31246,7 +31702,7 @@ var ts;
// Identifier references named import
write(getGeneratedNameForNode(declaration.parent.parent.parent));
var name_23 = declaration.propertyName || declaration.name;
- var identifier = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, name_23);
+ var identifier = ts.getTextOfNodeFromSourceText(currentText, name_23);
if (languageVersion === 0 /* ES3 */ && identifier === "default") {
write("[\"default\"]");
}
@@ -31270,7 +31726,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
}
function isNameOfNestedRedeclaration(node) {
@@ -31308,7 +31764,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
}
function emitThis(node) {
@@ -31712,7 +32168,7 @@ var ts;
function emitShorthandPropertyAssignment(node) {
// The name property of a short-hand property assignment is considered an expression position, so here
// we manually emit the identifier to avoid rewriting.
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
// If emitting pre-ES6 code, or if the name requires rewriting when resolved as an expression identifier,
// we emit a normal property assignment. For example:
// module m {
@@ -31722,7 +32178,7 @@ var ts;
// let obj = { y };
// }
// Here we need to emit obj = { y : m.y } regardless of the output target.
- if (languageVersion < 2 /* ES6 */ || isNamespaceExportReference(node.name)) {
+ if (modulekind !== 5 /* ES6 */ || isNamespaceExportReference(node.name)) {
// Emit identifier as an identifier
write(": ");
emit(node.name);
@@ -31779,11 +32235,11 @@ var ts;
var indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken);
// 1 .toString is a valid property access, emit a space after the literal
// Also emit a space if expression is a integer const enum value - it will appear in generated code as numeric literal
- var shouldEmitSpace;
+ var shouldEmitSpace = false;
if (!indentedBeforeDot) {
if (node.expression.kind === 8 /* NumericLiteral */) {
// check if numeric literal was originally written with a dot
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node.expression);
+ var text = ts.getTextOfNodeFromSourceText(currentText, node.expression);
shouldEmitSpace = text.indexOf(ts.tokenToString(21 /* DotToken */)) < 0;
}
else {
@@ -32962,16 +33418,16 @@ var ts;
emitToken(16 /* CloseBraceToken */, node.clauses.end);
}
function nodeStartPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node1.pos)) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node1.pos)) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
}
function nodeEndPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, node2.end);
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, node2.end);
}
function nodeEndIsOnSameLineAsNodeStart(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
}
function emitCaseOrDefaultClause(node) {
if (node.kind === 241 /* CaseClause */) {
@@ -33077,7 +33533,7 @@ var ts;
ts.Debug.assert(!!(node.flags & 512 /* Default */) || node.kind === 227 /* ExportAssignment */);
// only allow export default at a source file level
if (modulekind === 1 /* CommonJS */ || modulekind === 2 /* AMD */ || modulekind === 3 /* UMD */) {
- if (!currentSourceFile.symbol.exports["___esModule"]) {
+ if (!isEs6Module) {
if (languageVersion === 1 /* ES5 */) {
// default value of configurable, enumerable, writable are `false`.
write("Object.defineProperty(exports, \"__esModule\", { value: true });");
@@ -33272,14 +33728,20 @@ var ts;
return node;
}
function createPropertyAccessForDestructuringProperty(object, propName) {
- // We create a synthetic copy of the identifier in order to avoid the rewriting that might
- // otherwise occur when the identifier is emitted.
- var syntheticName = ts.createSynthesizedNode(propName.kind);
- syntheticName.text = propName.text;
- if (syntheticName.kind !== 69 /* Identifier */) {
- return createElementAccessExpression(object, syntheticName);
+ var index;
+ var nameIsComputed = propName.kind === 136 /* ComputedPropertyName */;
+ if (nameIsComputed) {
+ index = ensureIdentifier(propName.expression, /* reuseIdentifierExpression */ false);
+ }
+ else {
+ // We create a synthetic copy of the identifier in order to avoid the rewriting that might
+ // otherwise occur when the identifier is emitted.
+ index = ts.createSynthesizedNode(propName.kind);
+ index.text = propName.text;
}
- return createPropertyAccessExpression(object, syntheticName);
+ return !nameIsComputed && index.kind === 69 /* Identifier */
+ ? createPropertyAccessExpression(object, index)
+ : createElementAccessExpression(object, index);
}
function createSliceCall(value, sliceIndex) {
var call = ts.createSynthesizedNode(168 /* CallExpression */);
@@ -33742,7 +34204,6 @@ var ts;
var promiseConstructor = ts.getEntityNameFromTypeNode(node.type);
var isArrowFunction = node.kind === 174 /* ArrowFunction */;
var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 4096 /* CaptureArguments */) !== 0;
- var args;
// An async function is emit as an outer function that calls an inner
// generator function. To preserve lexical bindings, we pass the current
// `this` and `arguments` objects to `__awaiter`. The generator function
@@ -35197,8 +35658,8 @@ var ts;
* Here we check if alternative name was provided for a given moduleName and return it if possible.
*/
function tryRenameExternalModule(moduleName) {
- if (currentSourceFile.renamedDependencies && ts.hasProperty(currentSourceFile.renamedDependencies, moduleName.text)) {
- return "\"" + currentSourceFile.renamedDependencies[moduleName.text] + "\"";
+ if (renamedDependencies && ts.hasProperty(renamedDependencies, moduleName.text)) {
+ return "\"" + renamedDependencies[moduleName.text] + "\"";
}
return undefined;
}
@@ -35351,7 +35812,7 @@ var ts;
// - current file is not external module
// - import declaration is top level and target is value imported by entity name
if (resolver.isReferencedAliasDeclaration(node) ||
- (!ts.isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
+ (!isCurrentFileExternalModule && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
emitLeadingComments(node);
emitStart(node);
// variable declaration for import-equals declaration can be hoisted in system modules
@@ -35579,7 +36040,7 @@ var ts;
function getLocalNameForExternalImport(node) {
var namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, namespaceDeclaration.name);
+ return ts.getTextOfNodeFromSourceText(currentText, namespaceDeclaration.name);
}
if (node.kind === 222 /* ImportDeclaration */ && node.importClause) {
return getGeneratedNameForNode(node);
@@ -35884,7 +36345,7 @@ var ts;
ts.getEnclosingBlockScopeContainer(node).kind === 248 /* SourceFile */;
}
function isCurrentFileSystemExternalModule() {
- return modulekind === 4 /* System */ && ts.isExternalModule(currentSourceFile);
+ return modulekind === 4 /* System */ && isCurrentFileExternalModule;
}
function emitSystemModuleBody(node, dependencyGroups, startIndex) {
// shape of the body in system modules:
@@ -36054,7 +36515,13 @@ var ts;
writeLine();
write("}"); // execute
}
- function emitSystemModule(node) {
+ function writeModuleName(node, emitRelativePathAsModuleName) {
+ var moduleName = node.moduleName;
+ if (moduleName || (emitRelativePathAsModuleName && (moduleName = getResolvedExternalModuleName(host, node)))) {
+ write("\"" + moduleName + "\", ");
+ }
+ }
+ function emitSystemModule(node, emitRelativePathAsModuleName) {
collectExternalModuleInfo(node);
// System modules has the following shape
// System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
@@ -36069,9 +36536,7 @@ var ts;
exportFunctionForFile = makeUniqueName("exports");
writeLine();
write("System.register(");
- if (node.moduleName) {
- write("\"" + node.moduleName + "\", ");
- }
+ writeModuleName(node, emitRelativePathAsModuleName);
write("[");
var groupIndices = {};
var dependencyGroups = [];
@@ -36090,6 +36555,12 @@ var ts;
if (i !== 0) {
write(", ");
}
+ if (emitRelativePathAsModuleName) {
+ var name_29 = getExternalModuleNameFromDeclaration(host, resolver, externalImports[i]);
+ if (name_29) {
+ text = "\"" + name_29 + "\"";
+ }
+ }
write(text);
}
write("], function(" + exportFunctionForFile + ") {");
@@ -36103,7 +36574,7 @@ var ts;
writeLine();
write("});");
}
- function getAMDDependencyNames(node, includeNonAmdDependencies) {
+ function getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
// names of modules with corresponding parameter in the factory function
var aliasedModuleNames = [];
// names of modules with no corresponding parameters in factory function
@@ -36126,6 +36597,12 @@ var ts;
var importNode = externalImports_4[_c];
// Find the name of the external module
var externalModuleName = getExternalModuleNameText(importNode);
+ if (emitRelativePathAsModuleName) {
+ var name_30 = getExternalModuleNameFromDeclaration(host, resolver, importNode);
+ if (name_30) {
+ externalModuleName = "\"" + name_30 + "\"";
+ }
+ }
// Find the name of the module alias, if there is one
var importAliasName = getLocalNameForExternalImport(importNode);
if (includeNonAmdDependencies && importAliasName) {
@@ -36138,7 +36615,7 @@ var ts;
}
return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
}
- function emitAMDDependencies(node, includeNonAmdDependencies) {
+ function emitAMDDependencies(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
// An AMD define function has the following shape:
// define(id?, dependencies?, factory);
//
@@ -36150,7 +36627,7 @@ var ts;
// To ensure this is true in cases of modules with no aliases, e.g.:
// `import "module"` or ``
// we need to add modules without alias names to the end of the dependencies list
- var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies);
+ var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName);
emitAMDDependencyList(dependencyNames);
write(", ");
emitAMDFactoryHeader(dependencyNames);
@@ -36177,15 +36654,13 @@ var ts;
}
write(") {");
}
- function emitAMDModule(node) {
+ function emitAMDModule(node, emitRelativePathAsModuleName) {
emitEmitHelpers(node);
collectExternalModuleInfo(node);
writeLine();
write("define(");
- if (node.moduleName) {
- write("\"" + node.moduleName + "\", ");
- }
- emitAMDDependencies(node, /*includeNonAmdDependencies*/ true);
+ writeModuleName(node, emitRelativePathAsModuleName);
+ emitAMDDependencies(node, /*includeNonAmdDependencies*/ true, emitRelativePathAsModuleName);
increaseIndent();
var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
emitExportStarHelper();
@@ -36404,8 +36879,13 @@ var ts;
emitShebang();
emitDetachedCommentsAndUpdateCommentsInfo(node);
if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
- var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[1 /* CommonJS */];
- emitModule(node);
+ if (root || (!ts.isExternalModule(node) && compilerOptions.isolatedModules)) {
+ var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[1 /* CommonJS */];
+ emitModule(node);
+ }
+ else {
+ bundleEmitDelegates[modulekind](node, /*emitRelativePathAsModuleName*/ true);
+ }
}
else {
// emit prologue directives prior to __extends
@@ -36666,7 +37146,7 @@ var ts;
}
function getLeadingCommentsWithoutDetachedComments() {
// get the leading comments from detachedPos
- var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
+ var leadingComments = ts.getLeadingCommentRanges(currentText, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
if (detachedCommentsInfo.length - 1) {
detachedCommentsInfo.pop();
}
@@ -36683,10 +37163,10 @@ var ts;
function isTripleSlashComment(comment) {
// Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
// so that we don't end up computing comment string and doing match for all // comments
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 47 /* slash */ &&
+ if (currentText.charCodeAt(comment.pos + 1) === 47 /* slash */ &&
comment.pos + 2 < comment.end &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 47 /* slash */) {
- var textSubStr = currentSourceFile.text.substring(comment.pos, comment.end);
+ currentText.charCodeAt(comment.pos + 2) === 47 /* slash */) {
+ var textSubStr = currentText.substring(comment.pos, comment.end);
return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ?
true : false;
@@ -36703,7 +37183,7 @@ var ts;
}
else {
// get the leading comments from the node
- return ts.getLeadingCommentRangesOfNode(node, currentSourceFile);
+ return ts.getLeadingCommentRangesOfNodeFromText(node, currentText);
}
}
}
@@ -36712,7 +37192,7 @@ var ts;
// Emit the trailing comments only if the parent's pos doesn't match because parent should take care of emitting these comments
if (node.parent) {
if (node.parent.kind === 248 /* SourceFile */ || node.end !== node.parent.end) {
- return ts.getTrailingCommentRanges(currentSourceFile.text, node.end);
+ return ts.getTrailingCommentRanges(currentText, node.end);
}
}
}
@@ -36746,9 +37226,9 @@ var ts;
leadingComments = ts.filter(getLeadingCommentsToEmit(node), isTripleSlashComment);
}
}
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
- ts.emitComments(currentSourceFile, writer, leadingComments, /*trailingSeparator:*/ true, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator:*/ true, newLine, writeComment);
}
function emitTrailingComments(node) {
if (compilerOptions.removeComments) {
@@ -36757,7 +37237,7 @@ var ts;
// Emit the trailing comments only if the parent's end doesn't match
var trailingComments = getTrailingCommentsToEmit(node);
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
- ts.emitComments(currentSourceFile, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment);
}
/**
* Emit trailing comments at the position. The term trailing comment is used here to describe following comment:
@@ -36768,9 +37248,9 @@ var ts;
if (compilerOptions.removeComments) {
return;
}
- var trailingComments = ts.getTrailingCommentRanges(currentSourceFile.text, pos);
+ var trailingComments = ts.getTrailingCommentRanges(currentText, pos);
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
- ts.emitComments(currentSourceFile, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitLeadingCommentsOfPositionWorker(pos) {
if (compilerOptions.removeComments) {
@@ -36783,14 +37263,14 @@ var ts;
}
else {
// get the leading comments from the node
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, pos);
+ leadingComments = ts.getLeadingCommentRanges(currentText, pos);
}
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, { pos: pos, end: pos }, leadingComments);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
- ts.emitComments(currentSourceFile, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitDetachedCommentsAndUpdateCommentsInfo(node) {
- var currentDetachedCommentInfo = ts.emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, compilerOptions.removeComments);
+ var currentDetachedCommentInfo = ts.emitDetachedComments(currentText, currentLineMap, writer, writeComment, node, newLine, compilerOptions.removeComments);
if (currentDetachedCommentInfo) {
if (detachedCommentsInfo) {
detachedCommentsInfo.push(currentDetachedCommentInfo);
@@ -36801,12 +37281,12 @@ var ts;
}
}
function emitShebang() {
- var shebang = ts.getShebang(currentSourceFile.text);
+ var shebang = ts.getShebang(currentText);
if (shebang) {
write(shebang);
}
}
- var _a;
+ var _a, _b;
}
function emitFile(jsFilePath, sourceFile) {
emitJavaScript(jsFilePath, sourceFile);
@@ -36866,11 +37346,11 @@ var ts;
if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
var failedLookupLocations = [];
var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
- var resolvedFileName = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ var resolvedFileName = loadNodeModuleFromFile(ts.supportedJsExtensions, candidate, failedLookupLocations, host);
if (resolvedFileName) {
return { resolvedModule: { resolvedFileName: resolvedFileName }, failedLookupLocations: failedLookupLocations };
}
- resolvedFileName = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ resolvedFileName = loadNodeModuleFromDirectory(ts.supportedJsExtensions, candidate, failedLookupLocations, host);
return resolvedFileName
? { resolvedModule: { resolvedFileName: resolvedFileName }, failedLookupLocations: failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations: failedLookupLocations };
@@ -36880,8 +37360,8 @@ var ts;
}
}
ts.nodeModuleNameResolver = nodeModuleNameResolver;
- function loadNodeModuleFromFile(candidate, failedLookupLocation, host) {
- return ts.forEach(ts.moduleFileExtensions, tryLoad);
+ function loadNodeModuleFromFile(extensions, candidate, failedLookupLocation, host) {
+ return ts.forEach(extensions, tryLoad);
function tryLoad(ext) {
var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
if (host.fileExists(fileName)) {
@@ -36893,7 +37373,7 @@ var ts;
}
}
}
- function loadNodeModuleFromDirectory(candidate, failedLookupLocation, host) {
+ function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, host) {
var packageJsonPath = ts.combinePaths(candidate, "package.json");
if (host.fileExists(packageJsonPath)) {
var jsonContent;
@@ -36906,7 +37386,7 @@ var ts;
jsonContent = { typings: undefined };
}
if (jsonContent.typings) {
- var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
+ var result = loadNodeModuleFromFile(extensions, ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
if (result) {
return result;
}
@@ -36916,7 +37396,7 @@ var ts;
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
failedLookupLocation.push(packageJsonPath);
}
- return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), failedLookupLocation, host);
+ return loadNodeModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocation, host);
}
function loadModuleFromNodeModules(moduleName, directory, host) {
var failedLookupLocations = [];
@@ -36926,11 +37406,11 @@ var ts;
if (baseName !== "node_modules") {
var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName));
- var result = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ var result = loadNodeModuleFromFile(ts.supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations: failedLookupLocations };
}
- result = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ result = loadNodeModuleFromDirectory(ts.supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations: failedLookupLocations };
}
@@ -36956,9 +37436,10 @@ var ts;
var searchName;
var failedLookupLocations = [];
var referencedSourceFile;
+ var extensions = compilerOptions.allowNonTsExtensions ? ts.supportedJsExtensions : ts.supportedExtensions;
while (true) {
searchName = ts.normalizePath(ts.combinePaths(searchPath, moduleName));
- referencedSourceFile = ts.forEach(ts.supportedExtensions, function (extension) {
+ referencedSourceFile = ts.forEach(extensions, function (extension) {
if (extension === ".tsx" && !compilerOptions.jsx) {
// resolve .tsx files only if jsx support is enabled
// 'logical not' handles both undefined and None cases
@@ -36989,10 +37470,8 @@ var ts;
/* @internal */
ts.defaultInitCompilerOptions = {
module: 1 /* CommonJS */,
- target: 0 /* ES3 */,
+ target: 1 /* ES5 */,
noImplicitAny: false,
- outDir: "built",
- rootDir: ".",
sourceMap: false
};
function createCompilerHost(options, setParentNodes) {
@@ -37397,43 +37876,55 @@ var ts;
if (file.imports) {
return;
}
+ var isJavaScriptFile = ts.isSourceFileJavaScript(file);
var imports;
for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
var node = _a[_i];
- collect(node, /* allowRelativeModuleNames */ true);
+ collect(node, /* allowRelativeModuleNames */ true, /* collectOnlyRequireCalls */ false);
}
file.imports = imports || emptyArray;
- function collect(node, allowRelativeModuleNames) {
- switch (node.kind) {
- case 222 /* ImportDeclaration */:
- case 221 /* ImportEqualsDeclaration */:
- case 228 /* ExportDeclaration */:
- var moduleNameExpr = ts.getExternalModuleName(node);
- if (!moduleNameExpr || moduleNameExpr.kind !== 9 /* StringLiteral */) {
- break;
- }
- if (!moduleNameExpr.text) {
+ return;
+ function collect(node, allowRelativeModuleNames, collectOnlyRequireCalls) {
+ if (!collectOnlyRequireCalls) {
+ switch (node.kind) {
+ case 222 /* ImportDeclaration */:
+ case 221 /* ImportEqualsDeclaration */:
+ case 228 /* ExportDeclaration */:
+ var moduleNameExpr = ts.getExternalModuleName(node);
+ if (!moduleNameExpr || moduleNameExpr.kind !== 9 /* StringLiteral */) {
+ break;
+ }
+ if (!moduleNameExpr.text) {
+ break;
+ }
+ if (allowRelativeModuleNames || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
+ (imports || (imports = [])).push(moduleNameExpr);
+ }
break;
- }
- if (allowRelativeModuleNames || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
- (imports || (imports = [])).push(moduleNameExpr);
- }
- break;
- case 218 /* ModuleDeclaration */:
- if (node.name.kind === 9 /* StringLiteral */ && (node.flags & 4 /* Ambient */ || ts.isDeclarationFile(file))) {
- // TypeScript 1.0 spec (April 2014): 12.1.6
- // An AmbientExternalModuleDeclaration declares an external module.
- // This type of declaration is permitted only in the global module.
- // The StringLiteral must specify a top - level external module name.
- // Relative external module names are not permitted
- ts.forEachChild(node.body, function (node) {
+ case 218 /* ModuleDeclaration */:
+ if (node.name.kind === 9 /* StringLiteral */ && (node.flags & 4 /* Ambient */ || ts.isDeclarationFile(file))) {
// TypeScript 1.0 spec (April 2014): 12.1.6
- // An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
- // only through top - level external module names. Relative external module names are not permitted.
- collect(node, /* allowRelativeModuleNames */ false);
- });
- }
- break;
+ // An AmbientExternalModuleDeclaration declares an external module.
+ // This type of declaration is permitted only in the global module.
+ // The StringLiteral must specify a top - level external module name.
+ // Relative external module names are not permitted
+ ts.forEachChild(node.body, function (node) {
+ // TypeScript 1.0 spec (April 2014): 12.1.6
+ // An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
+ // only through top - level external module names. Relative external module names are not permitted.
+ collect(node, /* allowRelativeModuleNames */ false, collectOnlyRequireCalls);
+ });
+ }
+ break;
+ }
+ }
+ if (isJavaScriptFile) {
+ if (ts.isRequireCall(node)) {
+ (imports || (imports = [])).push(node.arguments[0]);
+ }
+ else {
+ ts.forEachChild(node, function (node) { return collect(node, allowRelativeModuleNames, /* collectOnlyRequireCalls */ true); });
+ }
}
}
}
@@ -37526,7 +38017,6 @@ var ts;
// always process imported modules to record module name resolutions
processImportedModules(file, basePath);
if (isDefaultLib) {
- file.isDefaultLib = true;
files.unshift(file);
}
else {
@@ -37604,6 +38094,9 @@ var ts;
commonPathComponents.length = sourcePathComponents.length;
}
});
+ if (!commonPathComponents) {
+ return currentDirectory;
+ }
return ts.getNormalizedPathFromPathComponents(commonPathComponents);
}
function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
@@ -37689,12 +38182,15 @@ var ts;
if (options.module === 5 /* ES6 */ && languageVersion < 2 /* ES6 */) {
programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower));
}
+ // Cannot specify module gen that isn't amd or system with --out
+ if (outFile && options.module && !(options.module === 2 /* AMD */ || options.module === 4 /* System */)) {
+ programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile"));
+ }
// there has to be common source directory if user specified --outdir || --sourceRoot
// if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
if (options.outDir ||
options.sourceRoot ||
- (options.mapRoot &&
- (!outFile || firstExternalModuleSourceFile !== undefined))) {
+ options.mapRoot) {
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
// If a rootDir is specified and is valid use it as the commonSourceDirectory
commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
@@ -38212,20 +38708,20 @@ var ts;
var exclude = json["exclude"] instanceof Array ? ts.map(json["exclude"], ts.normalizeSlashes) : undefined;
var sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
for (var i = 0; i < sysFiles.length; i++) {
- var name_29 = sysFiles[i];
- if (ts.fileExtensionIs(name_29, ".d.ts")) {
- var baseName = name_29.substr(0, name_29.length - ".d.ts".length);
+ var name_31 = sysFiles[i];
+ if (ts.fileExtensionIs(name_31, ".d.ts")) {
+ var baseName = name_31.substr(0, name_31.length - ".d.ts".length);
if (!ts.contains(sysFiles, baseName + ".tsx") && !ts.contains(sysFiles, baseName + ".ts")) {
- fileNames.push(name_29);
+ fileNames.push(name_31);
}
}
- else if (ts.fileExtensionIs(name_29, ".ts")) {
- if (!ts.contains(sysFiles, name_29 + "x")) {
- fileNames.push(name_29);
+ else if (ts.fileExtensionIs(name_31, ".ts")) {
+ if (!ts.contains(sysFiles, name_31 + "x")) {
+ fileNames.push(name_31);
}
}
else {
- fileNames.push(name_29);
+ fileNames.push(name_31);
}
}
}
@@ -38453,12 +38949,12 @@ var ts;
ts.forEach(program.getSourceFiles(), function (sourceFile) {
cancellationToken.throwIfCancellationRequested();
var nameToDeclarations = sourceFile.getNamedDeclarations();
- for (var name_30 in nameToDeclarations) {
- var declarations = ts.getProperty(nameToDeclarations, name_30);
+ for (var name_32 in nameToDeclarations) {
+ var declarations = ts.getProperty(nameToDeclarations, name_32);
if (declarations) {
// First do a quick check to see if the name of the declaration matches the
// last portion of the (possibly) dotted name they're searching for.
- var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_30);
+ var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_32);
if (!matches) {
continue;
}
@@ -38471,14 +38967,14 @@ var ts;
if (!containers) {
return undefined;
}
- matches = patternMatcher.getMatches(containers, name_30);
+ matches = patternMatcher.getMatches(containers, name_32);
if (!matches) {
continue;
}
}
var fileName = sourceFile.fileName;
var matchKind = bestMatchKind(matches);
- rawItems.push({ name: name_30, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration });
+ rawItems.push({ name: name_32, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration });
}
}
}
@@ -38859,9 +39355,9 @@ var ts;
case 211 /* VariableDeclaration */:
case 163 /* BindingElement */:
var variableDeclarationNode;
- var name_31;
+ var name_33;
if (node.kind === 163 /* BindingElement */) {
- name_31 = node.name;
+ name_33 = node.name;
variableDeclarationNode = node;
// binding elements are added only for variable declarations
// bubble up to the containing variable declaration
@@ -38873,16 +39369,16 @@ var ts;
else {
ts.Debug.assert(!ts.isBindingPattern(node.name));
variableDeclarationNode = node;
- name_31 = node.name;
+ name_33 = node.name;
}
if (ts.isConst(variableDeclarationNode)) {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.constElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.constElement);
}
else if (ts.isLet(variableDeclarationNode)) {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.letElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.letElement);
}
else {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.variableElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.variableElement);
}
case 144 /* Constructor */:
return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement);
@@ -39802,7 +40298,7 @@ var ts;
if (!candidates.length) {
// We didn't have any sig help items produced by the TS compiler. If this is a JS
// file, then see if we can figure out anything better.
- if (ts.isJavaScript(sourceFile.fileName)) {
+ if (ts.isSourceFileJavaScript(sourceFile)) {
return createJavaScriptSignatureHelpItems(argumentInfo);
}
return undefined;
@@ -41662,9 +42158,9 @@ var ts;
}
Rules.prototype.getRuleName = function (rule) {
var o = this;
- for (var name_32 in o) {
- if (o[name_32] === rule) {
- return name_32;
+ for (var name_34 in o) {
+ if (o[name_34] === rule) {
+ return name_34;
}
}
throw new Error("Unknown rule");
@@ -42096,7 +42592,7 @@ var ts;
function TokenRangeAccess(from, to, except) {
this.tokens = [];
for (var token = from; token <= to; token++) {
- if (except.indexOf(token) < 0) {
+ if (ts.indexOf(except, token) < 0) {
this.tokens.push(token);
}
}
@@ -43709,13 +44205,18 @@ var ts;
];
var jsDocCompletionEntries;
function createNode(kind, pos, end, flags, parent) {
- var node = new (ts.getNodeConstructor(kind))(pos, end);
+ var node = new NodeObject(kind, pos, end);
node.flags = flags;
node.parent = parent;
return node;
}
var NodeObject = (function () {
- function NodeObject() {
+ function NodeObject(kind, pos, end) {
+ this.kind = kind;
+ this.pos = pos;
+ this.end = end;
+ this.flags = 0 /* None */;
+ this.parent = undefined;
}
NodeObject.prototype.getSourceFile = function () {
return ts.getSourceFileOfNode(this);
@@ -44198,8 +44699,8 @@ var ts;
})();
var SourceFileObject = (function (_super) {
__extends(SourceFileObject, _super);
- function SourceFileObject() {
- _super.apply(this, arguments);
+ function SourceFileObject(kind, pos, end) {
+ _super.call(this, kind, pos, end);
}
SourceFileObject.prototype.update = function (newText, textChangeRange) {
return ts.updateSourceFile(this, newText, textChangeRange);
@@ -44521,6 +45022,9 @@ var ts;
ClassificationTypeNames.typeAliasName = "type alias name";
ClassificationTypeNames.parameterName = "parameter name";
ClassificationTypeNames.docCommentTagName = "doc comment tag name";
+ ClassificationTypeNames.jsxOpenTagName = "jsx open tag name";
+ ClassificationTypeNames.jsxCloseTagName = "jsx close tag name";
+ ClassificationTypeNames.jsxSelfClosingTagName = "jsx self closing tag name";
return ClassificationTypeNames;
})();
ts.ClassificationTypeNames = ClassificationTypeNames;
@@ -44543,6 +45047,9 @@ var ts;
ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName";
ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName";
ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName";
+ ClassificationType[ClassificationType["jsxOpenTagName"] = 19] = "jsxOpenTagName";
+ ClassificationType[ClassificationType["jsxCloseTagName"] = 20] = "jsxCloseTagName";
+ ClassificationType[ClassificationType["jsxSelfClosingTagName"] = 21] = "jsxSelfClosingTagName";
})(ts.ClassificationType || (ts.ClassificationType = {}));
var ClassificationType = ts.ClassificationType;
function displayPartsToString(displayParts) {
@@ -44922,8 +45429,9 @@ var ts;
};
}
ts.createDocumentRegistry = createDocumentRegistry;
- function preProcessFile(sourceText, readImportFiles) {
+ function preProcessFile(sourceText, readImportFiles, detectJavaScriptImports) {
if (readImportFiles === void 0) { readImportFiles = true; }
+ if (detectJavaScriptImports === void 0) { detectJavaScriptImports = false; }
var referencedFiles = [];
var importedFiles = [];
var ambientExternalModules;
@@ -44957,116 +45465,66 @@ var ts;
end: pos + importPath.length
});
}
- function processImport() {
- scanner.setText(sourceText);
- var token = scanner.scan();
- // Look for:
- // import "mod";
- // import d from "mod"
- // import {a as A } from "mod";
- // import * as NS from "mod"
- // import d, {a, b as B} from "mod"
- // import i = require("mod");
- //
- // export * from "mod"
- // export {a as b} from "mod"
- // export import i = require("mod")
- while (token !== 1 /* EndOfFileToken */) {
- if (token === 122 /* DeclareKeyword */) {
- // declare module "mod"
- token = scanner.scan();
- if (token === 125 /* ModuleKeyword */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- recordAmbientExternalModule();
- continue;
- }
- }
- }
- else if (token === 89 /* ImportKeyword */) {
+ /**
+ * Returns true if at least one token was consumed from the stream
+ */
+ function tryConsumeDeclare() {
+ var token = scanner.getToken();
+ if (token === 122 /* DeclareKeyword */) {
+ // declare module "mod"
+ token = scanner.scan();
+ if (token === 125 /* ModuleKeyword */) {
token = scanner.scan();
if (token === 9 /* StringLiteral */) {
- // import "mod";
- recordModuleName();
- continue;
+ recordAmbientExternalModule();
}
- else {
- if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
+ }
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Returns true if at least one token was consumed from the stream
+ */
+ function tryConsumeImport() {
+ var token = scanner.getToken();
+ if (token === 89 /* ImportKeyword */) {
+ token = scanner.scan();
+ if (token === 9 /* StringLiteral */) {
+ // import "mod";
+ recordModuleName();
+ return true;
+ }
+ else {
+ if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
+ token = scanner.scan();
+ if (token === 133 /* FromKeyword */) {
token = scanner.scan();
- if (token === 133 /* FromKeyword */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // import d from "mod";
- recordModuleName();
- continue;
- }
- }
- else if (token === 56 /* EqualsToken */) {
- token = scanner.scan();
- if (token === 127 /* RequireKeyword */) {
- token = scanner.scan();
- if (token === 17 /* OpenParenToken */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // import i = require("mod");
- recordModuleName();
- continue;
- }
- }
- }
- }
- else if (token === 24 /* CommaToken */) {
- // consume comma and keep going
- token = scanner.scan();
- }
- else {
- // unknown syntax
- continue;
+ if (token === 9 /* StringLiteral */) {
+ // import d from "mod";
+ recordModuleName();
+ return true;
}
}
- if (token === 15 /* OpenBraceToken */) {
- token = scanner.scan();
- // consume "{ a as B, c, d as D}" clauses
- while (token !== 16 /* CloseBraceToken */) {
- token = scanner.scan();
- }
- if (token === 16 /* CloseBraceToken */) {
- token = scanner.scan();
- if (token === 133 /* FromKeyword */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // import {a as A} from "mod";
- // import d, {a, b as B} from "mod"
- recordModuleName();
- }
- }
+ else if (token === 56 /* EqualsToken */) {
+ if (tryConsumeRequireCall(/* skipCurrentToken */ true)) {
+ return true;
}
}
- else if (token === 37 /* AsteriskToken */) {
+ else if (token === 24 /* CommaToken */) {
+ // consume comma and keep going
token = scanner.scan();
- if (token === 116 /* AsKeyword */) {
- token = scanner.scan();
- if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
- token = scanner.scan();
- if (token === 133 /* FromKeyword */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // import * as NS from "mod"
- // import d, * as NS from "mod"
- recordModuleName();
- }
- }
- }
- }
+ }
+ else {
+ // unknown syntax
+ return true;
}
}
- }
- else if (token === 82 /* ExportKeyword */) {
- token = scanner.scan();
if (token === 15 /* OpenBraceToken */) {
token = scanner.scan();
// consume "{ a as B, c, d as D}" clauses
- while (token !== 16 /* CloseBraceToken */) {
+ // make sure that it stops on EOF
+ while (token !== 16 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
token = scanner.scan();
}
if (token === 16 /* CloseBraceToken */) {
@@ -45074,49 +45532,171 @@ var ts;
if (token === 133 /* FromKeyword */) {
token = scanner.scan();
if (token === 9 /* StringLiteral */) {
- // export {a as A} from "mod";
- // export {a, b as B} from "mod"
+ // import {a as A} from "mod";
+ // import d, {a, b as B} from "mod"
recordModuleName();
}
}
}
}
else if (token === 37 /* AsteriskToken */) {
+ token = scanner.scan();
+ if (token === 116 /* AsKeyword */) {
+ token = scanner.scan();
+ if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
+ token = scanner.scan();
+ if (token === 133 /* FromKeyword */) {
+ token = scanner.scan();
+ if (token === 9 /* StringLiteral */) {
+ // import * as NS from "mod"
+ // import d, * as NS from "mod"
+ recordModuleName();
+ }
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeExport() {
+ var token = scanner.getToken();
+ if (token === 82 /* ExportKeyword */) {
+ token = scanner.scan();
+ if (token === 15 /* OpenBraceToken */) {
+ token = scanner.scan();
+ // consume "{ a as B, c, d as D}" clauses
+ // make sure it stops on EOF
+ while (token !== 16 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
+ token = scanner.scan();
+ }
+ if (token === 16 /* CloseBraceToken */) {
token = scanner.scan();
if (token === 133 /* FromKeyword */) {
token = scanner.scan();
if (token === 9 /* StringLiteral */) {
- // export * from "mod"
+ // export {a as A} from "mod";
+ // export {a, b as B} from "mod"
recordModuleName();
}
}
}
- else if (token === 89 /* ImportKeyword */) {
+ }
+ else if (token === 37 /* AsteriskToken */) {
+ token = scanner.scan();
+ if (token === 133 /* FromKeyword */) {
token = scanner.scan();
- if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
- token = scanner.scan();
- if (token === 56 /* EqualsToken */) {
- token = scanner.scan();
- if (token === 127 /* RequireKeyword */) {
- token = scanner.scan();
- if (token === 17 /* OpenParenToken */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // export import i = require("mod");
- recordModuleName();
- }
- }
- }
+ if (token === 9 /* StringLiteral */) {
+ // export * from "mod"
+ recordModuleName();
+ }
+ }
+ }
+ else if (token === 89 /* ImportKeyword */) {
+ token = scanner.scan();
+ if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
+ token = scanner.scan();
+ if (token === 56 /* EqualsToken */) {
+ if (tryConsumeRequireCall(/* skipCurrentToken */ true)) {
+ return true;
}
}
}
}
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeRequireCall(skipCurrentToken) {
+ var token = skipCurrentToken ? scanner.scan() : scanner.getToken();
+ if (token === 127 /* RequireKeyword */) {
+ token = scanner.scan();
+ if (token === 17 /* OpenParenToken */) {
+ token = scanner.scan();
+ if (token === 9 /* StringLiteral */) {
+ // require("mod");
+ recordModuleName();
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeDefine() {
+ var token = scanner.getToken();
+ if (token === 69 /* Identifier */ && scanner.getTokenValue() === "define") {
+ token = scanner.scan();
+ if (token !== 17 /* OpenParenToken */) {
+ return true;
+ }
token = scanner.scan();
+ if (token === 9 /* StringLiteral */) {
+ // looks like define ("modname", ... - skip string literal and comma
+ token = scanner.scan();
+ if (token === 24 /* CommaToken */) {
+ token = scanner.scan();
+ }
+ else {
+ // unexpected token
+ return true;
+ }
+ }
+ // should be start of dependency list
+ if (token !== 19 /* OpenBracketToken */) {
+ return true;
+ }
+ // skip open bracket
+ token = scanner.scan();
+ var i = 0;
+ // scan until ']' or EOF
+ while (token !== 20 /* CloseBracketToken */ && token !== 1 /* EndOfFileToken */) {
+ // record string literals as module names
+ if (token === 9 /* StringLiteral */) {
+ recordModuleName();
+ i++;
+ }
+ token = scanner.scan();
+ }
+ return true;
+ }
+ return false;
+ }
+ function processImports() {
+ scanner.setText(sourceText);
+ scanner.scan();
+ // Look for:
+ // import "mod";
+ // import d from "mod"
+ // import {a as A } from "mod";
+ // import * as NS from "mod"
+ // import d, {a, b as B} from "mod"
+ // import i = require("mod");
+ //
+ // export * from "mod"
+ // export {a as b} from "mod"
+ // export import i = require("mod")
+ // (for JavaScript files) require("mod")
+ while (true) {
+ if (scanner.getToken() === 1 /* EndOfFileToken */) {
+ break;
+ }
+ // check if at least one of alternative have moved scanner forward
+ if (tryConsumeDeclare() ||
+ tryConsumeImport() ||
+ tryConsumeExport() ||
+ (detectJavaScriptImports && (tryConsumeRequireCall(/* skipCurrentToken */ false) || tryConsumeDefine()))) {
+ continue;
+ }
+ else {
+ scanner.scan();
+ }
}
scanner.setText(undefined);
}
if (readImportFiles) {
- processImport();
+ processImports();
}
processTripleSlashDirectives();
return { referencedFiles: referencedFiles, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientExternalModules };
@@ -45547,7 +46127,7 @@ var ts;
// For JavaScript files, we don't want to report the normal typescript semantic errors.
// Instead, we just report errors for using TypeScript-only constructs from within a
// JavaScript file.
- if (ts.isJavaScript(fileName)) {
+ if (ts.isSourceFileJavaScript(targetSourceFile)) {
return getJavaScriptSemanticDiagnostics(targetSourceFile);
}
// Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
@@ -45759,7 +46339,7 @@ var ts;
var typeChecker = program.getTypeChecker();
var syntacticStart = new Date().getTime();
var sourceFile = getValidSourceFile(fileName);
- var isJavaScriptFile = ts.isJavaScript(fileName);
+ var isJavaScriptFile = ts.isSourceFileJavaScript(sourceFile);
var isJsDocTagName = false;
var start = new Date().getTime();
var currentToken = ts.getTokenAtPosition(sourceFile, position);
@@ -46393,8 +46973,8 @@ var ts;
if (element.getStart() <= position && position <= element.getEnd()) {
continue;
}
- var name_33 = element.propertyName || element.name;
- exisingImportsOrExports[name_33.text] = true;
+ var name_35 = element.propertyName || element.name;
+ exisingImportsOrExports[name_35.text] = true;
}
if (ts.isEmpty(exisingImportsOrExports)) {
return exportsOfModule;
@@ -46426,7 +47006,10 @@ var ts;
}
var existingName = void 0;
if (m.kind === 163 /* BindingElement */ && m.propertyName) {
- existingName = m.propertyName.text;
+ // include only identifiers in completion list
+ if (m.propertyName.kind === 69 /* Identifier */) {
+ existingName = m.propertyName.text;
+ }
}
else {
// TODO(jfreeman): Account for computed property name
@@ -46466,46 +47049,43 @@ var ts;
return undefined;
}
var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName;
- var entries;
if (isJsDocTagName) {
// If the current position is a jsDoc tag name, only tag names should be provided for completion
return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() };
}
- if (isRightOfDot && ts.isJavaScript(fileName)) {
- entries = getCompletionEntriesFromSymbols(symbols);
- ts.addRange(entries, getJavaScriptCompletionEntries());
+ var sourceFile = getValidSourceFile(fileName);
+ var entries = [];
+ if (isRightOfDot && ts.isSourceFileJavaScript(sourceFile)) {
+ var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries);
+ ts.addRange(entries, getJavaScriptCompletionEntries(sourceFile, uniqueNames));
}
else {
if (!symbols || symbols.length === 0) {
return undefined;
}
- entries = getCompletionEntriesFromSymbols(symbols);
+ getCompletionEntriesFromSymbols(symbols, entries);
}
// Add keywords if this is not a member completion list
if (!isMemberCompletion && !isJsDocTagName) {
ts.addRange(entries, keywordCompletions);
}
return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
- function getJavaScriptCompletionEntries() {
+ function getJavaScriptCompletionEntries(sourceFile, uniqueNames) {
var entries = [];
- var allNames = {};
var target = program.getCompilerOptions().target;
- for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
- var sourceFile = _a[_i];
- var nameTable = getNameTable(sourceFile);
- for (var name_34 in nameTable) {
- if (!allNames[name_34]) {
- allNames[name_34] = name_34;
- var displayName = getCompletionEntryDisplayName(name_34, target, /*performCharacterChecks:*/ true);
- if (displayName) {
- var entry = {
- name: displayName,
- kind: ScriptElementKind.warning,
- kindModifiers: "",
- sortText: "1"
- };
- entries.push(entry);
- }
+ var nameTable = getNameTable(sourceFile);
+ for (var name_36 in nameTable) {
+ if (!uniqueNames[name_36]) {
+ uniqueNames[name_36] = name_36;
+ var displayName = getCompletionEntryDisplayName(name_36, target, /*performCharacterChecks:*/ true);
+ if (displayName) {
+ var entry = {
+ name: displayName,
+ kind: ScriptElementKind.warning,
+ kindModifiers: "",
+ sortText: "1"
+ };
+ entries.push(entry);
}
}
}
@@ -46543,25 +47123,24 @@ var ts;
sortText: "0"
};
}
- function getCompletionEntriesFromSymbols(symbols) {
+ function getCompletionEntriesFromSymbols(symbols, entries) {
var start = new Date().getTime();
- var entries = [];
+ var uniqueNames = {};
if (symbols) {
- var nameToSymbol = {};
for (var _i = 0, symbols_3 = symbols; _i < symbols_3.length; _i++) {
var symbol = symbols_3[_i];
var entry = createCompletionEntry(symbol, location);
if (entry) {
var id = ts.escapeIdentifier(entry.name);
- if (!ts.lookUp(nameToSymbol, id)) {
+ if (!ts.lookUp(uniqueNames, id)) {
entries.push(entry);
- nameToSymbol[id] = symbol;
+ uniqueNames[id] = id;
}
}
}
}
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
- return entries;
+ return uniqueNames;
}
}
function getCompletionEntryDetails(fileName, position, entryName) {
@@ -46762,16 +47341,16 @@ var ts;
case ScriptElementKind.parameterElement:
case ScriptElementKind.localVariableElement:
// If it is call or construct signature of lambda's write type name
- displayParts.push(ts.punctuationPart(54 /* ColonToken */));
+ displayParts.push(ts.punctuationPart(ts.SyntaxKind.ColonToken));
displayParts.push(ts.spacePart());
if (useConstructSignatures) {
- displayParts.push(ts.keywordPart(92 /* NewKeyword */));
+ displayParts.push(ts.keywordPart(ts.SyntaxKind.NewKeyword));
displayParts.push(ts.spacePart());
}
- if (!(type.flags & 65536 /* Anonymous */)) {
- ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */));
+ if (!(type.flags & ts.TypeFlags.Anonymous)) {
+ ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, ts.SymbolFormatFlags.WriteTypeParametersOrArguments));
}
- addSignatureDisplayParts(signature, allSignatures, 8 /* WriteArrowStyleSignature */);
+ addSignatureDisplayParts(signature, allSignatures, ts.TypeFormatFlags.WriteArrowStyleSignature);
break;
default:
// Just signature
@@ -48396,19 +48975,19 @@ var ts;
if (isNameOfPropertyAssignment(node)) {
var objectLiteral = node.parent.parent;
var contextualType = typeChecker.getContextualType(objectLiteral);
- var name_35 = node.text;
+ var name_37 = node.text;
if (contextualType) {
if (contextualType.flags & 16384 /* Union */) {
// This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types)
// if not, search the constituent types for the property
- var unionProperty = contextualType.getProperty(name_35);
+ var unionProperty = contextualType.getProperty(name_37);
if (unionProperty) {
return [unionProperty];
}
else {
var result_4 = [];
ts.forEach(contextualType.types, function (t) {
- var symbol = t.getProperty(name_35);
+ var symbol = t.getProperty(name_37);
if (symbol) {
result_4.push(symbol);
}
@@ -48417,7 +48996,7 @@ var ts;
}
}
else {
- var symbol_1 = contextualType.getProperty(name_35);
+ var symbol_1 = contextualType.getProperty(name_37);
if (symbol_1) {
return [symbol_1];
}
@@ -48828,6 +49407,9 @@ var ts;
case 16 /* typeAliasName */: return ClassificationTypeNames.typeAliasName;
case 17 /* parameterName */: return ClassificationTypeNames.parameterName;
case 18 /* docCommentTagName */: return ClassificationTypeNames.docCommentTagName;
+ case 19 /* jsxOpenTagName */: return ClassificationTypeNames.jsxOpenTagName;
+ case 20 /* jsxCloseTagName */: return ClassificationTypeNames.jsxCloseTagName;
+ case 21 /* jsxSelfClosingTagName */: return ClassificationTypeNames.jsxSelfClosingTagName;
}
}
function convertClassifications(classifications) {
@@ -49097,6 +49679,21 @@ var ts;
return 17 /* parameterName */;
}
return;
+ case 235 /* JsxOpeningElement */:
+ if (token.parent.tagName === token) {
+ return 19 /* jsxOpenTagName */;
+ }
+ return;
+ case 237 /* JsxClosingElement */:
+ if (token.parent.tagName === token) {
+ return 20 /* jsxCloseTagName */;
+ }
+ return;
+ case 234 /* JsxSelfClosingElement */:
+ if (token.parent.tagName === token) {
+ return 21 /* jsxSelfClosingTagName */;
+ }
+ return;
}
}
return 2 /* identifier */;
@@ -50021,18 +50618,8 @@ var ts;
ts.getDefaultLibFilePath = getDefaultLibFilePath;
function initializeServices() {
ts.objectAllocator = {
- getNodeConstructor: function (kind) {
- function Node(pos, end) {
- this.pos = pos;
- this.end = end;
- this.flags = 0 /* None */;
- this.parent = undefined;
- }
- var proto = kind === 248 /* SourceFile */ ? new SourceFileObject() : new NodeObject();
- proto.kind = kind;
- Node.prototype = proto;
- return Node;
- },
+ getNodeConstructor: function () { return NodeObject; },
+ getSourceFileConstructor: function () { return SourceFileObject; },
getSymbolConstructor: function () { return SymbolObject; },
getTypeConstructor: function () { return TypeObject; },
getSignatureConstructor: function () { return SignatureObject; }
@@ -51102,7 +51689,8 @@ var ts;
};
CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) {
return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () {
- var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()));
+ // for now treat files as JavaScript
+ var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true);
var convertResult = {
referencedFiles: [],
importedFiles: [],
@@ -51166,7 +51754,7 @@ var ts;
TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) {
try {
if (this.documentRegistry === undefined) {
- this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
+ this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory());
}
var hostAdapter = new LanguageServiceShimHostAdapter(host);
var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry);
@@ -51199,7 +51787,7 @@ var ts;
TypeScriptServicesFactory.prototype.close = function () {
// Forget all the registered shims
this._shims = [];
- this.documentRegistry = ts.createDocumentRegistry();
+ this.documentRegistry = undefined;
};
TypeScriptServicesFactory.prototype.registerShim = function (shim) {
this._shims.push(shim);
diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts
index d2758e6d5e9a7..af9a8bffe3574 100644
--- a/lib/typescriptServices.d.ts
+++ b/lib/typescriptServices.d.ts
@@ -387,6 +387,7 @@ declare namespace ts {
right: Identifier;
}
type EntityName = Identifier | QualifiedName;
+ type PropertyName = Identifier | LiteralExpression | ComputedPropertyName;
type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern;
interface Declaration extends Node {
_declarationBrand: any;
@@ -425,7 +426,7 @@ declare namespace ts {
initializer?: Expression;
}
interface BindingElement extends Declaration {
- propertyName?: Identifier;
+ propertyName?: PropertyName;
dotDotDotToken?: Node;
name: Identifier | BindingPattern;
initializer?: Expression;
@@ -452,7 +453,7 @@ declare namespace ts {
objectAssignmentInitializer?: Expression;
}
interface VariableLikeDeclaration extends Declaration {
- propertyName?: Identifier;
+ propertyName?: PropertyName;
dotDotDotToken?: Node;
name: DeclarationName;
questionToken?: Node;
@@ -581,7 +582,7 @@ declare namespace ts {
asteriskToken?: Node;
expression?: Expression;
}
- interface BinaryExpression extends Expression {
+ interface BinaryExpression extends Expression, Declaration {
left: Expression;
operatorToken: Node;
right: Expression;
@@ -625,7 +626,7 @@ declare namespace ts {
interface ObjectLiteralExpression extends PrimaryExpression, Declaration {
properties: NodeArray;
}
- interface PropertyAccessExpression extends MemberExpression {
+ interface PropertyAccessExpression extends MemberExpression, Declaration {
expression: LeftHandSideExpression;
dotToken: Node;
name: Identifier;
@@ -1220,6 +1221,7 @@ declare namespace ts {
ObjectLiteral = 524288,
ESSymbol = 16777216,
ThisType = 33554432,
+ ObjectLiteralPatternWithComputedProperties = 67108864,
StringLike = 258,
NumberLike = 132,
ObjectType = 80896,
@@ -1537,7 +1539,6 @@ declare namespace ts {
function getTypeParameterOwner(d: Declaration): Declaration;
}
declare namespace ts {
- function getNodeConstructor(kind: SyntaxKind): new (pos?: number, end?: number) => Node;
function createNode(kind: SyntaxKind, pos?: number, end?: number): Node;
function forEachChild(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T;
function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes?: boolean): SourceFile;
@@ -2126,6 +2127,9 @@ declare namespace ts {
static typeAliasName: string;
static parameterName: string;
static docCommentTagName: string;
+ static jsxOpenTagName: string;
+ static jsxCloseTagName: string;
+ static jsxSelfClosingTagName: string;
}
enum ClassificationType {
comment = 1,
@@ -2146,6 +2150,9 @@ declare namespace ts {
typeAliasName = 16,
parameterName = 17,
docCommentTagName = 18,
+ jsxOpenTagName = 19,
+ jsxCloseTagName = 20,
+ jsxSelfClosingTagName = 21,
}
interface DisplayPartsSymbolWriter extends SymbolWriter {
displayParts(): SymbolDisplayPart[];
@@ -2171,7 +2178,7 @@ declare namespace ts {
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile;
function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string;
function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry;
- function preProcessFile(sourceText: string, readImportFiles?: boolean): PreProcessedFileInfo;
+ function preProcessFile(sourceText: string, readImportFiles?: boolean, detectJavaScriptImports?: boolean): PreProcessedFileInfo;
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry): LanguageService;
function createClassifier(): Classifier;
/**
diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js
index 8b0ef04f96e45..498ddc3786075 100644
--- a/lib/typescriptServices.js
+++ b/lib/typescriptServices.js
@@ -622,6 +622,7 @@ var ts;
TypeFlags[TypeFlags["ContainsAnyFunctionType"] = 8388608] = "ContainsAnyFunctionType";
TypeFlags[TypeFlags["ESSymbol"] = 16777216] = "ESSymbol";
TypeFlags[TypeFlags["ThisType"] = 33554432] = "ThisType";
+ TypeFlags[TypeFlags["ObjectLiteralPatternWithComputedProperties"] = 67108864] = "ObjectLiteralPatternWithComputedProperties";
/* @internal */
TypeFlags[TypeFlags["Intrinsic"] = 16777343] = "Intrinsic";
/* @internal */
@@ -1530,12 +1531,7 @@ var ts;
* List of supported extensions in order of file resolution precedence.
*/
ts.supportedExtensions = [".ts", ".tsx", ".d.ts"];
- /**
- * List of extensions that will be used to look for external modules.
- * This list is kept separate from supportedExtensions to for cases when we'll allow to include .js files in compilation,
- * but still would like to load only TypeScript files as modules
- */
- ts.moduleFileExtensions = ts.supportedExtensions;
+ ts.supportedJsExtensions = ts.supportedExtensions.concat(".js", ".jsx");
function isSupportedSourceFileName(fileName) {
if (!fileName) {
return false;
@@ -1586,17 +1582,16 @@ var ts;
}
function Signature(checker) {
}
+ function Node(kind, pos, end) {
+ this.kind = kind;
+ this.pos = pos;
+ this.end = end;
+ this.flags = 0 /* None */;
+ this.parent = undefined;
+ }
ts.objectAllocator = {
- getNodeConstructor: function (kind) {
- function Node(pos, end) {
- this.pos = pos;
- this.end = end;
- this.flags = 0 /* None */;
- this.parent = undefined;
- }
- Node.prototype = { kind: kind };
- return Node;
- },
+ getNodeConstructor: function () { return Node; },
+ getSourceFileConstructor: function () { return Node; },
getSymbolConstructor: function () { return Symbol; },
getTypeConstructor: function () { return Type; },
getSignatureConstructor: function () { return Signature; }
@@ -1913,7 +1908,16 @@ var ts;
if (writeByteOrderMark) {
data = "\uFEFF" + data;
}
- _fs.writeFileSync(fileName, data, "utf8");
+ var fd;
+ try {
+ fd = _fs.openSync(fileName, "w");
+ _fs.writeSync(fd, data, undefined, "utf8");
+ }
+ finally {
+ if (fd !== undefined) {
+ _fs.closeSync(fd);
+ }
+ }
}
function getCanonicalPath(path) {
return useCaseSensitiveFileNames ? path.toLowerCase() : path;
@@ -2614,6 +2618,7 @@ var ts;
Disallow_inconsistently_cased_references_to_the_same_file: { code: 6078, category: ts.DiagnosticCategory.Message, key: "Disallow_inconsistently_cased_references_to_the_same_file_6078", message: "Disallow inconsistently-cased references to the same file." },
Specify_JSX_code_generation_Colon_preserve_or_react: { code: 6080, category: ts.DiagnosticCategory.Message, key: "Specify_JSX_code_generation_Colon_preserve_or_react_6080", message: "Specify JSX code generation: 'preserve' or 'react'" },
Argument_for_jsx_must_be_preserve_or_react: { code: 6081, category: ts.DiagnosticCategory.Message, key: "Argument_for_jsx_must_be_preserve_or_react_6081", message: "Argument for '--jsx' must be 'preserve' or 'react'." },
+ Only_amd_and_system_modules_are_supported_alongside_0: { code: 6082, category: ts.DiagnosticCategory.Error, key: "Only_amd_and_system_modules_are_supported_alongside_0_6082", message: "Only 'amd' and 'system' modules are supported alongside --{0}." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." },
@@ -3173,7 +3178,7 @@ var ts;
function getCommentRanges(text, pos, trailing) {
var result;
var collecting = trailing || pos === 0;
- while (true) {
+ while (pos < text.length) {
var ch = text.charCodeAt(pos);
switch (ch) {
case 13 /* carriageReturn */:
@@ -3242,6 +3247,7 @@ var ts;
}
return result;
}
+ return result;
}
function getLeadingCommentRanges(text, pos) {
return getCommentRanges(text, pos, /*trailing*/ false);
@@ -3343,7 +3349,7 @@ var ts;
error(ts.Diagnostics.Digit_expected);
}
}
- return +(text.substring(start, end));
+ return "" + +(text.substring(start, end));
}
function scanOctalDigits() {
var start = pos;
@@ -3770,7 +3776,7 @@ var ts;
return pos++, token = 36 /* MinusToken */;
case 46 /* dot */:
if (isDigit(text.charCodeAt(pos + 1))) {
- tokenValue = "" + scanNumber();
+ tokenValue = scanNumber();
return token = 8 /* NumericLiteral */;
}
if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) {
@@ -3873,7 +3879,7 @@ var ts;
case 55 /* _7 */:
case 56 /* _8 */:
case 57 /* _9 */:
- tokenValue = "" + scanNumber();
+ tokenValue = scanNumber();
return token = 8 /* NumericLiteral */;
case 58 /* colon */:
return pos++, token = 54 /* ColonToken */;
@@ -4177,1558 +4183,243 @@ var ts;
}
ts.createScanner = createScanner;
})(ts || (ts = {}));
-///
+///
/* @internal */
var ts;
(function (ts) {
- ts.bindTime = 0;
- (function (ModuleInstanceState) {
- ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
- ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
- ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
- })(ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
- var ModuleInstanceState = ts.ModuleInstanceState;
- var Reachability;
- (function (Reachability) {
- Reachability[Reachability["Unintialized"] = 1] = "Unintialized";
- Reachability[Reachability["Reachable"] = 2] = "Reachable";
- Reachability[Reachability["Unreachable"] = 4] = "Unreachable";
- Reachability[Reachability["ReportedUnreachable"] = 8] = "ReportedUnreachable";
- })(Reachability || (Reachability = {}));
- function or(state1, state2) {
- return (state1 | state2) & 2 /* Reachable */
- ? 2 /* Reachable */
- : (state1 & state2) & 8 /* ReportedUnreachable */
- ? 8 /* ReportedUnreachable */
- : 4 /* Unreachable */;
- }
- function getModuleInstanceState(node) {
- // A module is uninstantiated if it contains only
- // 1. interface declarations, type alias declarations
- if (node.kind === 215 /* InterfaceDeclaration */ || node.kind === 216 /* TypeAliasDeclaration */) {
- return 0 /* NonInstantiated */;
+ function getDeclarationOfKind(symbol, kind) {
+ var declarations = symbol.declarations;
+ if (declarations) {
+ for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
+ var declaration = declarations_1[_i];
+ if (declaration.kind === kind) {
+ return declaration;
+ }
+ }
}
- else if (ts.isConstEnumDeclaration(node)) {
- return 2 /* ConstEnumOnly */;
+ return undefined;
+ }
+ ts.getDeclarationOfKind = getDeclarationOfKind;
+ // Pool writers to avoid needing to allocate them for every symbol we write.
+ var stringWriters = [];
+ function getSingleLineStringWriter() {
+ if (stringWriters.length === 0) {
+ var str = "";
+ var writeText = function (text) { return str += text; };
+ return {
+ string: function () { return str; },
+ writeKeyword: writeText,
+ writeOperator: writeText,
+ writePunctuation: writeText,
+ writeSpace: writeText,
+ writeStringLiteral: writeText,
+ writeParameter: writeText,
+ writeSymbol: writeText,
+ // Completely ignore indentation for string writers. And map newlines to
+ // a single space.
+ writeLine: function () { return str += " "; },
+ increaseIndent: function () { },
+ decreaseIndent: function () { },
+ clear: function () { return str = ""; },
+ trackSymbol: function () { },
+ reportInaccessibleThisError: function () { }
+ };
}
- else if ((node.kind === 222 /* ImportDeclaration */ || node.kind === 221 /* ImportEqualsDeclaration */) && !(node.flags & 2 /* Export */)) {
- return 0 /* NonInstantiated */;
+ return stringWriters.pop();
+ }
+ ts.getSingleLineStringWriter = getSingleLineStringWriter;
+ function releaseStringWriter(writer) {
+ writer.clear();
+ stringWriters.push(writer);
+ }
+ ts.releaseStringWriter = releaseStringWriter;
+ function getFullWidth(node) {
+ return node.end - node.pos;
+ }
+ ts.getFullWidth = getFullWidth;
+ function arrayIsEqualTo(array1, array2, equaler) {
+ if (!array1 || !array2) {
+ return array1 === array2;
}
- else if (node.kind === 219 /* ModuleBlock */) {
- var state = 0 /* NonInstantiated */;
- ts.forEachChild(node, function (n) {
- switch (getModuleInstanceState(n)) {
- case 0 /* NonInstantiated */:
- // child is non-instantiated - continue searching
- return false;
- case 2 /* ConstEnumOnly */:
- // child is const enum only - record state and continue searching
- state = 2 /* ConstEnumOnly */;
- return false;
- case 1 /* Instantiated */:
- // child is instantiated - record state and stop
- state = 1 /* Instantiated */;
- return true;
- }
- });
- return state;
+ if (array1.length !== array2.length) {
+ return false;
}
- else if (node.kind === 218 /* ModuleDeclaration */) {
- return getModuleInstanceState(node.body);
+ for (var i = 0; i < array1.length; ++i) {
+ var equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
+ if (!equals) {
+ return false;
+ }
}
- else {
- return 1 /* Instantiated */;
+ return true;
+ }
+ ts.arrayIsEqualTo = arrayIsEqualTo;
+ function hasResolvedModule(sourceFile, moduleNameText) {
+ return sourceFile.resolvedModules && ts.hasProperty(sourceFile.resolvedModules, moduleNameText);
+ }
+ ts.hasResolvedModule = hasResolvedModule;
+ function getResolvedModule(sourceFile, moduleNameText) {
+ return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
+ }
+ ts.getResolvedModule = getResolvedModule;
+ function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
+ if (!sourceFile.resolvedModules) {
+ sourceFile.resolvedModules = {};
}
+ sourceFile.resolvedModules[moduleNameText] = resolvedModule;
}
- ts.getModuleInstanceState = getModuleInstanceState;
- var ContainerFlags;
- (function (ContainerFlags) {
- // The current node is not a container, and no container manipulation should happen before
- // recursing into it.
- ContainerFlags[ContainerFlags["None"] = 0] = "None";
- // The current node is a container. It should be set as the current container (and block-
- // container) before recursing into it. The current node does not have locals. Examples:
- //
- // Classes, ObjectLiterals, TypeLiterals, Interfaces...
- ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
- // The current node is a block-scoped-container. It should be set as the current block-
- // container before recursing into it. Examples:
- //
- // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
- ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
- ContainerFlags[ContainerFlags["HasLocals"] = 4] = "HasLocals";
- // If the current node is a container that also container that also contains locals. Examples:
- //
- // Functions, Methods, Modules, Source-files.
- ContainerFlags[ContainerFlags["IsContainerWithLocals"] = 5] = "IsContainerWithLocals";
- })(ContainerFlags || (ContainerFlags = {}));
- var binder = createBinder();
- function bindSourceFile(file, options) {
- var start = new Date().getTime();
- binder(file, options);
- ts.bindTime += new Date().getTime() - start;
+ ts.setResolvedModule = setResolvedModule;
+ // Returns true if this node contains a parse error anywhere underneath it.
+ function containsParseError(node) {
+ aggregateChildData(node);
+ return (node.parserContextFlags & 64 /* ThisNodeOrAnySubNodesHasError */) !== 0;
}
- ts.bindSourceFile = bindSourceFile;
- function createBinder() {
- var file;
- var options;
- var parent;
- var container;
- var blockScopeContainer;
- var lastContainer;
- var seenThisKeyword;
- // state used by reachability checks
- var hasExplicitReturn;
- var currentReachabilityState;
- var labelStack;
- var labelIndexMap;
- var implicitLabels;
- // If this file is an external module, then it is automatically in strict-mode according to
- // ES6. If it is not an external module, then we'll determine if it is in strict mode or
- // not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
- var inStrictMode;
- var symbolCount = 0;
- var Symbol;
- var classifiableNames;
- function bindSourceFile(f, opts) {
- file = f;
- options = opts;
- inStrictMode = !!file.externalModuleIndicator;
- classifiableNames = {};
- Symbol = ts.objectAllocator.getSymbolConstructor();
- if (!file.locals) {
- bind(file);
- file.symbolCount = symbolCount;
- file.classifiableNames = classifiableNames;
+ ts.containsParseError = containsParseError;
+ function aggregateChildData(node) {
+ if (!(node.parserContextFlags & 128 /* HasAggregatedChildData */)) {
+ // A node is considered to contain a parse error if:
+ // a) the parser explicitly marked that it had an error
+ // b) any of it's children reported that it had an error.
+ var thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & 16 /* ThisNodeHasError */) !== 0) ||
+ ts.forEachChild(node, containsParseError);
+ // If so, mark ourselves accordingly.
+ if (thisNodeOrAnySubNodesHasError) {
+ node.parserContextFlags |= 64 /* ThisNodeOrAnySubNodesHasError */;
}
- parent = undefined;
- container = undefined;
- blockScopeContainer = undefined;
- lastContainer = undefined;
- seenThisKeyword = false;
- hasExplicitReturn = false;
- labelStack = undefined;
- labelIndexMap = undefined;
- implicitLabels = undefined;
+ // Also mark that we've propogated the child information to this node. This way we can
+ // always consult the bit directly on this node without needing to check its children
+ // again.
+ node.parserContextFlags |= 128 /* HasAggregatedChildData */;
}
- return bindSourceFile;
- function createSymbol(flags, name) {
- symbolCount++;
- return new Symbol(flags, name);
+ }
+ function getSourceFileOfNode(node) {
+ while (node && node.kind !== 248 /* SourceFile */) {
+ node = node.parent;
}
- function addDeclarationToSymbol(symbol, node, symbolFlags) {
- symbol.flags |= symbolFlags;
- node.symbol = symbol;
- if (!symbol.declarations) {
- symbol.declarations = [];
- }
- symbol.declarations.push(node);
- if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) {
- symbol.exports = {};
- }
- if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) {
- symbol.members = {};
- }
- if (symbolFlags & 107455 /* Value */ && !symbol.valueDeclaration) {
- symbol.valueDeclaration = node;
- }
+ return node;
+ }
+ ts.getSourceFileOfNode = getSourceFileOfNode;
+ function getStartPositionOfLine(line, sourceFile) {
+ ts.Debug.assert(line >= 0);
+ return ts.getLineStarts(sourceFile)[line];
+ }
+ ts.getStartPositionOfLine = getStartPositionOfLine;
+ // This is a useful function for debugging purposes.
+ function nodePosToString(node) {
+ var file = getSourceFileOfNode(node);
+ var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
+ return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
+ }
+ ts.nodePosToString = nodePosToString;
+ function getStartPosOfNode(node) {
+ return node.pos;
+ }
+ ts.getStartPosOfNode = getStartPosOfNode;
+ // Returns true if this node is missing from the actual source code. A 'missing' node is different
+ // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
+ // in the tree), it is definitely missing. However, a node may be defined, but still be
+ // missing. This happens whenever the parser knows it needs to parse something, but can't
+ // get anything in the source code that it expects at that location. For example:
+ //
+ // let a: ;
+ //
+ // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
+ // code). So the parser will attempt to parse out a type, and will create an actual node.
+ // However, this node will be 'missing' in the sense that no actual source-code/tokens are
+ // contained within it.
+ function nodeIsMissing(node) {
+ if (!node) {
+ return true;
}
- // Should not be called on a declaration with a computed property name,
- // unless it is a well known Symbol.
- function getDeclarationName(node) {
- if (node.name) {
- if (node.kind === 218 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */) {
- return "\"" + node.name.text + "\"";
- }
- if (node.name.kind === 136 /* ComputedPropertyName */) {
- var nameExpression = node.name.expression;
- ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
- return ts.getPropertyNameForKnownSymbolName(nameExpression.name.text);
- }
- return node.name.text;
- }
- switch (node.kind) {
- case 144 /* Constructor */:
- return "__constructor";
- case 152 /* FunctionType */:
- case 147 /* CallSignature */:
- return "__call";
- case 153 /* ConstructorType */:
- case 148 /* ConstructSignature */:
- return "__new";
- case 149 /* IndexSignature */:
- return "__index";
- case 228 /* ExportDeclaration */:
- return "__export";
- case 227 /* ExportAssignment */:
- return node.isExportEquals ? "export=" : "default";
- case 213 /* FunctionDeclaration */:
- case 214 /* ClassDeclaration */:
- return node.flags & 512 /* Default */ ? "default" : undefined;
- }
+ return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
+ }
+ ts.nodeIsMissing = nodeIsMissing;
+ function nodeIsPresent(node) {
+ return !nodeIsMissing(node);
+ }
+ ts.nodeIsPresent = nodeIsPresent;
+ function getTokenPosOfNode(node, sourceFile) {
+ // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
+ // want to skip trivia because this will launch us forward to the next token.
+ if (nodeIsMissing(node)) {
+ return node.pos;
}
- function getDisplayName(node) {
- return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node);
+ return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
+ }
+ ts.getTokenPosOfNode = getTokenPosOfNode;
+ function getNonDecoratorTokenPosOfNode(node, sourceFile) {
+ if (nodeIsMissing(node) || !node.decorators) {
+ return getTokenPosOfNode(node, sourceFile);
}
- /**
- * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names.
- * @param symbolTable - The symbol table which node will be added to.
- * @param parent - node's parent declaration.
- * @param node - The declaration to be added to the symbol table
- * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
- * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
- */
- function declareSymbol(symbolTable, parent, node, includes, excludes) {
- ts.Debug.assert(!ts.hasDynamicName(node));
- var isDefaultExport = node.flags & 512 /* Default */;
- // The exported symbol for an export default function/class node is always named "default"
- var name = isDefaultExport && parent ? "default" : getDeclarationName(node);
- var symbol;
- if (name !== undefined) {
- // Check and see if the symbol table already has a symbol with this name. If not,
- // create a new symbol with this name and add it to the table. Note that we don't
- // give the new symbol any flags *yet*. This ensures that it will not conflict
- // with the 'excludes' flags we pass in.
- //
- // If we do get an existing symbol, see if it conflicts with the new symbol we're
- // creating. For example, a 'var' symbol and a 'class' symbol will conflict within
- // the same symbol table. If we have a conflict, report the issue on each
- // declaration we have for this symbol, and then create a new symbol for this
- // declaration.
- //
- // If we created a new symbol, either because we didn't have a symbol with this name
- // in the symbol table, or we conflicted with an existing symbol, then just add this
- // node as the sole declaration of the new symbol.
- //
- // Otherwise, we'll be merging into a compatible existing symbol (for example when
- // you have multiple 'vars' with the same name in the same container). In this case
- // just add this node into the declarations list of the symbol.
- symbol = ts.hasProperty(symbolTable, name)
- ? symbolTable[name]
- : (symbolTable[name] = createSymbol(0 /* None */, name));
- if (name && (includes & 788448 /* Classifiable */)) {
- classifiableNames[name] = name;
- }
- if (symbol.flags & excludes) {
- if (node.name) {
- node.name.parent = node;
- }
- // Report errors every position with duplicate declaration
- // Report errors on previous encountered declarations
- var message = symbol.flags & 2 /* BlockScopedVariable */
- ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
- : ts.Diagnostics.Duplicate_identifier_0;
- ts.forEach(symbol.declarations, function (declaration) {
- if (declaration.flags & 512 /* Default */) {
- message = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
- }
- });
- ts.forEach(symbol.declarations, function (declaration) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
- });
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
- symbol = createSymbol(0 /* None */, name);
- }
- }
- else {
- symbol = createSymbol(0 /* None */, "__missing");
- }
- addDeclarationToSymbol(symbol, node, includes);
- symbol.parent = parent;
- return symbol;
+ return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
+ }
+ ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
+ function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
+ if (includeTrivia === void 0) { includeTrivia = false; }
+ if (nodeIsMissing(node)) {
+ return "";
}
- function declareModuleMember(node, symbolFlags, symbolExcludes) {
- var hasExportModifier = ts.getCombinedNodeFlags(node) & 2 /* Export */;
- if (symbolFlags & 8388608 /* Alias */) {
- if (node.kind === 230 /* ExportSpecifier */ || (node.kind === 221 /* ImportEqualsDeclaration */ && hasExportModifier)) {
- return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- }
- else {
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
+ var text = sourceFile.text;
+ return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end);
+ }
+ ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
+ function getTextOfNodeFromSourceText(sourceText, node) {
+ if (nodeIsMissing(node)) {
+ return "";
+ }
+ return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
+ }
+ ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
+ function getTextOfNode(node, includeTrivia) {
+ if (includeTrivia === void 0) { includeTrivia = false; }
+ return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
+ }
+ ts.getTextOfNode = getTextOfNode;
+ // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
+ function escapeIdentifier(identifier) {
+ return identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier;
+ }
+ ts.escapeIdentifier = escapeIdentifier;
+ // Remove extra underscore from escaped identifier
+ function unescapeIdentifier(identifier) {
+ return identifier.length >= 3 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ && identifier.charCodeAt(2) === 95 /* _ */ ? identifier.substr(1) : identifier;
+ }
+ ts.unescapeIdentifier = unescapeIdentifier;
+ // Make an identifier from an external module name by extracting the string after the last "/" and replacing
+ // all non-alphanumeric characters with underscores
+ function makeIdentifierFromModuleName(moduleName) {
+ return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
+ }
+ ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
+ function isBlockOrCatchScoped(declaration) {
+ return (getCombinedNodeFlags(declaration) & 24576 /* BlockScoped */) !== 0 ||
+ isCatchClauseVariableDeclaration(declaration);
+ }
+ ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
+ // Gets the nearest enclosing block scope container that has the provided node
+ // as a descendant, that is not the provided node.
+ function getEnclosingBlockScopeContainer(node) {
+ var current = node.parent;
+ while (current) {
+ if (isFunctionLike(current)) {
+ return current;
}
- else {
- // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue,
- // ExportType, or ExportContainer flag, and an associated export symbol with all the correct flags set
- // on it. There are 2 main reasons:
- //
- // 1. We treat locals and exports of the same name as mutually exclusive within a container.
- // That means the binder will issue a Duplicate Identifier error if you mix locals and exports
- // with the same name in the same container.
- // TODO: Make this a more specific error and decouple it from the exclusion logic.
- // 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
- // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
- // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
- if (hasExportModifier || container.flags & 131072 /* ExportContext */) {
- var exportKind = (symbolFlags & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0) |
- (symbolFlags & 793056 /* Type */ ? 2097152 /* ExportType */ : 0) |
- (symbolFlags & 1536 /* Namespace */ ? 4194304 /* ExportNamespace */ : 0);
- var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
- local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- node.localSymbol = local;
- return local;
- }
- else {
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
+ switch (current.kind) {
+ case 248 /* SourceFile */:
+ case 220 /* CaseBlock */:
+ case 244 /* CatchClause */:
+ case 218 /* ModuleDeclaration */:
+ case 199 /* ForStatement */:
+ case 200 /* ForInStatement */:
+ case 201 /* ForOfStatement */:
+ return current;
+ case 192 /* Block */:
+ // function block is not considered block-scope container
+ // see comment in binder.ts: bind(...), case for SyntaxKind.Block
+ if (!isFunctionLike(current.parent)) {
+ return current;
+ }
}
- }
- // All container nodes are kept on a linked list in declaration order. This list is used by
- // the getLocalNameOfContainer function in the type checker to validate that the local name
- // used for a container is unique.
- function bindChildren(node) {
- // Before we recurse into a node's chilren, we first save the existing parent, container
- // and block-container. Then after we pop out of processing the children, we restore
- // these saved values.
- var saveParent = parent;
- var saveContainer = container;
- var savedBlockScopeContainer = blockScopeContainer;
- // This node will now be set as the parent of all of its children as we recurse into them.
- parent = node;
- // Depending on what kind of node this is, we may have to adjust the current container
- // and block-container. If the current node is a container, then it is automatically
- // considered the current block-container as well. Also, for containers that we know
- // may contain locals, we proactively initialize the .locals field. We do this because
- // it's highly likely that the .locals will be needed to place some child in (for example,
- // a parameter, or variable declaration).
- //
- // However, we do not proactively create the .locals for block-containers because it's
- // totally normal and common for block-containers to never actually have a block-scoped
- // variable in them. We don't want to end up allocating an object for every 'block' we
- // run into when most of them won't be necessary.
- //
- // Finally, if this is a block-container, then we clear out any existing .locals object
- // it may contain within it. This happens in incremental scenarios. Because we can be
- // reusing a node from a previous compilation, that node may have had 'locals' created
- // for it. We must clear this so we don't accidently move any stale data forward from
- // a previous compilation.
- var containerFlags = getContainerFlags(node);
- if (containerFlags & 1 /* IsContainer */) {
- container = blockScopeContainer = node;
- if (containerFlags & 4 /* HasLocals */) {
- container.locals = {};
- }
- addToContainerChain(container);
- }
- else if (containerFlags & 2 /* IsBlockScopedContainer */) {
- blockScopeContainer = node;
- blockScopeContainer.locals = undefined;
- }
- var savedReachabilityState;
- var savedLabelStack;
- var savedLabels;
- var savedImplicitLabels;
- var savedHasExplicitReturn;
- var kind = node.kind;
- var flags = node.flags;
- // reset all reachability check related flags on node (for incremental scenarios)
- flags &= ~1572864 /* ReachabilityCheckFlags */;
- if (kind === 215 /* InterfaceDeclaration */) {
- seenThisKeyword = false;
- }
- var saveState = kind === 248 /* SourceFile */ || kind === 219 /* ModuleBlock */ || ts.isFunctionLikeKind(kind);
- if (saveState) {
- savedReachabilityState = currentReachabilityState;
- savedLabelStack = labelStack;
- savedLabels = labelIndexMap;
- savedImplicitLabels = implicitLabels;
- savedHasExplicitReturn = hasExplicitReturn;
- currentReachabilityState = 2 /* Reachable */;
- hasExplicitReturn = false;
- labelStack = labelIndexMap = implicitLabels = undefined;
- }
- bindReachableStatement(node);
- if (currentReachabilityState === 2 /* Reachable */ && ts.isFunctionLikeKind(kind) && ts.nodeIsPresent(node.body)) {
- flags |= 524288 /* HasImplicitReturn */;
- if (hasExplicitReturn) {
- flags |= 1048576 /* HasExplicitReturn */;
- }
- }
- if (kind === 215 /* InterfaceDeclaration */) {
- flags = seenThisKeyword ? flags | 262144 /* ContainsThis */ : flags & ~262144 /* ContainsThis */;
- }
- node.flags = flags;
- if (saveState) {
- hasExplicitReturn = savedHasExplicitReturn;
- currentReachabilityState = savedReachabilityState;
- labelStack = savedLabelStack;
- labelIndexMap = savedLabels;
- implicitLabels = savedImplicitLabels;
- }
- container = saveContainer;
- parent = saveParent;
- blockScopeContainer = savedBlockScopeContainer;
- }
- /**
- * Returns true if node and its subnodes were successfully traversed.
- * Returning false means that node was not examined and caller needs to dive into the node himself.
- */
- function bindReachableStatement(node) {
- if (checkUnreachable(node)) {
- ts.forEachChild(node, bind);
- return;
- }
- switch (node.kind) {
- case 198 /* WhileStatement */:
- bindWhileStatement(node);
- break;
- case 197 /* DoStatement */:
- bindDoStatement(node);
- break;
- case 199 /* ForStatement */:
- bindForStatement(node);
- break;
- case 200 /* ForInStatement */:
- case 201 /* ForOfStatement */:
- bindForInOrForOfStatement(node);
- break;
- case 196 /* IfStatement */:
- bindIfStatement(node);
- break;
- case 204 /* ReturnStatement */:
- case 208 /* ThrowStatement */:
- bindReturnOrThrow(node);
- break;
- case 203 /* BreakStatement */:
- case 202 /* ContinueStatement */:
- bindBreakOrContinueStatement(node);
- break;
- case 209 /* TryStatement */:
- bindTryStatement(node);
- break;
- case 206 /* SwitchStatement */:
- bindSwitchStatement(node);
- break;
- case 220 /* CaseBlock */:
- bindCaseBlock(node);
- break;
- case 207 /* LabeledStatement */:
- bindLabeledStatement(node);
- break;
- default:
- ts.forEachChild(node, bind);
- break;
- }
- }
- function bindWhileStatement(n) {
- var preWhileState = n.expression.kind === 84 /* FalseKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
- var postWhileState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
- // bind expressions (don't affect reachability)
- bind(n.expression);
- currentReachabilityState = preWhileState;
- var postWhileLabel = pushImplicitLabel();
- bind(n.statement);
- popImplicitLabel(postWhileLabel, postWhileState);
- }
- function bindDoStatement(n) {
- var preDoState = currentReachabilityState;
- var postDoLabel = pushImplicitLabel();
- bind(n.statement);
- var postDoState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : preDoState;
- popImplicitLabel(postDoLabel, postDoState);
- // bind expressions (don't affect reachability)
- bind(n.expression);
- }
- function bindForStatement(n) {
- var preForState = currentReachabilityState;
- var postForLabel = pushImplicitLabel();
- // bind expressions (don't affect reachability)
- bind(n.initializer);
- bind(n.condition);
- bind(n.incrementor);
- bind(n.statement);
- // for statement is considered infinite when it condition is either omitted or is true keyword
- // - for(..;;..)
- // - for(..;true;..)
- var isInfiniteLoop = (!n.condition || n.condition.kind === 99 /* TrueKeyword */);
- var postForState = isInfiniteLoop ? 4 /* Unreachable */ : preForState;
- popImplicitLabel(postForLabel, postForState);
- }
- function bindForInOrForOfStatement(n) {
- var preStatementState = currentReachabilityState;
- var postStatementLabel = pushImplicitLabel();
- // bind expressions (don't affect reachability)
- bind(n.initializer);
- bind(n.expression);
- bind(n.statement);
- popImplicitLabel(postStatementLabel, preStatementState);
- }
- function bindIfStatement(n) {
- // denotes reachability state when entering 'thenStatement' part of the if statement:
- // i.e. if condition is false then thenStatement is unreachable
- var ifTrueState = n.expression.kind === 84 /* FalseKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
- // denotes reachability state when entering 'elseStatement':
- // i.e. if condition is true then elseStatement is unreachable
- var ifFalseState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
- currentReachabilityState = ifTrueState;
- // bind expression (don't affect reachability)
- bind(n.expression);
- bind(n.thenStatement);
- if (n.elseStatement) {
- var preElseState = currentReachabilityState;
- currentReachabilityState = ifFalseState;
- bind(n.elseStatement);
- currentReachabilityState = or(currentReachabilityState, preElseState);
- }
- else {
- currentReachabilityState = or(currentReachabilityState, ifFalseState);
- }
- }
- function bindReturnOrThrow(n) {
- // bind expression (don't affect reachability)
- bind(n.expression);
- if (n.kind === 204 /* ReturnStatement */) {
- hasExplicitReturn = true;
- }
- currentReachabilityState = 4 /* Unreachable */;
- }
- function bindBreakOrContinueStatement(n) {
- // call bind on label (don't affect reachability)
- bind(n.label);
- // for continue case touch label so it will be marked a used
- var isValidJump = jumpToLabel(n.label, n.kind === 203 /* BreakStatement */ ? currentReachabilityState : 4 /* Unreachable */);
- if (isValidJump) {
- currentReachabilityState = 4 /* Unreachable */;
- }
- }
- function bindTryStatement(n) {
- // catch\finally blocks has the same reachability as try block
- var preTryState = currentReachabilityState;
- bind(n.tryBlock);
- var postTryState = currentReachabilityState;
- currentReachabilityState = preTryState;
- bind(n.catchClause);
- var postCatchState = currentReachabilityState;
- currentReachabilityState = preTryState;
- bind(n.finallyBlock);
- // post catch/finally state is reachable if
- // - post try state is reachable - control flow can fall out of try block
- // - post catch state is reachable - control flow can fall out of catch block
- currentReachabilityState = or(postTryState, postCatchState);
- }
- function bindSwitchStatement(n) {
- var preSwitchState = currentReachabilityState;
- var postSwitchLabel = pushImplicitLabel();
- // bind expression (don't affect reachability)
- bind(n.expression);
- bind(n.caseBlock);
- var hasDefault = ts.forEach(n.caseBlock.clauses, function (c) { return c.kind === 242 /* DefaultClause */; });
- // post switch state is unreachable if switch is exaustive (has a default case ) and does not have fallthrough from the last case
- var postSwitchState = hasDefault && currentReachabilityState !== 2 /* Reachable */ ? 4 /* Unreachable */ : preSwitchState;
- popImplicitLabel(postSwitchLabel, postSwitchState);
- }
- function bindCaseBlock(n) {
- var startState = currentReachabilityState;
- for (var _i = 0, _a = n.clauses; _i < _a.length; _i++) {
- var clause = _a[_i];
- currentReachabilityState = startState;
- bind(clause);
- if (clause.statements.length && currentReachabilityState === 2 /* Reachable */ && options.noFallthroughCasesInSwitch) {
- errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
- }
- }
- }
- function bindLabeledStatement(n) {
- // call bind on label (don't affect reachability)
- bind(n.label);
- var ok = pushNamedLabel(n.label);
- bind(n.statement);
- if (ok) {
- popNamedLabel(n.label, currentReachabilityState);
- }
- }
- function getContainerFlags(node) {
- switch (node.kind) {
- case 186 /* ClassExpression */:
- case 214 /* ClassDeclaration */:
- case 215 /* InterfaceDeclaration */:
- case 217 /* EnumDeclaration */:
- case 155 /* TypeLiteral */:
- case 165 /* ObjectLiteralExpression */:
- return 1 /* IsContainer */;
- case 147 /* CallSignature */:
- case 148 /* ConstructSignature */:
- case 149 /* IndexSignature */:
- case 143 /* MethodDeclaration */:
- case 142 /* MethodSignature */:
- case 213 /* FunctionDeclaration */:
- case 144 /* Constructor */:
- case 145 /* GetAccessor */:
- case 146 /* SetAccessor */:
- case 152 /* FunctionType */:
- case 153 /* ConstructorType */:
- case 173 /* FunctionExpression */:
- case 174 /* ArrowFunction */:
- case 218 /* ModuleDeclaration */:
- case 248 /* SourceFile */:
- case 216 /* TypeAliasDeclaration */:
- return 5 /* IsContainerWithLocals */;
- case 244 /* CatchClause */:
- case 199 /* ForStatement */:
- case 200 /* ForInStatement */:
- case 201 /* ForOfStatement */:
- case 220 /* CaseBlock */:
- return 2 /* IsBlockScopedContainer */;
- case 192 /* Block */:
- // do not treat blocks directly inside a function as a block-scoped-container.
- // Locals that reside in this block should go to the function locals. Othewise 'x'
- // would not appear to be a redeclaration of a block scoped local in the following
- // example:
- //
- // function foo() {
- // var x;
- // let x;
- // }
- //
- // If we placed 'var x' into the function locals and 'let x' into the locals of
- // the block, then there would be no collision.
- //
- // By not creating a new block-scoped-container here, we ensure that both 'var x'
- // and 'let x' go into the Function-container's locals, and we do get a collision
- // conflict.
- return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
- }
- return 0 /* None */;
- }
- function addToContainerChain(next) {
- if (lastContainer) {
- lastContainer.nextContainer = next;
- }
- lastContainer = next;
- }
- function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
- // Just call this directly so that the return type of this function stays "void".
- declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes);
- }
- function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) {
- switch (container.kind) {
- // Modules, source files, and classes need specialized handling for how their
- // members are declared (for example, a member of a class will go into a specific
- // symbol table depending on if it is static or not). We defer to specialized
- // handlers to take care of declaring these child members.
- case 218 /* ModuleDeclaration */:
- return declareModuleMember(node, symbolFlags, symbolExcludes);
- case 248 /* SourceFile */:
- return declareSourceFileMember(node, symbolFlags, symbolExcludes);
- case 186 /* ClassExpression */:
- case 214 /* ClassDeclaration */:
- return declareClassMember(node, symbolFlags, symbolExcludes);
- case 217 /* EnumDeclaration */:
- return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
- case 155 /* TypeLiteral */:
- case 165 /* ObjectLiteralExpression */:
- case 215 /* InterfaceDeclaration */:
- // Interface/Object-types always have their children added to the 'members' of
- // their container. They are only accessible through an instance of their
- // container, and are never in scope otherwise (even inside the body of the
- // object / type / interface declaring them). An exception is type parameters,
- // which are in scope without qualification (similar to 'locals').
- return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
- case 152 /* FunctionType */:
- case 153 /* ConstructorType */:
- case 147 /* CallSignature */:
- case 148 /* ConstructSignature */:
- case 149 /* IndexSignature */:
- case 143 /* MethodDeclaration */:
- case 142 /* MethodSignature */:
- case 144 /* Constructor */:
- case 145 /* GetAccessor */:
- case 146 /* SetAccessor */:
- case 213 /* FunctionDeclaration */:
- case 173 /* FunctionExpression */:
- case 174 /* ArrowFunction */:
- case 216 /* TypeAliasDeclaration */:
- // All the children of these container types are never visible through another
- // symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
- // they're only accessed 'lexically' (i.e. from code that exists underneath
- // their container in the tree. To accomplish this, we simply add their declared
- // symbol to the 'locals' of the container. These symbols can then be found as
- // the type checker walks up the containers, checking them for matching names.
- return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- }
- function declareClassMember(node, symbolFlags, symbolExcludes) {
- return node.flags & 64 /* Static */
- ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
- : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
- }
- function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
- return ts.isExternalModule(file)
- ? declareModuleMember(node, symbolFlags, symbolExcludes)
- : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- function hasExportDeclarations(node) {
- var body = node.kind === 248 /* SourceFile */ ? node : node.body;
- if (body.kind === 248 /* SourceFile */ || body.kind === 219 /* ModuleBlock */) {
- for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
- var stat = _a[_i];
- if (stat.kind === 228 /* ExportDeclaration */ || stat.kind === 227 /* ExportAssignment */) {
- return true;
- }
- }
- }
- return false;
- }
- function setExportContextFlag(node) {
- // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
- // declarations with export modifiers) is an export context in which declarations are implicitly exported.
- if (ts.isInAmbientContext(node) && !hasExportDeclarations(node)) {
- node.flags |= 131072 /* ExportContext */;
- }
- else {
- node.flags &= ~131072 /* ExportContext */;
- }
- }
- function bindModuleDeclaration(node) {
- setExportContextFlag(node);
- if (node.name.kind === 9 /* StringLiteral */) {
- declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
- }
- else {
- var state = getModuleInstanceState(node);
- if (state === 0 /* NonInstantiated */) {
- declareSymbolAndAddToSymbolTable(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */);
- }
- else {
- declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
- if (node.symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)) {
- // if module was already merged with some function, class or non-const enum
- // treat is a non-const-enum-only
- node.symbol.constEnumOnlyModule = false;
- }
- else {
- var currentModuleIsConstEnumOnly = state === 2 /* ConstEnumOnly */;
- if (node.symbol.constEnumOnlyModule === undefined) {
- // non-merged case - use the current state
- node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
- }
- else {
- // merged case: module is const enum only if all its pieces are non-instantiated or const enum
- node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
- }
- }
- }
- }
- }
- function bindFunctionOrConstructorType(node) {
- // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
- // to the one we would get for: { <...>(...): T }
- //
- // We do that by making an anonymous type literal symbol, and then setting the function
- // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
- // from an actual type literal symbol you would have gotten had you used the long form.
- var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node));
- addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
- var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type");
- addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
- typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a);
- var _a;
- }
- function bindObjectLiteralExpression(node) {
- var ElementKind;
- (function (ElementKind) {
- ElementKind[ElementKind["Property"] = 1] = "Property";
- ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
- })(ElementKind || (ElementKind = {}));
- if (inStrictMode) {
- var seen = {};
- for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
- var prop = _a[_i];
- if (prop.name.kind !== 69 /* Identifier */) {
- continue;
- }
- var identifier = prop.name;
- // ECMA-262 11.1.5 Object Initialiser
- // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
- // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
- // IsDataDescriptor(propId.descriptor) is true.
- // b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
- // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
- // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
- // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
- var currentKind = prop.kind === 245 /* PropertyAssignment */ || prop.kind === 246 /* ShorthandPropertyAssignment */ || prop.kind === 143 /* MethodDeclaration */
- ? 1 /* Property */
- : 2 /* Accessor */;
- var existingKind = seen[identifier.text];
- if (!existingKind) {
- seen[identifier.text] = currentKind;
- continue;
- }
- if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
- var span = ts.getErrorSpanForNode(file, identifier);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
- }
- }
- }
- return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object");
- }
- function bindAnonymousDeclaration(node, symbolFlags, name) {
- var symbol = createSymbol(symbolFlags, name);
- addDeclarationToSymbol(symbol, node, symbolFlags);
- }
- function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
- switch (blockScopeContainer.kind) {
- case 218 /* ModuleDeclaration */:
- declareModuleMember(node, symbolFlags, symbolExcludes);
- break;
- case 248 /* SourceFile */:
- if (ts.isExternalModule(container)) {
- declareModuleMember(node, symbolFlags, symbolExcludes);
- break;
- }
- // fall through.
- default:
- if (!blockScopeContainer.locals) {
- blockScopeContainer.locals = {};
- addToContainerChain(blockScopeContainer);
- }
- declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
- }
- }
- function bindBlockScopedVariableDeclaration(node) {
- bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
- }
- // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
- // check for reserved words used as identifiers in strict mode code.
- function checkStrictModeIdentifier(node) {
- if (inStrictMode &&
- node.originalKeywordKind >= 106 /* FirstFutureReservedWord */ &&
- node.originalKeywordKind <= 114 /* LastFutureReservedWord */ &&
- !ts.isIdentifierName(node)) {
- // Report error only if there are no parse errors in file
- if (!file.parseDiagnostics.length) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
- }
- }
- }
- function getStrictModeIdentifierMessage(node) {
- // Provide specialized messages to help the user understand why we think they're in
- // strict mode.
- if (ts.getContainingClass(node)) {
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
- }
- if (file.externalModuleIndicator) {
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
- }
- return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
- }
- function checkStrictModeBinaryExpression(node) {
- if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
- // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
- // Assignment operator(11.13) or of a PostfixExpression(11.3)
- checkStrictModeEvalOrArguments(node, node.left);
- }
- }
- function checkStrictModeCatchClause(node) {
- // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
- // Catch production is eval or arguments
- if (inStrictMode && node.variableDeclaration) {
- checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
- }
- }
- function checkStrictModeDeleteExpression(node) {
- // Grammar checking
- if (inStrictMode && node.expression.kind === 69 /* Identifier */) {
- // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
- // UnaryExpression is a direct reference to a variable, function argument, or function name
- var span = ts.getErrorSpanForNode(file, node.expression);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
- }
- }
- function isEvalOrArgumentsIdentifier(node) {
- return node.kind === 69 /* Identifier */ &&
- (node.text === "eval" || node.text === "arguments");
- }
- function checkStrictModeEvalOrArguments(contextNode, name) {
- if (name && name.kind === 69 /* Identifier */) {
- var identifier = name;
- if (isEvalOrArgumentsIdentifier(identifier)) {
- // We check first if the name is inside class declaration or class expression; if so give explicit message
- // otherwise report generic error message.
- var span = ts.getErrorSpanForNode(file, name);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
- }
- }
- }
- function getStrictModeEvalOrArgumentsMessage(node) {
- // Provide specialized messages to help the user understand why we think they're in
- // strict mode.
- if (ts.getContainingClass(node)) {
- return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
- }
- if (file.externalModuleIndicator) {
- return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
- }
- return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
- }
- function checkStrictModeFunctionName(node) {
- if (inStrictMode) {
- // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
- checkStrictModeEvalOrArguments(node, node.name);
- }
- }
- function checkStrictModeNumericLiteral(node) {
- if (inStrictMode && node.flags & 32768 /* OctalLiteral */) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
- }
- }
- function checkStrictModePostfixUnaryExpression(node) {
- // Grammar checking
- // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
- // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
- // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
- if (inStrictMode) {
- checkStrictModeEvalOrArguments(node, node.operand);
- }
- }
- function checkStrictModePrefixUnaryExpression(node) {
- // Grammar checking
- if (inStrictMode) {
- if (node.operator === 41 /* PlusPlusToken */ || node.operator === 42 /* MinusMinusToken */) {
- checkStrictModeEvalOrArguments(node, node.operand);
- }
- }
- }
- function checkStrictModeWithStatement(node) {
- // Grammar checking for withStatement
- if (inStrictMode) {
- errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
- }
- }
- function errorOnFirstToken(node, message, arg0, arg1, arg2) {
- var span = ts.getSpanOfTokenAtPosition(file, node.pos);
- file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
- }
- function getDestructuringParameterName(node) {
- return "__" + ts.indexOf(node.parent.parameters, node);
- }
- function bind(node) {
- if (!node) {
- return;
- }
- node.parent = parent;
- var savedInStrictMode = inStrictMode;
- if (!savedInStrictMode) {
- updateStrictMode(node);
- }
- // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
- // and then potentially add the symbol to an appropriate symbol table. Possible
- // destination symbol tables are:
- //
- // 1) The 'exports' table of the current container's symbol.
- // 2) The 'members' table of the current container's symbol.
- // 3) The 'locals' table of the current container.
- //
- // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
- // (like TypeLiterals for example) will not be put in any table.
- bindWorker(node);
- // Then we recurse into the children of the node to bind them as well. For certain
- // symbols we do specialized work when we recurse. For example, we'll keep track of
- // the current 'container' node when it changes. This helps us know which symbol table
- // a local should go into for example.
- bindChildren(node);
- inStrictMode = savedInStrictMode;
- }
- function updateStrictMode(node) {
- switch (node.kind) {
- case 248 /* SourceFile */:
- case 219 /* ModuleBlock */:
- updateStrictModeStatementList(node.statements);
- return;
- case 192 /* Block */:
- if (ts.isFunctionLike(node.parent)) {
- updateStrictModeStatementList(node.statements);
- }
- return;
- case 214 /* ClassDeclaration */:
- case 186 /* ClassExpression */:
- // All classes are automatically in strict mode in ES6.
- inStrictMode = true;
- return;
- }
- }
- function updateStrictModeStatementList(statements) {
- for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
- var statement = statements_1[_i];
- if (!ts.isPrologueDirective(statement)) {
- return;
- }
- if (isUseStrictPrologueDirective(statement)) {
- inStrictMode = true;
- return;
- }
- }
- }
- /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
- function isUseStrictPrologueDirective(node) {
- var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression);
- // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
- // string to contain unicode escapes (as per ES5).
- return nodeText === "\"use strict\"" || nodeText === "'use strict'";
- }
- function bindWorker(node) {
- switch (node.kind) {
- case 69 /* Identifier */:
- return checkStrictModeIdentifier(node);
- case 181 /* BinaryExpression */:
- return checkStrictModeBinaryExpression(node);
- case 244 /* CatchClause */:
- return checkStrictModeCatchClause(node);
- case 175 /* DeleteExpression */:
- return checkStrictModeDeleteExpression(node);
- case 8 /* NumericLiteral */:
- return checkStrictModeNumericLiteral(node);
- case 180 /* PostfixUnaryExpression */:
- return checkStrictModePostfixUnaryExpression(node);
- case 179 /* PrefixUnaryExpression */:
- return checkStrictModePrefixUnaryExpression(node);
- case 205 /* WithStatement */:
- return checkStrictModeWithStatement(node);
- case 97 /* ThisKeyword */:
- seenThisKeyword = true;
- return;
- case 137 /* TypeParameter */:
- return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */);
- case 138 /* Parameter */:
- return bindParameter(node);
- case 211 /* VariableDeclaration */:
- case 163 /* BindingElement */:
- return bindVariableDeclarationOrBindingElement(node);
- case 141 /* PropertyDeclaration */:
- case 140 /* PropertySignature */:
- return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 107455 /* PropertyExcludes */);
- case 245 /* PropertyAssignment */:
- case 246 /* ShorthandPropertyAssignment */:
- return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */);
- case 247 /* EnumMember */:
- return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */);
- case 147 /* CallSignature */:
- case 148 /* ConstructSignature */:
- case 149 /* IndexSignature */:
- return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
- case 143 /* MethodDeclaration */:
- case 142 /* MethodSignature */:
- // If this is an ObjectLiteralExpression method, then it sits in the same space
- // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes
- // so that it will conflict with any other object literal members with the same
- // name.
- return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */);
- case 213 /* FunctionDeclaration */:
- checkStrictModeFunctionName(node);
- return declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */);
- case 144 /* Constructor */:
- return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
- case 145 /* GetAccessor */:
- return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */);
- case 146 /* SetAccessor */:
- return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */);
- case 152 /* FunctionType */:
- case 153 /* ConstructorType */:
- return bindFunctionOrConstructorType(node);
- case 155 /* TypeLiteral */:
- return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type");
- case 165 /* ObjectLiteralExpression */:
- return bindObjectLiteralExpression(node);
- case 173 /* FunctionExpression */:
- case 174 /* ArrowFunction */:
- checkStrictModeFunctionName(node);
- var bindingName = node.name ? node.name.text : "__function";
- return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
- case 186 /* ClassExpression */:
- case 214 /* ClassDeclaration */:
- return bindClassLikeDeclaration(node);
- case 215 /* InterfaceDeclaration */:
- return bindBlockScopedDeclaration(node, 64 /* Interface */, 792960 /* InterfaceExcludes */);
- case 216 /* TypeAliasDeclaration */:
- return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */);
- case 217 /* EnumDeclaration */:
- return bindEnumDeclaration(node);
- case 218 /* ModuleDeclaration */:
- return bindModuleDeclaration(node);
- case 221 /* ImportEqualsDeclaration */:
- case 224 /* NamespaceImport */:
- case 226 /* ImportSpecifier */:
- case 230 /* ExportSpecifier */:
- return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
- case 223 /* ImportClause */:
- return bindImportClause(node);
- case 228 /* ExportDeclaration */:
- return bindExportDeclaration(node);
- case 227 /* ExportAssignment */:
- return bindExportAssignment(node);
- case 248 /* SourceFile */:
- return bindSourceFileIfExternalModule();
- }
- }
- function bindSourceFileIfExternalModule() {
- setExportContextFlag(file);
- if (ts.isExternalModule(file)) {
- bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
- }
- }
- function bindExportAssignment(node) {
- if (!container.symbol || !container.symbol.exports) {
- // Export assignment in some sort of block construct
- bindAnonymousDeclaration(node, 8388608 /* Alias */, getDeclarationName(node));
- }
- else if (node.expression.kind === 69 /* Identifier */) {
- // An export default clause with an identifier exports all meanings of that identifier
- declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
- }
- else {
- // An export default clause with an expression exports a value
- declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
- }
- }
- function bindExportDeclaration(node) {
- if (!container.symbol || !container.symbol.exports) {
- // Export * in some sort of block construct
- bindAnonymousDeclaration(node, 1073741824 /* ExportStar */, getDeclarationName(node));
- }
- else if (!node.exportClause) {
- // All export * declarations are collected in an __export symbol
- declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0 /* None */);
- }
- }
- function bindImportClause(node) {
- if (node.name) {
- declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
- }
- }
- function bindClassLikeDeclaration(node) {
- if (node.kind === 214 /* ClassDeclaration */) {
- bindBlockScopedDeclaration(node, 32 /* Class */, 899519 /* ClassExcludes */);
- }
- else {
- var bindingName = node.name ? node.name.text : "__class";
- bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
- // Add name of class expression into the map for semantic classifier
- if (node.name) {
- classifiableNames[node.name.text] = node.name.text;
- }
- }
- var symbol = node.symbol;
- // TypeScript 1.0 spec (April 2014): 8.4
- // Every class automatically contains a static property member named 'prototype', the
- // type of which is an instantiation of the class type with type Any supplied as a type
- // argument for each type parameter. It is an error to explicitly declare a static
- // property member with the name 'prototype'.
- //
- // Note: we check for this here because this class may be merging into a module. The
- // module might have an exported variable called 'prototype'. We can't allow that as
- // that would clash with the built-in 'prototype' for the class.
- var prototypeSymbol = createSymbol(4 /* Property */ | 134217728 /* Prototype */, "prototype");
- if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) {
- if (node.name) {
- node.name.parent = node;
- }
- file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
- }
- symbol.exports[prototypeSymbol.name] = prototypeSymbol;
- prototypeSymbol.parent = symbol;
- }
- function bindEnumDeclaration(node) {
- return ts.isConst(node)
- ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */)
- : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */);
- }
- function bindVariableDeclarationOrBindingElement(node) {
- if (inStrictMode) {
- checkStrictModeEvalOrArguments(node, node.name);
- }
- if (!ts.isBindingPattern(node.name)) {
- if (ts.isBlockOrCatchScoped(node)) {
- bindBlockScopedVariableDeclaration(node);
- }
- else if (ts.isParameterDeclaration(node)) {
- // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
- // because its parent chain has already been set up, since parents are set before descending into children.
- //
- // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
- // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
- // For example:
- // function foo([a,a]) {} // Duplicate Identifier error
- // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
- // // which correctly set excluded symbols
- declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
- }
- else {
- declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */);
- }
- }
- }
- function bindParameter(node) {
- if (inStrictMode) {
- // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
- // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
- checkStrictModeEvalOrArguments(node, node.name);
- }
- if (ts.isBindingPattern(node.name)) {
- bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, getDestructuringParameterName(node));
- }
- else {
- declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
- }
- // If this is a property-parameter, then also declare the property symbol into the
- // containing class.
- if (node.flags & 56 /* AccessibilityModifier */ &&
- node.parent.kind === 144 /* Constructor */ &&
- ts.isClassLike(node.parent.parent)) {
- var classDeclaration = node.parent.parent;
- declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */);
- }
- }
- function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
- return ts.hasDynamicName(node)
- ? bindAnonymousDeclaration(node, symbolFlags, "__computed")
- : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
- }
- // reachability checks
- function pushNamedLabel(name) {
- initializeReachabilityStateIfNecessary();
- if (ts.hasProperty(labelIndexMap, name.text)) {
- return false;
- }
- labelIndexMap[name.text] = labelStack.push(1 /* Unintialized */) - 1;
- return true;
- }
- function pushImplicitLabel() {
- initializeReachabilityStateIfNecessary();
- var index = labelStack.push(1 /* Unintialized */) - 1;
- implicitLabels.push(index);
- return index;
- }
- function popNamedLabel(label, outerState) {
- var index = labelIndexMap[label.text];
- ts.Debug.assert(index !== undefined);
- ts.Debug.assert(labelStack.length == index + 1);
- labelIndexMap[label.text] = undefined;
- setCurrentStateAtLabel(labelStack.pop(), outerState, label);
- }
- function popImplicitLabel(implicitLabelIndex, outerState) {
- if (labelStack.length !== implicitLabelIndex + 1) {
- ts.Debug.assert(false, "Label stack: " + labelStack.length + ", index:" + implicitLabelIndex);
- }
- var i = implicitLabels.pop();
- if (implicitLabelIndex !== i) {
- ts.Debug.assert(false, "i: " + i + ", index: " + implicitLabelIndex);
- }
- setCurrentStateAtLabel(labelStack.pop(), outerState, /*name*/ undefined);
- }
- function setCurrentStateAtLabel(innerMergedState, outerState, label) {
- if (innerMergedState === 1 /* Unintialized */) {
- if (label && !options.allowUnusedLabels) {
- file.bindDiagnostics.push(ts.createDiagnosticForNode(label, ts.Diagnostics.Unused_label));
- }
- currentReachabilityState = outerState;
- }
- else {
- currentReachabilityState = or(innerMergedState, outerState);
- }
- }
- function jumpToLabel(label, outerState) {
- initializeReachabilityStateIfNecessary();
- var index = label ? labelIndexMap[label.text] : ts.lastOrUndefined(implicitLabels);
- if (index === undefined) {
- // reference to unknown label or
- // break/continue used outside of loops
- return false;
- }
- var stateAtLabel = labelStack[index];
- labelStack[index] = stateAtLabel === 1 /* Unintialized */ ? outerState : or(stateAtLabel, outerState);
- return true;
- }
- function checkUnreachable(node) {
- switch (currentReachabilityState) {
- case 4 /* Unreachable */:
- var reportError =
- // report error on all statements
- ts.isStatement(node) ||
- // report error on class declarations
- node.kind === 214 /* ClassDeclaration */ ||
- // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
- (node.kind === 218 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node)) ||
- // report error on regular enums and const enums if preserveConstEnums is set
- (node.kind === 217 /* EnumDeclaration */ && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
- if (reportError) {
- currentReachabilityState = 8 /* ReportedUnreachable */;
- // unreachable code is reported if
- // - user has explicitly asked about it AND
- // - statement is in not ambient context (statements in ambient context is already an error
- // so we should not report extras) AND
- // - node is not variable statement OR
- // - node is block scoped variable statement OR
- // - node is not block scoped variable statement and at least one variable declaration has initializer
- // Rationale: we don't want to report errors on non-initialized var's since they are hoisted
- // On the other side we do want to report errors on non-initialized 'lets' because of TDZ
- var reportUnreachableCode = !options.allowUnreachableCode &&
- !ts.isInAmbientContext(node) &&
- (node.kind !== 193 /* VariableStatement */ ||
- ts.getCombinedNodeFlags(node.declarationList) & 24576 /* BlockScoped */ ||
- ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
- if (reportUnreachableCode) {
- errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
- }
- }
- case 8 /* ReportedUnreachable */:
- return true;
- default:
- return false;
- }
- function shouldReportErrorOnModuleDeclaration(node) {
- var instanceState = getModuleInstanceState(node);
- return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && options.preserveConstEnums);
- }
- }
- function initializeReachabilityStateIfNecessary() {
- if (labelIndexMap) {
- return;
- }
- currentReachabilityState = 2 /* Reachable */;
- labelIndexMap = {};
- labelStack = [];
- implicitLabels = [];
- }
- }
-})(ts || (ts = {}));
-///
-///
-/* @internal */
-var ts;
-(function (ts) {
- function getDeclarationOfKind(symbol, kind) {
- var declarations = symbol.declarations;
- if (declarations) {
- for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
- var declaration = declarations_1[_i];
- if (declaration.kind === kind) {
- return declaration;
- }
- }
- }
- return undefined;
- }
- ts.getDeclarationOfKind = getDeclarationOfKind;
- // Pool writers to avoid needing to allocate them for every symbol we write.
- var stringWriters = [];
- function getSingleLineStringWriter() {
- if (stringWriters.length === 0) {
- var str = "";
- var writeText = function (text) { return str += text; };
- return {
- string: function () { return str; },
- writeKeyword: writeText,
- writeOperator: writeText,
- writePunctuation: writeText,
- writeSpace: writeText,
- writeStringLiteral: writeText,
- writeParameter: writeText,
- writeSymbol: writeText,
- // Completely ignore indentation for string writers. And map newlines to
- // a single space.
- writeLine: function () { return str += " "; },
- increaseIndent: function () { },
- decreaseIndent: function () { },
- clear: function () { return str = ""; },
- trackSymbol: function () { },
- reportInaccessibleThisError: function () { }
- };
- }
- return stringWriters.pop();
- }
- ts.getSingleLineStringWriter = getSingleLineStringWriter;
- function releaseStringWriter(writer) {
- writer.clear();
- stringWriters.push(writer);
- }
- ts.releaseStringWriter = releaseStringWriter;
- function getFullWidth(node) {
- return node.end - node.pos;
- }
- ts.getFullWidth = getFullWidth;
- function arrayIsEqualTo(array1, array2, equaler) {
- if (!array1 || !array2) {
- return array1 === array2;
- }
- if (array1.length !== array2.length) {
- return false;
- }
- for (var i = 0; i < array1.length; ++i) {
- var equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
- if (!equals) {
- return false;
- }
- }
- return true;
- }
- ts.arrayIsEqualTo = arrayIsEqualTo;
- function hasResolvedModule(sourceFile, moduleNameText) {
- return sourceFile.resolvedModules && ts.hasProperty(sourceFile.resolvedModules, moduleNameText);
- }
- ts.hasResolvedModule = hasResolvedModule;
- function getResolvedModule(sourceFile, moduleNameText) {
- return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
- }
- ts.getResolvedModule = getResolvedModule;
- function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
- if (!sourceFile.resolvedModules) {
- sourceFile.resolvedModules = {};
- }
- sourceFile.resolvedModules[moduleNameText] = resolvedModule;
- }
- ts.setResolvedModule = setResolvedModule;
- // Returns true if this node contains a parse error anywhere underneath it.
- function containsParseError(node) {
- aggregateChildData(node);
- return (node.parserContextFlags & 64 /* ThisNodeOrAnySubNodesHasError */) !== 0;
- }
- ts.containsParseError = containsParseError;
- function aggregateChildData(node) {
- if (!(node.parserContextFlags & 128 /* HasAggregatedChildData */)) {
- // A node is considered to contain a parse error if:
- // a) the parser explicitly marked that it had an error
- // b) any of it's children reported that it had an error.
- var thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & 16 /* ThisNodeHasError */) !== 0) ||
- ts.forEachChild(node, containsParseError);
- // If so, mark ourselves accordingly.
- if (thisNodeOrAnySubNodesHasError) {
- node.parserContextFlags |= 64 /* ThisNodeOrAnySubNodesHasError */;
- }
- // Also mark that we've propogated the child information to this node. This way we can
- // always consult the bit directly on this node without needing to check its children
- // again.
- node.parserContextFlags |= 128 /* HasAggregatedChildData */;
- }
- }
- function getSourceFileOfNode(node) {
- while (node && node.kind !== 248 /* SourceFile */) {
- node = node.parent;
- }
- return node;
- }
- ts.getSourceFileOfNode = getSourceFileOfNode;
- function getStartPositionOfLine(line, sourceFile) {
- ts.Debug.assert(line >= 0);
- return ts.getLineStarts(sourceFile)[line];
- }
- ts.getStartPositionOfLine = getStartPositionOfLine;
- // This is a useful function for debugging purposes.
- function nodePosToString(node) {
- var file = getSourceFileOfNode(node);
- var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
- return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
- }
- ts.nodePosToString = nodePosToString;
- function getStartPosOfNode(node) {
- return node.pos;
- }
- ts.getStartPosOfNode = getStartPosOfNode;
- // Returns true if this node is missing from the actual source code. A 'missing' node is different
- // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
- // in the tree), it is definitely missing. However, a node may be defined, but still be
- // missing. This happens whenever the parser knows it needs to parse something, but can't
- // get anything in the source code that it expects at that location. For example:
- //
- // let a: ;
- //
- // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
- // code). So the parser will attempt to parse out a type, and will create an actual node.
- // However, this node will be 'missing' in the sense that no actual source-code/tokens are
- // contained within it.
- function nodeIsMissing(node) {
- if (!node) {
- return true;
- }
- return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
- }
- ts.nodeIsMissing = nodeIsMissing;
- function nodeIsPresent(node) {
- return !nodeIsMissing(node);
- }
- ts.nodeIsPresent = nodeIsPresent;
- function getTokenPosOfNode(node, sourceFile) {
- // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
- // want to skip trivia because this will launch us forward to the next token.
- if (nodeIsMissing(node)) {
- return node.pos;
- }
- return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
- }
- ts.getTokenPosOfNode = getTokenPosOfNode;
- function getNonDecoratorTokenPosOfNode(node, sourceFile) {
- if (nodeIsMissing(node) || !node.decorators) {
- return getTokenPosOfNode(node, sourceFile);
- }
- return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
- }
- ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
- function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
- if (includeTrivia === void 0) { includeTrivia = false; }
- if (nodeIsMissing(node)) {
- return "";
- }
- var text = sourceFile.text;
- return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end);
- }
- ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
- function getTextOfNodeFromSourceText(sourceText, node) {
- if (nodeIsMissing(node)) {
- return "";
- }
- return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
- }
- ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
- function getTextOfNode(node, includeTrivia) {
- if (includeTrivia === void 0) { includeTrivia = false; }
- return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
- }
- ts.getTextOfNode = getTextOfNode;
- // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
- function escapeIdentifier(identifier) {
- return identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier;
- }
- ts.escapeIdentifier = escapeIdentifier;
- // Remove extra underscore from escaped identifier
- function unescapeIdentifier(identifier) {
- return identifier.length >= 3 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ && identifier.charCodeAt(2) === 95 /* _ */ ? identifier.substr(1) : identifier;
- }
- ts.unescapeIdentifier = unescapeIdentifier;
- // Make an identifier from an external module name by extracting the string after the last "/" and replacing
- // all non-alphanumeric characters with underscores
- function makeIdentifierFromModuleName(moduleName) {
- return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
- }
- ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
- function isBlockOrCatchScoped(declaration) {
- return (getCombinedNodeFlags(declaration) & 24576 /* BlockScoped */) !== 0 ||
- isCatchClauseVariableDeclaration(declaration);
- }
- ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
- // Gets the nearest enclosing block scope container that has the provided node
- // as a descendant, that is not the provided node.
- function getEnclosingBlockScopeContainer(node) {
- var current = node.parent;
- while (current) {
- if (isFunctionLike(current)) {
- return current;
- }
- switch (current.kind) {
- case 248 /* SourceFile */:
- case 220 /* CaseBlock */:
- case 244 /* CatchClause */:
- case 218 /* ModuleDeclaration */:
- case 199 /* ForStatement */:
- case 200 /* ForInStatement */:
- case 201 /* ForOfStatement */:
- return current;
- case 192 /* Block */:
- // function block is not considered block-scope container
- // see comment in binder.ts: bind(...), case for SyntaxKind.Block
- if (!isFunctionLike(current.parent)) {
- return current;
- }
- }
- current = current.parent;
+ current = current.parent;
}
}
ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
@@ -5812,6 +4503,10 @@ var ts;
return file.externalModuleIndicator !== undefined;
}
ts.isExternalModule = isExternalModule;
+ function isExternalOrCommonJsModule(file) {
+ return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
+ }
+ ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
function isDeclarationFile(file) {
return (file.flags & 4096 /* DeclarationFile */) !== 0;
}
@@ -5865,19 +4560,27 @@ var ts;
return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
}
ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
+ function getLeadingCommentRangesOfNodeFromText(node, text) {
+ return ts.getLeadingCommentRanges(text, node.pos);
+ }
+ ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText;
function getJsDocComments(node, sourceFileOfNode) {
+ return getJsDocCommentsFromText(node, sourceFileOfNode.text);
+ }
+ ts.getJsDocComments = getJsDocComments;
+ function getJsDocCommentsFromText(node, text) {
var commentRanges = (node.kind === 138 /* Parameter */ || node.kind === 137 /* TypeParameter */) ?
- ts.concatenate(ts.getTrailingCommentRanges(sourceFileOfNode.text, node.pos), ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) :
- getLeadingCommentRangesOfNode(node, sourceFileOfNode);
+ ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
+ getLeadingCommentRangesOfNodeFromText(node, text);
return ts.filter(commentRanges, isJsDocComment);
function isJsDocComment(comment) {
// True if the comment starts with '/**' but not if it is '/**/'
- return sourceFileOfNode.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
- sourceFileOfNode.text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
- sourceFileOfNode.text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
+ return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
+ text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
+ text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
}
}
- ts.getJsDocComments = getJsDocComments;
+ ts.getJsDocCommentsFromText = getJsDocCommentsFromText;
ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/;
ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/;
function isTypeNode(node) {
@@ -6464,6 +5167,57 @@ var ts;
return node.kind === 221 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 232 /* ExternalModuleReference */;
}
ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
+ function isSourceFileJavaScript(file) {
+ return isInJavaScriptFile(file);
+ }
+ ts.isSourceFileJavaScript = isSourceFileJavaScript;
+ function isInJavaScriptFile(node) {
+ return node && !!(node.parserContextFlags & 32 /* JavaScriptFile */);
+ }
+ ts.isInJavaScriptFile = isInJavaScriptFile;
+ /**
+ * Returns true if the node is a CallExpression to the identifier 'require' with
+ * exactly one string literal argument.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ function isRequireCall(expression) {
+ // of the form 'require("name")'
+ return expression.kind === 168 /* CallExpression */ &&
+ expression.expression.kind === 69 /* Identifier */ &&
+ expression.expression.text === "require" &&
+ expression.arguments.length === 1 &&
+ expression.arguments[0].kind === 9 /* StringLiteral */;
+ }
+ ts.isRequireCall = isRequireCall;
+ /**
+ * Returns true if the node is an assignment to a property on the identifier 'exports'.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ function isExportsPropertyAssignment(expression) {
+ // of the form 'exports.name = expr' where 'name' and 'expr' are arbitrary
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === 181 /* BinaryExpression */) &&
+ (expression.operatorToken.kind === 56 /* EqualsToken */) &&
+ (expression.left.kind === 166 /* PropertyAccessExpression */) &&
+ (expression.left.expression.kind === 69 /* Identifier */) &&
+ ((expression.left.expression).text === "exports");
+ }
+ ts.isExportsPropertyAssignment = isExportsPropertyAssignment;
+ /**
+ * Returns true if the node is an assignment to the property access expression 'module.exports'.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ function isModuleExportsAssignment(expression) {
+ // of the form 'module.exports = expr' where 'expr' is arbitrary
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === 181 /* BinaryExpression */) &&
+ (expression.operatorToken.kind === 56 /* EqualsToken */) &&
+ (expression.left.kind === 166 /* PropertyAccessExpression */) &&
+ (expression.left.expression.kind === 69 /* Identifier */) &&
+ ((expression.left.expression).text === "module") &&
+ (expression.left.name.text === "exports");
+ }
+ ts.isModuleExportsAssignment = isModuleExportsAssignment;
function getExternalModuleName(node) {
if (node.kind === 222 /* ImportDeclaration */) {
return node.moduleSpecifier;
@@ -6791,8 +5545,8 @@ var ts;
function getFileReferenceFromReferencePath(comment, commentRange) {
var simpleReferenceRegEx = /^\/\/\/\s*/gim;
- if (simpleReferenceRegEx.exec(comment)) {
- if (isNoDefaultLibRegEx.exec(comment)) {
+ if (simpleReferenceRegEx.test(comment)) {
+ if (isNoDefaultLibRegEx.test(comment)) {
return {
isNoDefaultLib: true
};
@@ -6834,6 +5588,10 @@ var ts;
return isFunctionLike(node) && (node.flags & 256 /* Async */) !== 0 && !isAccessor(node);
}
ts.isAsyncFunctionLike = isAsyncFunctionLike;
+ function isStringOrNumericLiteral(kind) {
+ return kind === 9 /* StringLiteral */ || kind === 8 /* NumericLiteral */;
+ }
+ ts.isStringOrNumericLiteral = isStringOrNumericLiteral;
/**
* A declaration has a dynamic name if both of the following are true:
* 1. The declaration has a computed property name
@@ -6842,11 +5600,15 @@ var ts;
* Symbol.
*/
function hasDynamicName(declaration) {
- return declaration.name &&
- declaration.name.kind === 136 /* ComputedPropertyName */ &&
- !isWellKnownSymbolSyntactically(declaration.name.expression);
+ return declaration.name && isDynamicName(declaration.name);
}
ts.hasDynamicName = hasDynamicName;
+ function isDynamicName(name) {
+ return name.kind === 136 /* ComputedPropertyName */ &&
+ !isStringOrNumericLiteral(name.expression.kind) &&
+ !isWellKnownSymbolSyntactically(name.expression);
+ }
+ ts.isDynamicName = isDynamicName;
/**
* Checks if the expression is of the form:
* Symbol.name
@@ -7087,11 +5849,11 @@ var ts;
}
ts.getIndentSize = getIndentSize;
function createTextWriter(newLine) {
- var output = "";
- var indent = 0;
- var lineStart = true;
- var lineCount = 0;
- var linePos = 0;
+ var output;
+ var indent;
+ var lineStart;
+ var lineCount;
+ var linePos;
function write(s) {
if (s && s.length) {
if (lineStart) {
@@ -7101,6 +5863,13 @@ var ts;
output += s;
}
}
+ function reset() {
+ output = "";
+ indent = 0;
+ lineStart = true;
+ lineCount = 0;
+ linePos = 0;
+ }
function rawWrite(s) {
if (s !== undefined) {
if (lineStart) {
@@ -7127,9 +5896,10 @@ var ts;
lineStart = true;
}
}
- function writeTextOfNode(sourceFile, node) {
- write(getSourceTextOfNodeFromSourceFile(sourceFile, node));
+ function writeTextOfNode(text, node) {
+ write(getTextOfNodeFromSourceText(text, node));
}
+ reset();
return {
write: write,
rawWrite: rawWrite,
@@ -7142,10 +5912,20 @@ var ts;
getTextPos: function () { return output.length; },
getLine: function () { return lineCount + 1; },
getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; },
- getText: function () { return output; }
+ getText: function () { return output; },
+ reset: reset
};
}
ts.createTextWriter = createTextWriter;
+ /**
+ * Resolves a local path to a path which is absolute to the base of the emit
+ */
+ function getExternalModuleNameFromPath(host, fileName) {
+ var dir = host.getCurrentDirectory();
+ var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, fileName, dir, function (f) { return host.getCanonicalFileName(f); }, /*isAbsolutePathAnUrl*/ false);
+ return ts.removeFileExtension(relativePath);
+ }
+ ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
function getOwnEmitOutputFilePath(sourceFile, host, extension) {
var compilerOptions = host.getCompilerOptions();
var emitOutputFilePathWithoutExtension;
@@ -7174,6 +5954,10 @@ var ts;
return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line;
}
ts.getLineOfLocalPosition = getLineOfLocalPosition;
+ function getLineOfLocalPositionFromLineMap(lineMap, pos) {
+ return ts.computeLineAndCharacterOfPosition(lineMap, pos).line;
+ }
+ ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
function getFirstConstructorWithBody(node) {
return ts.forEach(node.members, function (member) {
if (member.kind === 144 /* Constructor */ && nodeIsPresent(member.body)) {
@@ -7246,22 +6030,22 @@ var ts;
};
}
ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
- function emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments) {
+ function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
// If the leading comments start on different line than the start of node, write new line
if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
- getLineOfLocalPosition(currentSourceFile, node.pos) !== getLineOfLocalPosition(currentSourceFile, leadingComments[0].pos)) {
+ getLineOfLocalPositionFromLineMap(lineMap, node.pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
writer.writeLine();
}
}
ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
- function emitComments(currentSourceFile, writer, comments, trailingSeparator, newLine, writeComment) {
+ function emitComments(text, lineMap, writer, comments, trailingSeparator, newLine, writeComment) {
var emitLeadingSpace = !trailingSeparator;
ts.forEach(comments, function (comment) {
if (emitLeadingSpace) {
writer.write(" ");
emitLeadingSpace = false;
}
- writeComment(currentSourceFile, writer, comment, newLine);
+ writeComment(text, lineMap, writer, comment, newLine);
if (comment.hasTrailingNewLine) {
writer.writeLine();
}
@@ -7279,7 +6063,7 @@ var ts;
* Detached comment is a comment at the top of file or function body that is separated from
* the next statement by space.
*/
- function emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, removeComments) {
+ function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
var leadingComments;
var currentDetachedCommentInfo;
if (removeComments) {
@@ -7289,12 +6073,12 @@ var ts;
//
// var x = 10;
if (node.pos === 0) {
- leadingComments = ts.filter(ts.getLeadingCommentRanges(currentSourceFile.text, node.pos), isPinnedComment);
+ leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment);
}
}
else {
// removeComments is false, just get detached as normal and bypass the process to filter comment
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
+ leadingComments = ts.getLeadingCommentRanges(text, node.pos);
}
if (leadingComments) {
var detachedComments = [];
@@ -7302,8 +6086,8 @@ var ts;
for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
var comment = leadingComments_1[_i];
if (lastComment) {
- var lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastComment.end);
- var commentLine = getLineOfLocalPosition(currentSourceFile, comment.pos);
+ var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
+ var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
if (commentLine >= lastCommentLine + 2) {
// There was a blank line between the last comment and this comment. This
// comment is not part of the copyright comments. Return what we have so
@@ -7318,36 +6102,36 @@ var ts;
// All comments look like they could have been part of the copyright header. Make
// sure there is at least one blank line between it and the node. If not, it's not
// a copyright header.
- var lastCommentLine = getLineOfLocalPosition(currentSourceFile, ts.lastOrUndefined(detachedComments).end);
- var nodeLine = getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node.pos));
+ var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.lastOrUndefined(detachedComments).end);
+ var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
if (nodeLine >= lastCommentLine + 2) {
// Valid detachedComments
- emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
- emitComments(currentSourceFile, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
+ emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
+ emitComments(text, lineMap, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end };
}
}
}
return currentDetachedCommentInfo;
function isPinnedComment(comment) {
- return currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
+ return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
+ text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
}
}
ts.emitDetachedComments = emitDetachedComments;
- function writeCommentRange(currentSourceFile, writer, comment, newLine) {
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */) {
- var firstCommentLineAndCharacter = ts.getLineAndCharacterOfPosition(currentSourceFile, comment.pos);
- var lineCount = ts.getLineStarts(currentSourceFile).length;
+ function writeCommentRange(text, lineMap, writer, comment, newLine) {
+ if (text.charCodeAt(comment.pos + 1) === 42 /* asterisk */) {
+ var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, comment.pos);
+ var lineCount = lineMap.length;
var firstCommentLineIndent;
for (var pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
var nextLineStart = (currentLine + 1) === lineCount
- ? currentSourceFile.text.length + 1
- : getStartPositionOfLine(currentLine + 1, currentSourceFile);
+ ? text.length + 1
+ : lineMap[currentLine + 1];
if (pos !== comment.pos) {
// If we are not emitting first line, we need to write the spaces to adjust the alignment
if (firstCommentLineIndent === undefined) {
- firstCommentLineIndent = calculateIndent(getStartPositionOfLine(firstCommentLineAndCharacter.line, currentSourceFile), comment.pos);
+ firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], comment.pos);
}
// These are number of spaces writer is going to write at current indent
var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
@@ -7365,7 +6149,7 @@ var ts;
// More right indented comment */ --4 = 8 - 4 + 11
// class c { }
// }
- var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(pos, nextLineStart);
+ var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
if (spacesToEmit > 0) {
var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
@@ -7383,45 +6167,45 @@ var ts;
}
}
// Write the comment line text
- writeTrimmedCurrentLine(pos, nextLineStart);
+ writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart);
pos = nextLineStart;
}
}
else {
// Single line comment of style //....
- writer.write(currentSourceFile.text.substring(comment.pos, comment.end));
- }
- function writeTrimmedCurrentLine(pos, nextLineStart) {
- var end = Math.min(comment.end, nextLineStart - 1);
- var currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, "");
- if (currentLineText) {
- // trimmed forward and ending spaces text
- writer.write(currentLineText);
- if (end !== comment.end) {
- writer.writeLine();
- }
- }
- else {
- // Empty string - make sure we write empty line
- writer.writeLiteral(newLine);
+ writer.write(text.substring(comment.pos, comment.end));
+ }
+ }
+ ts.writeCommentRange = writeCommentRange;
+ function writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart) {
+ var end = Math.min(comment.end, nextLineStart - 1);
+ var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
+ if (currentLineText) {
+ // trimmed forward and ending spaces text
+ writer.write(currentLineText);
+ if (end !== comment.end) {
+ writer.writeLine();
}
}
- function calculateIndent(pos, end) {
- var currentLineIndent = 0;
- for (; pos < end && ts.isWhiteSpace(currentSourceFile.text.charCodeAt(pos)); pos++) {
- if (currentSourceFile.text.charCodeAt(pos) === 9 /* tab */) {
- // Tabs = TabSize = indent size and go to next tabStop
- currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
- }
- else {
- // Single space
- currentLineIndent++;
- }
+ else {
+ // Empty string - make sure we write empty line
+ writer.writeLiteral(newLine);
+ }
+ }
+ function calculateIndent(text, pos, end) {
+ var currentLineIndent = 0;
+ for (; pos < end && ts.isWhiteSpace(text.charCodeAt(pos)); pos++) {
+ if (text.charCodeAt(pos) === 9 /* tab */) {
+ // Tabs = TabSize = indent size and go to next tabStop
+ currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
+ }
+ else {
+ // Single space
+ currentLineIndent++;
}
- return currentLineIndent;
}
+ return currentLineIndent;
}
- ts.writeCommentRange = writeCommentRange;
function modifierToFlag(token) {
switch (token) {
case 113 /* StaticKeyword */: return 64 /* Static */;
@@ -7517,14 +6301,14 @@ var ts;
return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 512 /* Default */) ? symbol.valueDeclaration.localSymbol : undefined;
}
ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
- function isJavaScript(fileName) {
- return ts.fileExtensionIs(fileName, ".js");
+ function hasJavaScriptFileExtension(fileName) {
+ return ts.fileExtensionIs(fileName, ".js") || ts.fileExtensionIs(fileName, ".jsx");
}
- ts.isJavaScript = isJavaScript;
- function isTsx(fileName) {
- return ts.fileExtensionIs(fileName, ".tsx");
+ ts.hasJavaScriptFileExtension = hasJavaScriptFileExtension;
+ function allowsJsxExpressions(fileName) {
+ return ts.fileExtensionIs(fileName, ".tsx") || ts.fileExtensionIs(fileName, ".jsx");
}
- ts.isTsx = isTsx;
+ ts.allowsJsxExpressions = allowsJsxExpressions;
/**
* Replace each instance of non-ascii characters by one, two, three, or four escape sequences
* representing the UTF-8 encoding of the character, and return the expanded char code list.
@@ -7835,18 +6619,20 @@ var ts;
}
ts.getTypeParameterOwner = getTypeParameterOwner;
})(ts || (ts = {}));
-///
///
+///
var ts;
(function (ts) {
- var nodeConstructors = new Array(272 /* Count */);
/* @internal */ ts.parseTime = 0;
- function getNodeConstructor(kind) {
- return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind));
- }
- ts.getNodeConstructor = getNodeConstructor;
+ var NodeConstructor;
+ var SourceFileConstructor;
function createNode(kind, pos, end) {
- return new (getNodeConstructor(kind))(pos, end);
+ if (kind === 248 /* SourceFile */) {
+ return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
+ }
+ else {
+ return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
+ }
}
ts.createNode = createNode;
function visitNode(cbNode, node) {
@@ -8269,6 +7055,9 @@ var ts;
// up by avoiding the cost of creating/compiling scanners over and over again.
var scanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ true);
var disallowInAndDecoratorContext = 1 /* DisallowIn */ | 4 /* Decorator */;
+ // capture constructors in 'initializeState' to avoid null checks
+ var NodeConstructor;
+ var SourceFileConstructor;
var sourceFile;
var parseDiagnostics;
var syntaxCursor;
@@ -8354,13 +7143,16 @@ var ts;
// attached to the EOF token.
var parseErrorBeforeNextFinishedNode = false;
function parseSourceFile(fileName, _sourceText, languageVersion, _syntaxCursor, setParentNodes) {
- initializeState(fileName, _sourceText, languageVersion, _syntaxCursor);
+ var isJavaScriptFile = ts.hasJavaScriptFileExtension(fileName) || _sourceText.lastIndexOf("// @language=javascript", 0) === 0;
+ initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor);
var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes);
clearState();
return result;
}
Parser.parseSourceFile = parseSourceFile;
- function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor) {
+ function initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor) {
+ NodeConstructor = ts.objectAllocator.getNodeConstructor();
+ SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
sourceText = _sourceText;
syntaxCursor = _syntaxCursor;
parseDiagnostics = [];
@@ -8368,13 +7160,13 @@ var ts;
identifiers = {};
identifierCount = 0;
nodeCount = 0;
- contextFlags = ts.isJavaScript(fileName) ? 32 /* JavaScriptFile */ : 0 /* None */;
+ contextFlags = isJavaScriptFile ? 32 /* JavaScriptFile */ : 0 /* None */;
parseErrorBeforeNextFinishedNode = false;
// Initialize and prime the scanner before parsing the source elements.
scanner.setText(sourceText);
scanner.setOnError(scanError);
scanner.setScriptTarget(languageVersion);
- scanner.setLanguageVariant(ts.isTsx(fileName) ? 1 /* JSX */ : 0 /* Standard */);
+ scanner.setLanguageVariant(ts.allowsJsxExpressions(fileName) ? 1 /* JSX */ : 0 /* Standard */);
}
function clearState() {
// Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily.
@@ -8389,6 +7181,9 @@ var ts;
}
function parseSourceFileWorker(fileName, languageVersion, setParentNodes) {
sourceFile = createSourceFile(fileName, languageVersion);
+ if (contextFlags & 32 /* JavaScriptFile */) {
+ sourceFile.parserContextFlags = 32 /* JavaScriptFile */;
+ }
// Prime the scanner.
token = nextToken();
processReferenceComments(sourceFile);
@@ -8406,7 +7201,7 @@ var ts;
// If this is a javascript file, proactively see if we can get JSDoc comments for
// relevant nodes in the file. We'll use these to provide typing informaion if they're
// available.
- if (ts.isJavaScript(fileName)) {
+ if (ts.isSourceFileJavaScript(sourceFile)) {
addJSDocComments();
}
return sourceFile;
@@ -8461,15 +7256,16 @@ var ts;
}
Parser.fixupParentReferences = fixupParentReferences;
function createSourceFile(fileName, languageVersion) {
- var sourceFile = createNode(248 /* SourceFile */, /*pos*/ 0);
- sourceFile.pos = 0;
- sourceFile.end = sourceText.length;
+ // code from createNode is inlined here so createNode won't have to deal with special case of creating source files
+ // this is quite rare comparing to other nodes and createNode should be as fast as possible
+ var sourceFile = new SourceFileConstructor(248 /* SourceFile */, /*pos*/ 0, /* end */ sourceText.length);
+ nodeCount++;
sourceFile.text = sourceText;
sourceFile.bindDiagnostics = [];
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = ts.normalizePath(fileName);
sourceFile.flags = ts.fileExtensionIs(sourceFile.fileName, ".d.ts") ? 4096 /* DeclarationFile */ : 0;
- sourceFile.languageVariant = ts.isTsx(sourceFile.fileName) ? 1 /* JSX */ : 0 /* Standard */;
+ sourceFile.languageVariant = ts.allowsJsxExpressions(sourceFile.fileName) ? 1 /* JSX */ : 0 /* Standard */;
return sourceFile;
}
function setContextFlag(val, flag) {
@@ -8734,12 +7530,13 @@ var ts;
return parseExpected(23 /* SemicolonToken */);
}
}
+ // note: this function creates only node
function createNode(kind, pos) {
nodeCount++;
if (!(pos >= 0)) {
pos = scanner.getStartPos();
}
- return new (nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)))(pos, pos);
+ return new NodeConstructor(kind, pos, pos);
}
function finishNode(node, end) {
node.end = end === undefined ? scanner.getStartPos() : end;
@@ -8904,7 +7701,7 @@ var ts;
case 12 /* ObjectLiteralMembers */:
return token === 19 /* OpenBracketToken */ || token === 37 /* AsteriskToken */ || isLiteralPropertyName();
case 9 /* ObjectBindingElements */:
- return isLiteralPropertyName();
+ return token === 19 /* OpenBracketToken */ || isLiteralPropertyName();
case 7 /* HeritageClauseElement */:
// If we see { } then only consume it as an expression if it is followed by , or {
// That way we won't consume the body of a class in its heritage clause.
@@ -9584,9 +8381,7 @@ var ts;
}
function parseParameterType() {
if (parseOptional(54 /* ColonToken */)) {
- return token === 9 /* StringLiteral */
- ? parseLiteralNode(/*internName*/ true)
- : parseType();
+ return parseType();
}
return undefined;
}
@@ -9917,6 +8712,8 @@ var ts;
// If these are followed by a dot, then parse these out as a dotted type reference instead.
var node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReferenceOrTypePredicate();
+ case 9 /* StringLiteral */:
+ return parseLiteralNode(/*internName*/ true);
case 103 /* VoidKeyword */:
case 97 /* ThisKeyword */:
return parseTokenNode();
@@ -9946,6 +8743,7 @@ var ts;
case 19 /* OpenBracketToken */:
case 25 /* LessThanToken */:
case 92 /* NewKeyword */:
+ case 9 /* StringLiteral */:
return true;
case 17 /* OpenParenToken */:
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
@@ -10362,7 +9160,7 @@ var ts;
return 1 /* True */;
}
// This *could* be a parenthesized arrow function.
- // Return Unknown to let the caller know.
+ // Return Unknown to const the caller know.
return 2 /* Unknown */;
}
else {
@@ -10448,7 +9246,7 @@ var ts;
// user meant to supply a block. For example, if the user wrote:
//
// a =>
- // let v = 0;
+ // const v = 0;
// }
//
// they may be missing an open brace. Check to see if that's the case so we can
@@ -10485,3202 +9283,4567 @@ var ts;
function isInOrOfKeyword(t) {
return t === 90 /* InKeyword */ || t === 134 /* OfKeyword */;
}
- function parseBinaryExpressionRest(precedence, leftOperand) {
+ function parseBinaryExpressionRest(precedence, leftOperand) {
+ while (true) {
+ // We either have a binary operator here, or we're finished. We call
+ // reScanGreaterToken so that we merge token sequences like > and = into >=
+ reScanGreaterToken();
+ var newPrecedence = getBinaryOperatorPrecedence();
+ // Check the precedence to see if we should "take" this operator
+ // - For left associative operator (all operator but **), consume the operator,
+ // recursively call the function below, and parse binaryExpression as a rightOperand
+ // of the caller if the new precendence of the operator is greater then or equal to the current precendence.
+ // For example:
+ // a - b - c;
+ // ^token; leftOperand = b. Return b to the caller as a rightOperand
+ // a * b - c
+ // ^token; leftOperand = b. Return b to the caller as a rightOperand
+ // a - b * c;
+ // ^token; leftOperand = b. Return b * c to the caller as a rightOperand
+ // - For right associative operator (**), consume the operator, recursively call the function
+ // and parse binaryExpression as a rightOperand of the caller if the new precendence of
+ // the operator is strictly grater than the current precendence
+ // For example:
+ // a ** b ** c;
+ // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
+ // a - b ** c;
+ // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
+ // a ** b - c
+ // ^token; leftOperand = b. Return b to the caller as a rightOperand
+ var consumeCurrentOperator = token === 38 /* AsteriskAsteriskToken */ ?
+ newPrecedence >= precedence :
+ newPrecedence > precedence;
+ if (!consumeCurrentOperator) {
+ break;
+ }
+ if (token === 90 /* InKeyword */ && inDisallowInContext()) {
+ break;
+ }
+ if (token === 116 /* AsKeyword */) {
+ // Make sure we *do* perform ASI for constructs like this:
+ // var x = foo
+ // as (Bar)
+ // This should be parsed as an initialized variable, followed
+ // by a function call to 'as' with the argument 'Bar'
+ if (scanner.hasPrecedingLineBreak()) {
+ break;
+ }
+ else {
+ nextToken();
+ leftOperand = makeAsExpression(leftOperand, parseType());
+ }
+ }
+ else {
+ leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+ }
+ }
+ return leftOperand;
+ }
+ function isBinaryOperator() {
+ if (inDisallowInContext() && token === 90 /* InKeyword */) {
+ return false;
+ }
+ return getBinaryOperatorPrecedence() > 0;
+ }
+ function getBinaryOperatorPrecedence() {
+ switch (token) {
+ case 52 /* BarBarToken */:
+ return 1;
+ case 51 /* AmpersandAmpersandToken */:
+ return 2;
+ case 47 /* BarToken */:
+ return 3;
+ case 48 /* CaretToken */:
+ return 4;
+ case 46 /* AmpersandToken */:
+ return 5;
+ case 30 /* EqualsEqualsToken */:
+ case 31 /* ExclamationEqualsToken */:
+ case 32 /* EqualsEqualsEqualsToken */:
+ case 33 /* ExclamationEqualsEqualsToken */:
+ return 6;
+ case 25 /* LessThanToken */:
+ case 27 /* GreaterThanToken */:
+ case 28 /* LessThanEqualsToken */:
+ case 29 /* GreaterThanEqualsToken */:
+ case 91 /* InstanceOfKeyword */:
+ case 90 /* InKeyword */:
+ case 116 /* AsKeyword */:
+ return 7;
+ case 43 /* LessThanLessThanToken */:
+ case 44 /* GreaterThanGreaterThanToken */:
+ case 45 /* GreaterThanGreaterThanGreaterThanToken */:
+ return 8;
+ case 35 /* PlusToken */:
+ case 36 /* MinusToken */:
+ return 9;
+ case 37 /* AsteriskToken */:
+ case 39 /* SlashToken */:
+ case 40 /* PercentToken */:
+ return 10;
+ case 38 /* AsteriskAsteriskToken */:
+ return 11;
+ }
+ // -1 is lower than all other precedences. Returning it will cause binary expression
+ // parsing to stop.
+ return -1;
+ }
+ function makeBinaryExpression(left, operatorToken, right) {
+ var node = createNode(181 /* BinaryExpression */, left.pos);
+ node.left = left;
+ node.operatorToken = operatorToken;
+ node.right = right;
+ return finishNode(node);
+ }
+ function makeAsExpression(left, right) {
+ var node = createNode(189 /* AsExpression */, left.pos);
+ node.expression = left;
+ node.type = right;
+ return finishNode(node);
+ }
+ function parsePrefixUnaryExpression() {
+ var node = createNode(179 /* PrefixUnaryExpression */);
+ node.operator = token;
+ nextToken();
+ node.operand = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function parseDeleteExpression() {
+ var node = createNode(175 /* DeleteExpression */);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function parseTypeOfExpression() {
+ var node = createNode(176 /* TypeOfExpression */);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function parseVoidExpression() {
+ var node = createNode(177 /* VoidExpression */);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ function isAwaitExpression() {
+ if (token === 119 /* AwaitKeyword */) {
+ if (inAwaitContext()) {
+ return true;
+ }
+ // here we are using similar heuristics as 'isYieldExpression'
+ return lookAhead(nextTokenIsIdentifierOnSameLine);
+ }
+ return false;
+ }
+ function parseAwaitExpression() {
+ var node = createNode(178 /* AwaitExpression */);
+ nextToken();
+ node.expression = parseSimpleUnaryExpression();
+ return finishNode(node);
+ }
+ /**
+ * Parse ES7 unary expression and await expression
+ *
+ * ES7 UnaryExpression:
+ * 1) SimpleUnaryExpression[?yield]
+ * 2) IncrementExpression[?yield] ** UnaryExpression[?yield]
+ */
+ function parseUnaryExpressionOrHigher() {
+ if (isAwaitExpression()) {
+ return parseAwaitExpression();
+ }
+ if (isIncrementExpression()) {
+ var incrementExpression = parseIncrementExpression();
+ return token === 38 /* AsteriskAsteriskToken */ ?
+ parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
+ incrementExpression;
+ }
+ var unaryOperator = token;
+ var simpleUnaryExpression = parseSimpleUnaryExpression();
+ if (token === 38 /* AsteriskAsteriskToken */) {
+ var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
+ if (simpleUnaryExpression.kind === 171 /* TypeAssertionExpression */) {
+ parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
+ }
+ else {
+ parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
+ }
+ }
+ return simpleUnaryExpression;
+ }
+ /**
+ * Parse ES7 simple-unary expression or higher:
+ *
+ * ES7 SimpleUnaryExpression:
+ * 1) IncrementExpression[?yield]
+ * 2) delete UnaryExpression[?yield]
+ * 3) void UnaryExpression[?yield]
+ * 4) typeof UnaryExpression[?yield]
+ * 5) + UnaryExpression[?yield]
+ * 6) - UnaryExpression[?yield]
+ * 7) ~ UnaryExpression[?yield]
+ * 8) ! UnaryExpression[?yield]
+ */
+ function parseSimpleUnaryExpression() {
+ switch (token) {
+ case 35 /* PlusToken */:
+ case 36 /* MinusToken */:
+ case 50 /* TildeToken */:
+ case 49 /* ExclamationToken */:
+ return parsePrefixUnaryExpression();
+ case 78 /* DeleteKeyword */:
+ return parseDeleteExpression();
+ case 101 /* TypeOfKeyword */:
+ return parseTypeOfExpression();
+ case 103 /* VoidKeyword */:
+ return parseVoidExpression();
+ case 25 /* LessThanToken */:
+ // This is modified UnaryExpression grammar in TypeScript
+ // UnaryExpression (modified):
+ // < type > UnaryExpression
+ return parseTypeAssertion();
+ default:
+ return parseIncrementExpression();
+ }
+ }
+ /**
+ * Check if the current token can possibly be an ES7 increment expression.
+ *
+ * ES7 IncrementExpression:
+ * LeftHandSideExpression[?Yield]
+ * LeftHandSideExpression[?Yield][no LineTerminator here]++
+ * LeftHandSideExpression[?Yield][no LineTerminator here]--
+ * ++LeftHandSideExpression[?Yield]
+ * --LeftHandSideExpression[?Yield]
+ */
+ function isIncrementExpression() {
+ // This function is called inside parseUnaryExpression to decide
+ // whether to call parseSimpleUnaryExpression or call parseIncrmentExpression directly
+ switch (token) {
+ case 35 /* PlusToken */:
+ case 36 /* MinusToken */:
+ case 50 /* TildeToken */:
+ case 49 /* ExclamationToken */:
+ case 78 /* DeleteKeyword */:
+ case 101 /* TypeOfKeyword */:
+ case 103 /* VoidKeyword */:
+ return false;
+ case 25 /* LessThanToken */:
+ // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
+ if (sourceFile.languageVariant !== 1 /* JSX */) {
+ return false;
+ }
+ // We are in JSX context and the token is part of JSXElement.
+ // Fall through
+ default:
+ return true;
+ }
+ }
+ /**
+ * Parse ES7 IncrementExpression. IncrementExpression is used instead of ES6's PostFixExpression.
+ *
+ * ES7 IncrementExpression[yield]:
+ * 1) LeftHandSideExpression[?yield]
+ * 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
+ * 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
+ * 4) ++LeftHandSideExpression[?yield]
+ * 5) --LeftHandSideExpression[?yield]
+ * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
+ */
+ function parseIncrementExpression() {
+ if (token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) {
+ var node = createNode(179 /* PrefixUnaryExpression */);
+ node.operator = token;
+ nextToken();
+ node.operand = parseLeftHandSideExpressionOrHigher();
+ return finishNode(node);
+ }
+ else if (sourceFile.languageVariant === 1 /* JSX */ && token === 25 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeyword)) {
+ // JSXElement is part of primaryExpression
+ return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
+ }
+ var expression = parseLeftHandSideExpressionOrHigher();
+ ts.Debug.assert(ts.isLeftHandSideExpression(expression));
+ if ((token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
+ var node = createNode(180 /* PostfixUnaryExpression */, expression.pos);
+ node.operand = expression;
+ node.operator = token;
+ nextToken();
+ return finishNode(node);
+ }
+ return expression;
+ }
+ function parseLeftHandSideExpressionOrHigher() {
+ // Original Ecma:
+ // LeftHandSideExpression: See 11.2
+ // NewExpression
+ // CallExpression
+ //
+ // Our simplification:
+ //
+ // LeftHandSideExpression: See 11.2
+ // MemberExpression
+ // CallExpression
+ //
+ // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
+ // MemberExpression to make our lives easier.
+ //
+ // to best understand the below code, it's important to see how CallExpression expands
+ // out into its own productions:
+ //
+ // CallExpression:
+ // MemberExpression Arguments
+ // CallExpression Arguments
+ // CallExpression[Expression]
+ // CallExpression.IdentifierName
+ // super ( ArgumentListopt )
+ // super.IdentifierName
+ //
+ // Because of the recursion in these calls, we need to bottom out first. There are two
+ // bottom out states we can run into. Either we see 'super' which must start either of
+ // the last two CallExpression productions. Or we have a MemberExpression which either
+ // completes the LeftHandSideExpression, or starts the beginning of the first four
+ // CallExpression productions.
+ var expression = token === 95 /* SuperKeyword */
+ ? parseSuperExpression()
+ : parseMemberExpressionOrHigher();
+ // Now, we *may* be complete. However, we might have consumed the start of a
+ // CallExpression. As such, we need to consume the rest of it here to be complete.
+ return parseCallExpressionRest(expression);
+ }
+ function parseMemberExpressionOrHigher() {
+ // Note: to make our lives simpler, we decompose the the NewExpression productions and
+ // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
+ // like so:
+ //
+ // PrimaryExpression : See 11.1
+ // this
+ // Identifier
+ // Literal
+ // ArrayLiteral
+ // ObjectLiteral
+ // (Expression)
+ // FunctionExpression
+ // new MemberExpression Arguments?
+ //
+ // MemberExpression : See 11.2
+ // PrimaryExpression
+ // MemberExpression[Expression]
+ // MemberExpression.IdentifierName
+ //
+ // CallExpression : See 11.2
+ // MemberExpression
+ // CallExpression Arguments
+ // CallExpression[Expression]
+ // CallExpression.IdentifierName
+ //
+ // Technically this is ambiguous. i.e. CallExpression defines:
+ //
+ // CallExpression:
+ // CallExpression Arguments
+ //
+ // If you see: "new Foo()"
+ //
+ // Then that could be treated as a single ObjectCreationExpression, or it could be
+ // treated as the invocation of "new Foo". We disambiguate that in code (to match
+ // the original grammar) by making sure that if we see an ObjectCreationExpression
+ // we always consume arguments if they are there. So we treat "new Foo()" as an
+ // object creation only, and not at all as an invocation) Another way to think
+ // about this is that for every "new" that we see, we will consume an argument list if
+ // it is there as part of the *associated* object creation node. Any additional
+ // argument lists we see, will become invocation expressions.
+ //
+ // Because there are no other places in the grammar now that refer to FunctionExpression
+ // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
+ // production.
+ //
+ // Because CallExpression and MemberExpression are left recursive, we need to bottom out
+ // of the recursion immediately. So we parse out a primary expression to start with.
+ var expression = parsePrimaryExpression();
+ return parseMemberExpressionRest(expression);
+ }
+ function parseSuperExpression() {
+ var expression = parseTokenNode();
+ if (token === 17 /* OpenParenToken */ || token === 21 /* DotToken */ || token === 19 /* OpenBracketToken */) {
+ return expression;
+ }
+ // If we have seen "super" it must be followed by '(' or '.'.
+ // If it wasn't then just try to parse out a '.' and report an error.
+ var node = createNode(166 /* PropertyAccessExpression */, expression.pos);
+ node.expression = expression;
+ node.dotToken = parseExpectedToken(21 /* DotToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
+ node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
+ return finishNode(node);
+ }
+ function parseJsxElementOrSelfClosingElement(inExpressionContext) {
+ var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
+ var result;
+ if (opening.kind === 235 /* JsxOpeningElement */) {
+ var node = createNode(233 /* JsxElement */, opening.pos);
+ node.openingElement = opening;
+ node.children = parseJsxChildren(node.openingElement.tagName);
+ node.closingElement = parseJsxClosingElement(inExpressionContext);
+ result = finishNode(node);
+ }
+ else {
+ ts.Debug.assert(opening.kind === 234 /* JsxSelfClosingElement */);
+ // Nothing else to do for self-closing elements
+ result = opening;
+ }
+ // If the user writes the invalid code '' in an expression context (i.e. not wrapped in
+ // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag
+ // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
+ // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
+ // does less damage and we can report a better error.
+ // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
+ // of one sort or another.
+ if (inExpressionContext && token === 25 /* LessThanToken */) {
+ var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true); });
+ if (invalidElement) {
+ parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
+ var badNode = createNode(181 /* BinaryExpression */, result.pos);
+ badNode.end = invalidElement.end;
+ badNode.left = result;
+ badNode.right = invalidElement;
+ badNode.operatorToken = createMissingNode(24 /* CommaToken */, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
+ badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
+ return badNode;
+ }
+ }
+ return result;
+ }
+ function parseJsxText() {
+ var node = createNode(236 /* JsxText */, scanner.getStartPos());
+ token = scanner.scanJsxToken();
+ return finishNode(node);
+ }
+ function parseJsxChild() {
+ switch (token) {
+ case 236 /* JsxText */:
+ return parseJsxText();
+ case 15 /* OpenBraceToken */:
+ return parseJsxExpression(/*inExpressionContext*/ false);
+ case 25 /* LessThanToken */:
+ return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
+ }
+ ts.Debug.fail("Unknown JSX child kind " + token);
+ }
+ function parseJsxChildren(openingTagName) {
+ var result = [];
+ result.pos = scanner.getStartPos();
+ var saveParsingContext = parsingContext;
+ parsingContext |= 1 << 14 /* JsxChildren */;
while (true) {
- // We either have a binary operator here, or we're finished. We call
- // reScanGreaterToken so that we merge token sequences like > and = into >=
- reScanGreaterToken();
- var newPrecedence = getBinaryOperatorPrecedence();
- // Check the precedence to see if we should "take" this operator
- // - For left associative operator (all operator but **), consume the operator,
- // recursively call the function below, and parse binaryExpression as a rightOperand
- // of the caller if the new precendence of the operator is greater then or equal to the current precendence.
- // For example:
- // a - b - c;
- // ^token; leftOperand = b. Return b to the caller as a rightOperand
- // a * b - c
- // ^token; leftOperand = b. Return b to the caller as a rightOperand
- // a - b * c;
- // ^token; leftOperand = b. Return b * c to the caller as a rightOperand
- // - For right associative operator (**), consume the operator, recursively call the function
- // and parse binaryExpression as a rightOperand of the caller if the new precendence of
- // the operator is strictly grater than the current precendence
- // For example:
- // a ** b ** c;
- // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
- // a - b ** c;
- // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
- // a ** b - c
- // ^token; leftOperand = b. Return b to the caller as a rightOperand
- var consumeCurrentOperator = token === 38 /* AsteriskAsteriskToken */ ?
- newPrecedence >= precedence :
- newPrecedence > precedence;
- if (!consumeCurrentOperator) {
+ token = scanner.reScanJsxToken();
+ if (token === 26 /* LessThanSlashToken */) {
break;
}
- if (token === 90 /* InKeyword */ && inDisallowInContext()) {
+ else if (token === 1 /* EndOfFileToken */) {
+ parseErrorAtCurrentToken(ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, openingTagName));
break;
}
- if (token === 116 /* AsKeyword */) {
- // Make sure we *do* perform ASI for constructs like this:
- // var x = foo
- // as (Bar)
- // This should be parsed as an initialized variable, followed
- // by a function call to 'as' with the argument 'Bar'
- if (scanner.hasPrecedingLineBreak()) {
- break;
- }
- else {
- nextToken();
- leftOperand = makeAsExpression(leftOperand, parseType());
- }
+ result.push(parseJsxChild());
+ }
+ result.end = scanner.getTokenPos();
+ parsingContext = saveParsingContext;
+ return result;
+ }
+ function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
+ var fullStart = scanner.getStartPos();
+ parseExpected(25 /* LessThanToken */);
+ var tagName = parseJsxElementName();
+ var attributes = parseList(13 /* JsxAttributes */, parseJsxAttribute);
+ var node;
+ if (token === 27 /* GreaterThanToken */) {
+ // Closing tag, so scan the immediately-following text with the JSX scanning instead
+ // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
+ // scanning errors
+ node = createNode(235 /* JsxOpeningElement */, fullStart);
+ scanJsxText();
+ }
+ else {
+ parseExpected(39 /* SlashToken */);
+ if (inExpressionContext) {
+ parseExpected(27 /* GreaterThanToken */);
}
else {
- leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+ parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*advance*/ false);
+ scanJsxText();
}
+ node = createNode(234 /* JsxSelfClosingElement */, fullStart);
}
- return leftOperand;
+ node.tagName = tagName;
+ node.attributes = attributes;
+ return finishNode(node);
}
- function isBinaryOperator() {
- if (inDisallowInContext() && token === 90 /* InKeyword */) {
- return false;
+ function parseJsxElementName() {
+ scanJsxIdentifier();
+ var elementName = parseIdentifierName();
+ while (parseOptional(21 /* DotToken */)) {
+ scanJsxIdentifier();
+ var node = createNode(135 /* QualifiedName */, elementName.pos);
+ node.left = elementName;
+ node.right = parseIdentifierName();
+ elementName = finishNode(node);
}
- return getBinaryOperatorPrecedence() > 0;
+ return elementName;
}
- function getBinaryOperatorPrecedence() {
- switch (token) {
- case 52 /* BarBarToken */:
- return 1;
- case 51 /* AmpersandAmpersandToken */:
- return 2;
- case 47 /* BarToken */:
- return 3;
- case 48 /* CaretToken */:
- return 4;
- case 46 /* AmpersandToken */:
- return 5;
- case 30 /* EqualsEqualsToken */:
- case 31 /* ExclamationEqualsToken */:
- case 32 /* EqualsEqualsEqualsToken */:
- case 33 /* ExclamationEqualsEqualsToken */:
- return 6;
- case 25 /* LessThanToken */:
- case 27 /* GreaterThanToken */:
- case 28 /* LessThanEqualsToken */:
- case 29 /* GreaterThanEqualsToken */:
- case 91 /* InstanceOfKeyword */:
- case 90 /* InKeyword */:
- case 116 /* AsKeyword */:
- return 7;
- case 43 /* LessThanLessThanToken */:
- case 44 /* GreaterThanGreaterThanToken */:
- case 45 /* GreaterThanGreaterThanGreaterThanToken */:
- return 8;
- case 35 /* PlusToken */:
- case 36 /* MinusToken */:
- return 9;
- case 37 /* AsteriskToken */:
- case 39 /* SlashToken */:
- case 40 /* PercentToken */:
- return 10;
- case 38 /* AsteriskAsteriskToken */:
- return 11;
+ function parseJsxExpression(inExpressionContext) {
+ var node = createNode(240 /* JsxExpression */);
+ parseExpected(15 /* OpenBraceToken */);
+ if (token !== 16 /* CloseBraceToken */) {
+ node.expression = parseExpression();
+ }
+ if (inExpressionContext) {
+ parseExpected(16 /* CloseBraceToken */);
+ }
+ else {
+ parseExpected(16 /* CloseBraceToken */, /*message*/ undefined, /*advance*/ false);
+ scanJsxText();
}
- // -1 is lower than all other precedences. Returning it will cause binary expression
- // parsing to stop.
- return -1;
- }
- function makeBinaryExpression(left, operatorToken, right) {
- var node = createNode(181 /* BinaryExpression */, left.pos);
- node.left = left;
- node.operatorToken = operatorToken;
- node.right = right;
return finishNode(node);
}
- function makeAsExpression(left, right) {
- var node = createNode(189 /* AsExpression */, left.pos);
- node.expression = left;
- node.type = right;
+ function parseJsxAttribute() {
+ if (token === 15 /* OpenBraceToken */) {
+ return parseJsxSpreadAttribute();
+ }
+ scanJsxIdentifier();
+ var node = createNode(238 /* JsxAttribute */);
+ node.name = parseIdentifierName();
+ if (parseOptional(56 /* EqualsToken */)) {
+ switch (token) {
+ case 9 /* StringLiteral */:
+ node.initializer = parseLiteralNode();
+ break;
+ default:
+ node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
+ break;
+ }
+ }
return finishNode(node);
}
- function parsePrefixUnaryExpression() {
- var node = createNode(179 /* PrefixUnaryExpression */);
- node.operator = token;
- nextToken();
- node.operand = parseSimpleUnaryExpression();
+ function parseJsxSpreadAttribute() {
+ var node = createNode(239 /* JsxSpreadAttribute */);
+ parseExpected(15 /* OpenBraceToken */);
+ parseExpected(22 /* DotDotDotToken */);
+ node.expression = parseExpression();
+ parseExpected(16 /* CloseBraceToken */);
return finishNode(node);
}
- function parseDeleteExpression() {
- var node = createNode(175 /* DeleteExpression */);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
+ function parseJsxClosingElement(inExpressionContext) {
+ var node = createNode(237 /* JsxClosingElement */);
+ parseExpected(26 /* LessThanSlashToken */);
+ node.tagName = parseJsxElementName();
+ if (inExpressionContext) {
+ parseExpected(27 /* GreaterThanToken */);
+ }
+ else {
+ parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*advance*/ false);
+ scanJsxText();
+ }
return finishNode(node);
}
- function parseTypeOfExpression() {
- var node = createNode(176 /* TypeOfExpression */);
- nextToken();
+ function parseTypeAssertion() {
+ var node = createNode(171 /* TypeAssertionExpression */);
+ parseExpected(25 /* LessThanToken */);
+ node.type = parseType();
+ parseExpected(27 /* GreaterThanToken */);
node.expression = parseSimpleUnaryExpression();
return finishNode(node);
}
- function parseVoidExpression() {
- var node = createNode(177 /* VoidExpression */);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function parseMemberExpressionRest(expression) {
+ while (true) {
+ var dotToken = parseOptionalToken(21 /* DotToken */);
+ if (dotToken) {
+ var propertyAccess = createNode(166 /* PropertyAccessExpression */, expression.pos);
+ propertyAccess.expression = expression;
+ propertyAccess.dotToken = dotToken;
+ propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
+ expression = finishNode(propertyAccess);
+ continue;
+ }
+ // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
+ if (!inDecoratorContext() && parseOptional(19 /* OpenBracketToken */)) {
+ var indexedAccess = createNode(167 /* ElementAccessExpression */, expression.pos);
+ indexedAccess.expression = expression;
+ // It's not uncommon for a user to write: "new Type[]".
+ // Check for that common pattern and report a better error message.
+ if (token !== 20 /* CloseBracketToken */) {
+ indexedAccess.argumentExpression = allowInAnd(parseExpression);
+ if (indexedAccess.argumentExpression.kind === 9 /* StringLiteral */ || indexedAccess.argumentExpression.kind === 8 /* NumericLiteral */) {
+ var literal = indexedAccess.argumentExpression;
+ literal.text = internIdentifier(literal.text);
+ }
+ }
+ parseExpected(20 /* CloseBracketToken */);
+ expression = finishNode(indexedAccess);
+ continue;
+ }
+ if (token === 11 /* NoSubstitutionTemplateLiteral */ || token === 12 /* TemplateHead */) {
+ var tagExpression = createNode(170 /* TaggedTemplateExpression */, expression.pos);
+ tagExpression.tag = expression;
+ tagExpression.template = token === 11 /* NoSubstitutionTemplateLiteral */
+ ? parseLiteralNode()
+ : parseTemplateExpression();
+ expression = finishNode(tagExpression);
+ continue;
+ }
+ return expression;
+ }
}
- function isAwaitExpression() {
- if (token === 119 /* AwaitKeyword */) {
- if (inAwaitContext()) {
- return true;
+ function parseCallExpressionRest(expression) {
+ while (true) {
+ expression = parseMemberExpressionRest(expression);
+ if (token === 25 /* LessThanToken */) {
+ // See if this is the start of a generic invocation. If so, consume it and
+ // keep checking for postfix expressions. Otherwise, it's just a '<' that's
+ // part of an arithmetic expression. Break out so we consume it higher in the
+ // stack.
+ var typeArguments = tryParse(parseTypeArgumentsInExpression);
+ if (!typeArguments) {
+ return expression;
+ }
+ var callExpr = createNode(168 /* CallExpression */, expression.pos);
+ callExpr.expression = expression;
+ callExpr.typeArguments = typeArguments;
+ callExpr.arguments = parseArgumentList();
+ expression = finishNode(callExpr);
+ continue;
}
- // here we are using similar heuristics as 'isYieldExpression'
- return lookAhead(nextTokenIsIdentifierOnSameLine);
+ else if (token === 17 /* OpenParenToken */) {
+ var callExpr = createNode(168 /* CallExpression */, expression.pos);
+ callExpr.expression = expression;
+ callExpr.arguments = parseArgumentList();
+ expression = finishNode(callExpr);
+ continue;
+ }
+ return expression;
}
- return false;
}
- function parseAwaitExpression() {
- var node = createNode(178 /* AwaitExpression */);
- nextToken();
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function parseArgumentList() {
+ parseExpected(17 /* OpenParenToken */);
+ var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
+ parseExpected(18 /* CloseParenToken */);
+ return result;
}
- /**
- * Parse ES7 unary expression and await expression
- *
- * ES7 UnaryExpression:
- * 1) SimpleUnaryExpression[?yield]
- * 2) IncrementExpression[?yield] ** UnaryExpression[?yield]
- */
- function parseUnaryExpressionOrHigher() {
- if (isAwaitExpression()) {
- return parseAwaitExpression();
- }
- if (isIncrementExpression()) {
- var incrementExpression = parseIncrementExpression();
- return token === 38 /* AsteriskAsteriskToken */ ?
- parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
- incrementExpression;
+ function parseTypeArgumentsInExpression() {
+ if (!parseOptional(25 /* LessThanToken */)) {
+ return undefined;
}
- var unaryOperator = token;
- var simpleUnaryExpression = parseSimpleUnaryExpression();
- if (token === 38 /* AsteriskAsteriskToken */) {
- var diagnostic;
- var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
- if (simpleUnaryExpression.kind === 171 /* TypeAssertionExpression */) {
- parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
- }
- else {
- parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
- }
+ var typeArguments = parseDelimitedList(18 /* TypeArguments */, parseType);
+ if (!parseExpected(27 /* GreaterThanToken */)) {
+ // If it doesn't have the closing > then it's definitely not an type argument list.
+ return undefined;
}
- return simpleUnaryExpression;
+ // If we have a '<', then only parse this as a arugment list if the type arguments
+ // are complete and we have an open paren. if we don't, rewind and return nothing.
+ return typeArguments && canFollowTypeArgumentsInExpression()
+ ? typeArguments
+ : undefined;
}
- /**
- * Parse ES7 simple-unary expression or higher:
- *
- * ES7 SimpleUnaryExpression:
- * 1) IncrementExpression[?yield]
- * 2) delete UnaryExpression[?yield]
- * 3) void UnaryExpression[?yield]
- * 4) typeof UnaryExpression[?yield]
- * 5) + UnaryExpression[?yield]
- * 6) - UnaryExpression[?yield]
- * 7) ~ UnaryExpression[?yield]
- * 8) ! UnaryExpression[?yield]
- */
- function parseSimpleUnaryExpression() {
+ function canFollowTypeArgumentsInExpression() {
switch (token) {
- case 35 /* PlusToken */:
- case 36 /* MinusToken */:
- case 50 /* TildeToken */:
- case 49 /* ExclamationToken */:
- return parsePrefixUnaryExpression();
- case 78 /* DeleteKeyword */:
- return parseDeleteExpression();
- case 101 /* TypeOfKeyword */:
- return parseTypeOfExpression();
- case 103 /* VoidKeyword */:
- return parseVoidExpression();
- case 25 /* LessThanToken */:
- // This is modified UnaryExpression grammar in TypeScript
- // UnaryExpression (modified):
- // < type > UnaryExpression
- return parseTypeAssertion();
+ case 17 /* OpenParenToken */: // foo(
+ // this case are the only case where this token can legally follow a type argument
+ // list. So we definitely want to treat this as a type arg list.
+ case 21 /* DotToken */: // foo.
+ case 18 /* CloseParenToken */: // foo)
+ case 20 /* CloseBracketToken */: // foo]
+ case 54 /* ColonToken */: // foo:
+ case 23 /* SemicolonToken */: // foo;
+ case 53 /* QuestionToken */: // foo?
+ case 30 /* EqualsEqualsToken */: // foo ==
+ case 32 /* EqualsEqualsEqualsToken */: // foo ===
+ case 31 /* ExclamationEqualsToken */: // foo !=
+ case 33 /* ExclamationEqualsEqualsToken */: // foo !==
+ case 51 /* AmpersandAmpersandToken */: // foo &&
+ case 52 /* BarBarToken */: // foo ||
+ case 48 /* CaretToken */: // foo ^
+ case 46 /* AmpersandToken */: // foo &
+ case 47 /* BarToken */: // foo |
+ case 16 /* CloseBraceToken */: // foo }
+ case 1 /* EndOfFileToken */:
+ // these cases can't legally follow a type arg list. However, they're not legal
+ // expressions either. The user is probably in the middle of a generic type. So
+ // treat it as such.
+ return true;
+ case 24 /* CommaToken */: // foo,
+ case 15 /* OpenBraceToken */: // foo {
+ // We don't want to treat these as type arguments. Otherwise we'll parse this
+ // as an invocation expression. Instead, we want to parse out the expression
+ // in isolation from the type arguments.
default:
- return parseIncrementExpression();
+ // Anything else treat as an expression.
+ return false;
}
}
- /**
- * Check if the current token can possibly be an ES7 increment expression.
- *
- * ES7 IncrementExpression:
- * LeftHandSideExpression[?Yield]
- * LeftHandSideExpression[?Yield][no LineTerminator here]++
- * LeftHandSideExpression[?Yield][no LineTerminator here]--
- * ++LeftHandSideExpression[?Yield]
- * --LeftHandSideExpression[?Yield]
- */
- function isIncrementExpression() {
- // This function is called inside parseUnaryExpression to decide
- // whether to call parseSimpleUnaryExpression or call parseIncrmentExpression directly
+ function parsePrimaryExpression() {
switch (token) {
- case 35 /* PlusToken */:
- case 36 /* MinusToken */:
- case 50 /* TildeToken */:
- case 49 /* ExclamationToken */:
- case 78 /* DeleteKeyword */:
- case 101 /* TypeOfKeyword */:
- case 103 /* VoidKeyword */:
- return false;
- case 25 /* LessThanToken */:
- // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
- if (sourceFile.languageVariant !== 1 /* JSX */) {
- return false;
+ case 8 /* NumericLiteral */:
+ case 9 /* StringLiteral */:
+ case 11 /* NoSubstitutionTemplateLiteral */:
+ return parseLiteralNode();
+ case 97 /* ThisKeyword */:
+ case 95 /* SuperKeyword */:
+ case 93 /* NullKeyword */:
+ case 99 /* TrueKeyword */:
+ case 84 /* FalseKeyword */:
+ return parseTokenNode();
+ case 17 /* OpenParenToken */:
+ return parseParenthesizedExpression();
+ case 19 /* OpenBracketToken */:
+ return parseArrayLiteralExpression();
+ case 15 /* OpenBraceToken */:
+ return parseObjectLiteralExpression();
+ case 118 /* AsyncKeyword */:
+ // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
+ // If we encounter `async [no LineTerminator here] function` then this is an async
+ // function; otherwise, its an identifier.
+ if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
+ break;
}
- // We are in JSX context and the token is part of JSXElement.
- // Fall through
- default:
- return true;
+ return parseFunctionExpression();
+ case 73 /* ClassKeyword */:
+ return parseClassExpression();
+ case 87 /* FunctionKeyword */:
+ return parseFunctionExpression();
+ case 92 /* NewKeyword */:
+ return parseNewExpression();
+ case 39 /* SlashToken */:
+ case 61 /* SlashEqualsToken */:
+ if (reScanSlashToken() === 10 /* RegularExpressionLiteral */) {
+ return parseLiteralNode();
+ }
+ break;
+ case 12 /* TemplateHead */:
+ return parseTemplateExpression();
+ }
+ return parseIdentifier(ts.Diagnostics.Expression_expected);
+ }
+ function parseParenthesizedExpression() {
+ var node = createNode(172 /* ParenthesizedExpression */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ return finishNode(node);
+ }
+ function parseSpreadElement() {
+ var node = createNode(185 /* SpreadElementExpression */);
+ parseExpected(22 /* DotDotDotToken */);
+ node.expression = parseAssignmentExpressionOrHigher();
+ return finishNode(node);
+ }
+ function parseArgumentOrArrayLiteralElement() {
+ return token === 22 /* DotDotDotToken */ ? parseSpreadElement() :
+ token === 24 /* CommaToken */ ? createNode(187 /* OmittedExpression */) :
+ parseAssignmentExpressionOrHigher();
+ }
+ function parseArgumentExpression() {
+ return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
+ }
+ function parseArrayLiteralExpression() {
+ var node = createNode(164 /* ArrayLiteralExpression */);
+ parseExpected(19 /* OpenBracketToken */);
+ if (scanner.hasPrecedingLineBreak())
+ node.flags |= 1024 /* MultiLine */;
+ node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
+ parseExpected(20 /* CloseBracketToken */);
+ return finishNode(node);
+ }
+ function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
+ if (parseContextualModifier(123 /* GetKeyword */)) {
+ return parseAccessorDeclaration(145 /* GetAccessor */, fullStart, decorators, modifiers);
+ }
+ else if (parseContextualModifier(129 /* SetKeyword */)) {
+ return parseAccessorDeclaration(146 /* SetAccessor */, fullStart, decorators, modifiers);
}
+ return undefined;
}
- /**
- * Parse ES7 IncrementExpression. IncrementExpression is used instead of ES6's PostFixExpression.
- *
- * ES7 IncrementExpression[yield]:
- * 1) LeftHandSideExpression[?yield]
- * 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
- * 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
- * 4) ++LeftHandSideExpression[?yield]
- * 5) --LeftHandSideExpression[?yield]
- * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
- */
- function parseIncrementExpression() {
- if (token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) {
- var node = createNode(179 /* PrefixUnaryExpression */);
- node.operator = token;
- nextToken();
- node.operand = parseLeftHandSideExpressionOrHigher();
- return finishNode(node);
+ function parseObjectLiteralElement() {
+ var fullStart = scanner.getStartPos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
+ if (accessor) {
+ return accessor;
}
- else if (sourceFile.languageVariant === 1 /* JSX */ && token === 25 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeyword)) {
- // JSXElement is part of primaryExpression
- return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
+ var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
+ var tokenIsIdentifier = isIdentifier();
+ var nameToken = token;
+ var propertyName = parsePropertyName();
+ // Disallowing of optional property assignments happens in the grammar checker.
+ var questionToken = parseOptionalToken(53 /* QuestionToken */);
+ if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
+ return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
}
- var expression = parseLeftHandSideExpressionOrHigher();
- ts.Debug.assert(ts.isLeftHandSideExpression(expression));
- if ((token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
- var node = createNode(180 /* PostfixUnaryExpression */, expression.pos);
- node.operand = expression;
- node.operator = token;
- nextToken();
- return finishNode(node);
+ // check if it is short-hand property assignment or normal property assignment
+ // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
+ // CoverInitializedName[Yield] :
+ // IdentifierReference[?Yield] Initializer[In, ?Yield]
+ // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
+ var isShorthandPropertyAssignment = tokenIsIdentifier && (token === 24 /* CommaToken */ || token === 16 /* CloseBraceToken */ || token === 56 /* EqualsToken */);
+ if (isShorthandPropertyAssignment) {
+ var shorthandDeclaration = createNode(246 /* ShorthandPropertyAssignment */, fullStart);
+ shorthandDeclaration.name = propertyName;
+ shorthandDeclaration.questionToken = questionToken;
+ var equalsToken = parseOptionalToken(56 /* EqualsToken */);
+ if (equalsToken) {
+ shorthandDeclaration.equalsToken = equalsToken;
+ shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
+ }
+ return finishNode(shorthandDeclaration);
+ }
+ else {
+ var propertyAssignment = createNode(245 /* PropertyAssignment */, fullStart);
+ propertyAssignment.name = propertyName;
+ propertyAssignment.questionToken = questionToken;
+ parseExpected(54 /* ColonToken */);
+ propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
+ return finishNode(propertyAssignment);
}
- return expression;
}
- function parseLeftHandSideExpressionOrHigher() {
- // Original Ecma:
- // LeftHandSideExpression: See 11.2
- // NewExpression
- // CallExpression
- //
- // Our simplification:
- //
- // LeftHandSideExpression: See 11.2
- // MemberExpression
- // CallExpression
- //
- // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
- // MemberExpression to make our lives easier.
- //
- // to best understand the below code, it's important to see how CallExpression expands
- // out into its own productions:
- //
- // CallExpression:
- // MemberExpression Arguments
- // CallExpression Arguments
- // CallExpression[Expression]
- // CallExpression.IdentifierName
- // super ( ArgumentListopt )
- // super.IdentifierName
- //
- // Because of the recursion in these calls, we need to bottom out first. There are two
- // bottom out states we can run into. Either we see 'super' which must start either of
- // the last two CallExpression productions. Or we have a MemberExpression which either
- // completes the LeftHandSideExpression, or starts the beginning of the first four
- // CallExpression productions.
- var expression = token === 95 /* SuperKeyword */
- ? parseSuperExpression()
- : parseMemberExpressionOrHigher();
- // Now, we *may* be complete. However, we might have consumed the start of a
- // CallExpression. As such, we need to consume the rest of it here to be complete.
- return parseCallExpressionRest(expression);
+ function parseObjectLiteralExpression() {
+ var node = createNode(165 /* ObjectLiteralExpression */);
+ parseExpected(15 /* OpenBraceToken */);
+ if (scanner.hasPrecedingLineBreak()) {
+ node.flags |= 1024 /* MultiLine */;
+ }
+ node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimeter*/ true);
+ parseExpected(16 /* CloseBraceToken */);
+ return finishNode(node);
}
- function parseMemberExpressionOrHigher() {
- // Note: to make our lives simpler, we decompose the the NewExpression productions and
- // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
- // like so:
- //
- // PrimaryExpression : See 11.1
- // this
- // Identifier
- // Literal
- // ArrayLiteral
- // ObjectLiteral
- // (Expression)
- // FunctionExpression
- // new MemberExpression Arguments?
- //
- // MemberExpression : See 11.2
- // PrimaryExpression
- // MemberExpression[Expression]
- // MemberExpression.IdentifierName
- //
- // CallExpression : See 11.2
- // MemberExpression
- // CallExpression Arguments
- // CallExpression[Expression]
- // CallExpression.IdentifierName
- //
- // Technically this is ambiguous. i.e. CallExpression defines:
- //
- // CallExpression:
- // CallExpression Arguments
- //
- // If you see: "new Foo()"
- //
- // Then that could be treated as a single ObjectCreationExpression, or it could be
- // treated as the invocation of "new Foo". We disambiguate that in code (to match
- // the original grammar) by making sure that if we see an ObjectCreationExpression
- // we always consume arguments if they are there. So we treat "new Foo()" as an
- // object creation only, and not at all as an invocation) Another way to think
- // about this is that for every "new" that we see, we will consume an argument list if
- // it is there as part of the *associated* object creation node. Any additional
- // argument lists we see, will become invocation expressions.
- //
- // Because there are no other places in the grammar now that refer to FunctionExpression
- // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
- // production.
+ function parseFunctionExpression() {
+ // GeneratorExpression:
+ // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
//
- // Because CallExpression and MemberExpression are left recursive, we need to bottom out
- // of the recursion immediately. So we parse out a primary expression to start with.
- var expression = parsePrimaryExpression();
- return parseMemberExpressionRest(expression);
+ // FunctionExpression:
+ // function BindingIdentifier[opt](FormalParameters){ FunctionBody }
+ var saveDecoratorContext = inDecoratorContext();
+ if (saveDecoratorContext) {
+ setDecoratorContext(false);
+ }
+ var node = createNode(173 /* FunctionExpression */);
+ setModifiers(node, parseModifiers());
+ parseExpected(87 /* FunctionKeyword */);
+ node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
+ var isGenerator = !!node.asteriskToken;
+ var isAsync = !!(node.flags & 256 /* Async */);
+ node.name =
+ isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
+ isGenerator ? doInYieldContext(parseOptionalIdentifier) :
+ isAsync ? doInAwaitContext(parseOptionalIdentifier) :
+ parseOptionalIdentifier();
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
+ node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
+ if (saveDecoratorContext) {
+ setDecoratorContext(true);
+ }
+ return finishNode(node);
}
- function parseSuperExpression() {
- var expression = parseTokenNode();
- if (token === 17 /* OpenParenToken */ || token === 21 /* DotToken */ || token === 19 /* OpenBracketToken */) {
- return expression;
+ function parseOptionalIdentifier() {
+ return isIdentifier() ? parseIdentifier() : undefined;
+ }
+ function parseNewExpression() {
+ var node = createNode(169 /* NewExpression */);
+ parseExpected(92 /* NewKeyword */);
+ node.expression = parseMemberExpressionOrHigher();
+ node.typeArguments = tryParse(parseTypeArgumentsInExpression);
+ if (node.typeArguments || token === 17 /* OpenParenToken */) {
+ node.arguments = parseArgumentList();
}
- // If we have seen "super" it must be followed by '(' or '.'.
- // If it wasn't then just try to parse out a '.' and report an error.
- var node = createNode(166 /* PropertyAccessExpression */, expression.pos);
- node.expression = expression;
- node.dotToken = parseExpectedToken(21 /* DotToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
- node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
return finishNode(node);
}
- function parseJsxElementOrSelfClosingElement(inExpressionContext) {
- var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
- var result;
- if (opening.kind === 235 /* JsxOpeningElement */) {
- var node = createNode(233 /* JsxElement */, opening.pos);
- node.openingElement = opening;
- node.children = parseJsxChildren(node.openingElement.tagName);
- node.closingElement = parseJsxClosingElement(inExpressionContext);
- result = finishNode(node);
+ // STATEMENTS
+ function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
+ var node = createNode(192 /* Block */);
+ if (parseExpected(15 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
+ node.statements = parseList(1 /* BlockStatements */, parseStatement);
+ parseExpected(16 /* CloseBraceToken */);
}
else {
- ts.Debug.assert(opening.kind === 234 /* JsxSelfClosingElement */);
- // Nothing else to do for self-closing elements
- result = opening;
+ node.statements = createMissingList();
}
- // If the user writes the invalid code '' in an expression context (i.e. not wrapped in
- // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag
- // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
- // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
- // does less damage and we can report a better error.
- // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
- // of one sort or another.
- if (inExpressionContext && token === 25 /* LessThanToken */) {
- var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true); });
- if (invalidElement) {
- parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
- var badNode = createNode(181 /* BinaryExpression */, result.pos);
- badNode.end = invalidElement.end;
- badNode.left = result;
- badNode.right = invalidElement;
- badNode.operatorToken = createMissingNode(24 /* CommaToken */, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
- badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
- return badNode;
- }
+ return finishNode(node);
+ }
+ function parseFunctionBlock(allowYield, allowAwait, ignoreMissingOpenBrace, diagnosticMessage) {
+ var savedYieldContext = inYieldContext();
+ setYieldContext(allowYield);
+ var savedAwaitContext = inAwaitContext();
+ setAwaitContext(allowAwait);
+ // We may be in a [Decorator] context when parsing a function expression or
+ // arrow function. The body of the function is not in [Decorator] context.
+ var saveDecoratorContext = inDecoratorContext();
+ if (saveDecoratorContext) {
+ setDecoratorContext(false);
}
- return result;
+ var block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
+ if (saveDecoratorContext) {
+ setDecoratorContext(true);
+ }
+ setYieldContext(savedYieldContext);
+ setAwaitContext(savedAwaitContext);
+ return block;
}
- function parseJsxText() {
- var node = createNode(236 /* JsxText */, scanner.getStartPos());
- token = scanner.scanJsxToken();
+ function parseEmptyStatement() {
+ var node = createNode(194 /* EmptyStatement */);
+ parseExpected(23 /* SemicolonToken */);
return finishNode(node);
}
- function parseJsxChild() {
- switch (token) {
- case 236 /* JsxText */:
- return parseJsxText();
- case 15 /* OpenBraceToken */:
- return parseJsxExpression(/*inExpressionContext*/ false);
- case 25 /* LessThanToken */:
- return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
- }
- ts.Debug.fail("Unknown JSX child kind " + token);
+ function parseIfStatement() {
+ var node = createNode(196 /* IfStatement */);
+ parseExpected(88 /* IfKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ node.thenStatement = parseStatement();
+ node.elseStatement = parseOptional(80 /* ElseKeyword */) ? parseStatement() : undefined;
+ return finishNode(node);
}
- function parseJsxChildren(openingTagName) {
- var result = [];
- result.pos = scanner.getStartPos();
- var saveParsingContext = parsingContext;
- parsingContext |= 1 << 14 /* JsxChildren */;
- while (true) {
- token = scanner.reScanJsxToken();
- if (token === 26 /* LessThanSlashToken */) {
- break;
+ function parseDoStatement() {
+ var node = createNode(197 /* DoStatement */);
+ parseExpected(79 /* DoKeyword */);
+ node.statement = parseStatement();
+ parseExpected(104 /* WhileKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
+ // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
+ // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
+ // do;while(0)x will have a semicolon inserted before x.
+ parseOptional(23 /* SemicolonToken */);
+ return finishNode(node);
+ }
+ function parseWhileStatement() {
+ var node = createNode(198 /* WhileStatement */);
+ parseExpected(104 /* WhileKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ node.statement = parseStatement();
+ return finishNode(node);
+ }
+ function parseForOrForInOrForOfStatement() {
+ var pos = getNodePos();
+ parseExpected(86 /* ForKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ var initializer = undefined;
+ if (token !== 23 /* SemicolonToken */) {
+ if (token === 102 /* VarKeyword */ || token === 108 /* LetKeyword */ || token === 74 /* ConstKeyword */) {
+ initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
}
- else if (token === 1 /* EndOfFileToken */) {
- parseErrorAtCurrentToken(ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, openingTagName));
- break;
+ else {
+ initializer = disallowInAnd(parseExpression);
}
- result.push(parseJsxChild());
}
- result.end = scanner.getTokenPos();
- parsingContext = saveParsingContext;
- return result;
- }
- function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
- var fullStart = scanner.getStartPos();
- parseExpected(25 /* LessThanToken */);
- var tagName = parseJsxElementName();
- var attributes = parseList(13 /* JsxAttributes */, parseJsxAttribute);
- var node;
- if (token === 27 /* GreaterThanToken */) {
- // Closing tag, so scan the immediately-following text with the JSX scanning instead
- // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
- // scanning errors
- node = createNode(235 /* JsxOpeningElement */, fullStart);
- scanJsxText();
+ var forOrForInOrForOfStatement;
+ if (parseOptional(90 /* InKeyword */)) {
+ var forInStatement = createNode(200 /* ForInStatement */, pos);
+ forInStatement.initializer = initializer;
+ forInStatement.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ forOrForInOrForOfStatement = forInStatement;
+ }
+ else if (parseOptional(134 /* OfKeyword */)) {
+ var forOfStatement = createNode(201 /* ForOfStatement */, pos);
+ forOfStatement.initializer = initializer;
+ forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
+ parseExpected(18 /* CloseParenToken */);
+ forOrForInOrForOfStatement = forOfStatement;
}
else {
- parseExpected(39 /* SlashToken */);
- if (inExpressionContext) {
- parseExpected(27 /* GreaterThanToken */);
+ var forStatement = createNode(199 /* ForStatement */, pos);
+ forStatement.initializer = initializer;
+ parseExpected(23 /* SemicolonToken */);
+ if (token !== 23 /* SemicolonToken */ && token !== 18 /* CloseParenToken */) {
+ forStatement.condition = allowInAnd(parseExpression);
}
- else {
- parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*advance*/ false);
- scanJsxText();
+ parseExpected(23 /* SemicolonToken */);
+ if (token !== 18 /* CloseParenToken */) {
+ forStatement.incrementor = allowInAnd(parseExpression);
}
- node = createNode(234 /* JsxSelfClosingElement */, fullStart);
+ parseExpected(18 /* CloseParenToken */);
+ forOrForInOrForOfStatement = forStatement;
}
- node.tagName = tagName;
- node.attributes = attributes;
+ forOrForInOrForOfStatement.statement = parseStatement();
+ return finishNode(forOrForInOrForOfStatement);
+ }
+ function parseBreakOrContinueStatement(kind) {
+ var node = createNode(kind);
+ parseExpected(kind === 203 /* BreakStatement */ ? 70 /* BreakKeyword */ : 75 /* ContinueKeyword */);
+ if (!canParseSemicolon()) {
+ node.label = parseIdentifier();
+ }
+ parseSemicolon();
return finishNode(node);
}
- function parseJsxElementName() {
- scanJsxIdentifier();
- var elementName = parseIdentifierName();
- while (parseOptional(21 /* DotToken */)) {
- scanJsxIdentifier();
- var node = createNode(135 /* QualifiedName */, elementName.pos);
- node.left = elementName;
- node.right = parseIdentifierName();
- elementName = finishNode(node);
+ function parseReturnStatement() {
+ var node = createNode(204 /* ReturnStatement */);
+ parseExpected(94 /* ReturnKeyword */);
+ if (!canParseSemicolon()) {
+ node.expression = allowInAnd(parseExpression);
}
- return elementName;
+ parseSemicolon();
+ return finishNode(node);
}
- function parseJsxExpression(inExpressionContext) {
- var node = createNode(240 /* JsxExpression */);
+ function parseWithStatement() {
+ var node = createNode(205 /* WithStatement */);
+ parseExpected(105 /* WithKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ node.statement = parseStatement();
+ return finishNode(node);
+ }
+ function parseCaseClause() {
+ var node = createNode(241 /* CaseClause */);
+ parseExpected(71 /* CaseKeyword */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(54 /* ColonToken */);
+ node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
+ return finishNode(node);
+ }
+ function parseDefaultClause() {
+ var node = createNode(242 /* DefaultClause */);
+ parseExpected(77 /* DefaultKeyword */);
+ parseExpected(54 /* ColonToken */);
+ node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
+ return finishNode(node);
+ }
+ function parseCaseOrDefaultClause() {
+ return token === 71 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
+ }
+ function parseSwitchStatement() {
+ var node = createNode(206 /* SwitchStatement */);
+ parseExpected(96 /* SwitchKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = allowInAnd(parseExpression);
+ parseExpected(18 /* CloseParenToken */);
+ var caseBlock = createNode(220 /* CaseBlock */, scanner.getStartPos());
parseExpected(15 /* OpenBraceToken */);
- if (token !== 16 /* CloseBraceToken */) {
- node.expression = parseExpression();
- }
- if (inExpressionContext) {
- parseExpected(16 /* CloseBraceToken */);
- }
- else {
- parseExpected(16 /* CloseBraceToken */, /*message*/ undefined, /*advance*/ false);
- scanJsxText();
- }
+ caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
+ parseExpected(16 /* CloseBraceToken */);
+ node.caseBlock = finishNode(caseBlock);
return finishNode(node);
}
- function parseJsxAttribute() {
- if (token === 15 /* OpenBraceToken */) {
- return parseJsxSpreadAttribute();
- }
- scanJsxIdentifier();
- var node = createNode(238 /* JsxAttribute */);
- node.name = parseIdentifierName();
- if (parseOptional(56 /* EqualsToken */)) {
- switch (token) {
- case 9 /* StringLiteral */:
- node.initializer = parseLiteralNode();
- break;
- default:
- node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
- break;
- }
+ function parseThrowStatement() {
+ // ThrowStatement[Yield] :
+ // throw [no LineTerminator here]Expression[In, ?Yield];
+ // Because of automatic semicolon insertion, we need to report error if this
+ // throw could be terminated with a semicolon. Note: we can't call 'parseExpression'
+ // directly as that might consume an expression on the following line.
+ // We just return 'undefined' in that case. The actual error will be reported in the
+ // grammar walker.
+ var node = createNode(208 /* ThrowStatement */);
+ parseExpected(98 /* ThrowKeyword */);
+ node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
+ parseSemicolon();
+ return finishNode(node);
+ }
+ // TODO: Review for error recovery
+ function parseTryStatement() {
+ var node = createNode(209 /* TryStatement */);
+ parseExpected(100 /* TryKeyword */);
+ node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
+ node.catchClause = token === 72 /* CatchKeyword */ ? parseCatchClause() : undefined;
+ // If we don't have a catch clause, then we must have a finally clause. Try to parse
+ // one out no matter what.
+ if (!node.catchClause || token === 85 /* FinallyKeyword */) {
+ parseExpected(85 /* FinallyKeyword */);
+ node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
}
return finishNode(node);
}
- function parseJsxSpreadAttribute() {
- var node = createNode(239 /* JsxSpreadAttribute */);
- parseExpected(15 /* OpenBraceToken */);
- parseExpected(22 /* DotDotDotToken */);
- node.expression = parseExpression();
- parseExpected(16 /* CloseBraceToken */);
+ function parseCatchClause() {
+ var result = createNode(244 /* CatchClause */);
+ parseExpected(72 /* CatchKeyword */);
+ if (parseExpected(17 /* OpenParenToken */)) {
+ result.variableDeclaration = parseVariableDeclaration();
+ }
+ parseExpected(18 /* CloseParenToken */);
+ result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
+ return finishNode(result);
+ }
+ function parseDebuggerStatement() {
+ var node = createNode(210 /* DebuggerStatement */);
+ parseExpected(76 /* DebuggerKeyword */);
+ parseSemicolon();
return finishNode(node);
}
- function parseJsxClosingElement(inExpressionContext) {
- var node = createNode(237 /* JsxClosingElement */);
- parseExpected(26 /* LessThanSlashToken */);
- node.tagName = parseJsxElementName();
- if (inExpressionContext) {
- parseExpected(27 /* GreaterThanToken */);
+ function parseExpressionOrLabeledStatement() {
+ // Avoiding having to do the lookahead for a labeled statement by just trying to parse
+ // out an expression, seeing if it is identifier and then seeing if it is followed by
+ // a colon.
+ var fullStart = scanner.getStartPos();
+ var expression = allowInAnd(parseExpression);
+ if (expression.kind === 69 /* Identifier */ && parseOptional(54 /* ColonToken */)) {
+ var labeledStatement = createNode(207 /* LabeledStatement */, fullStart);
+ labeledStatement.label = expression;
+ labeledStatement.statement = parseStatement();
+ return finishNode(labeledStatement);
}
else {
- parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*advance*/ false);
- scanJsxText();
+ var expressionStatement = createNode(195 /* ExpressionStatement */, fullStart);
+ expressionStatement.expression = expression;
+ parseSemicolon();
+ return finishNode(expressionStatement);
}
- return finishNode(node);
}
- function parseTypeAssertion() {
- var node = createNode(171 /* TypeAssertionExpression */);
- parseExpected(25 /* LessThanToken */);
- node.type = parseType();
- parseExpected(27 /* GreaterThanToken */);
- node.expression = parseSimpleUnaryExpression();
- return finishNode(node);
+ function nextTokenIsIdentifierOrKeywordOnSameLine() {
+ nextToken();
+ return ts.tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
}
- function parseMemberExpressionRest(expression) {
- while (true) {
- var dotToken = parseOptionalToken(21 /* DotToken */);
- if (dotToken) {
- var propertyAccess = createNode(166 /* PropertyAccessExpression */, expression.pos);
- propertyAccess.expression = expression;
- propertyAccess.dotToken = dotToken;
- propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
- expression = finishNode(propertyAccess);
- continue;
- }
- // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
- if (!inDecoratorContext() && parseOptional(19 /* OpenBracketToken */)) {
- var indexedAccess = createNode(167 /* ElementAccessExpression */, expression.pos);
- indexedAccess.expression = expression;
- // It's not uncommon for a user to write: "new Type[]".
- // Check for that common pattern and report a better error message.
- if (token !== 20 /* CloseBracketToken */) {
- indexedAccess.argumentExpression = allowInAnd(parseExpression);
- if (indexedAccess.argumentExpression.kind === 9 /* StringLiteral */ || indexedAccess.argumentExpression.kind === 8 /* NumericLiteral */) {
- var literal = indexedAccess.argumentExpression;
- literal.text = internIdentifier(literal.text);
- }
- }
- parseExpected(20 /* CloseBracketToken */);
- expression = finishNode(indexedAccess);
- continue;
- }
- if (token === 11 /* NoSubstitutionTemplateLiteral */ || token === 12 /* TemplateHead */) {
- var tagExpression = createNode(170 /* TaggedTemplateExpression */, expression.pos);
- tagExpression.tag = expression;
- tagExpression.template = token === 11 /* NoSubstitutionTemplateLiteral */
- ? parseLiteralNode()
- : parseTemplateExpression();
- expression = finishNode(tagExpression);
- continue;
- }
- return expression;
- }
+ function nextTokenIsFunctionKeywordOnSameLine() {
+ nextToken();
+ return token === 87 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
}
- function parseCallExpressionRest(expression) {
+ function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
+ nextToken();
+ return (ts.tokenIsIdentifierOrKeyword(token) || token === 8 /* NumericLiteral */) && !scanner.hasPrecedingLineBreak();
+ }
+ function isDeclaration() {
while (true) {
- expression = parseMemberExpressionRest(expression);
- if (token === 25 /* LessThanToken */) {
- // See if this is the start of a generic invocation. If so, consume it and
- // keep checking for postfix expressions. Otherwise, it's just a '<' that's
- // part of an arithmetic expression. Break out so we consume it higher in the
- // stack.
- var typeArguments = tryParse(parseTypeArgumentsInExpression);
- if (!typeArguments) {
- return expression;
- }
- var callExpr = createNode(168 /* CallExpression */, expression.pos);
- callExpr.expression = expression;
- callExpr.typeArguments = typeArguments;
- callExpr.arguments = parseArgumentList();
- expression = finishNode(callExpr);
- continue;
- }
- else if (token === 17 /* OpenParenToken */) {
- var callExpr = createNode(168 /* CallExpression */, expression.pos);
- callExpr.expression = expression;
- callExpr.arguments = parseArgumentList();
- expression = finishNode(callExpr);
- continue;
+ switch (token) {
+ case 102 /* VarKeyword */:
+ case 108 /* LetKeyword */:
+ case 74 /* ConstKeyword */:
+ case 87 /* FunctionKeyword */:
+ case 73 /* ClassKeyword */:
+ case 81 /* EnumKeyword */:
+ return true;
+ // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
+ // however, an identifier cannot be followed by another identifier on the same line. This is what we
+ // count on to parse out the respective declarations. For instance, we exploit this to say that
+ //
+ // namespace n
+ //
+ // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
+ //
+ // namespace
+ // n
+ //
+ // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
+ // We need to look one token ahead to see if it permissible to try parsing a declaration.
+ //
+ // *Note*: 'interface' is actually a strict mode reserved word. So while
+ //
+ // "use strict"
+ // interface
+ // I {}
+ //
+ // could be legal, it would add complexity for very little gain.
+ case 107 /* InterfaceKeyword */:
+ case 132 /* TypeKeyword */:
+ return nextTokenIsIdentifierOnSameLine();
+ case 125 /* ModuleKeyword */:
+ case 126 /* NamespaceKeyword */:
+ return nextTokenIsIdentifierOrStringLiteralOnSameLine();
+ case 115 /* AbstractKeyword */:
+ case 118 /* AsyncKeyword */:
+ case 122 /* DeclareKeyword */:
+ case 110 /* PrivateKeyword */:
+ case 111 /* ProtectedKeyword */:
+ case 112 /* PublicKeyword */:
+ nextToken();
+ // ASI takes effect for this modifier.
+ if (scanner.hasPrecedingLineBreak()) {
+ return false;
+ }
+ continue;
+ case 89 /* ImportKeyword */:
+ nextToken();
+ return token === 9 /* StringLiteral */ || token === 37 /* AsteriskToken */ ||
+ token === 15 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token);
+ case 82 /* ExportKeyword */:
+ nextToken();
+ if (token === 56 /* EqualsToken */ || token === 37 /* AsteriskToken */ ||
+ token === 15 /* OpenBraceToken */ || token === 77 /* DefaultKeyword */) {
+ return true;
+ }
+ continue;
+ case 113 /* StaticKeyword */:
+ nextToken();
+ continue;
+ default:
+ return false;
}
- return expression;
}
}
- function parseArgumentList() {
- parseExpected(17 /* OpenParenToken */);
- var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
- parseExpected(18 /* CloseParenToken */);
- return result;
- }
- function parseTypeArgumentsInExpression() {
- if (!parseOptional(25 /* LessThanToken */)) {
- return undefined;
- }
- var typeArguments = parseDelimitedList(18 /* TypeArguments */, parseType);
- if (!parseExpected(27 /* GreaterThanToken */)) {
- // If it doesn't have the closing > then it's definitely not an type argument list.
- return undefined;
- }
- // If we have a '<', then only parse this as a arugment list if the type arguments
- // are complete and we have an open paren. if we don't, rewind and return nothing.
- return typeArguments && canFollowTypeArgumentsInExpression()
- ? typeArguments
- : undefined;
+ function isStartOfDeclaration() {
+ return lookAhead(isDeclaration);
}
- function canFollowTypeArgumentsInExpression() {
+ function isStartOfStatement() {
switch (token) {
- case 17 /* OpenParenToken */: // foo(
- // this case are the only case where this token can legally follow a type argument
- // list. So we definitely want to treat this as a type arg list.
- case 21 /* DotToken */: // foo.
- case 18 /* CloseParenToken */: // foo)
- case 20 /* CloseBracketToken */: // foo]
- case 54 /* ColonToken */: // foo:
- case 23 /* SemicolonToken */: // foo;
- case 53 /* QuestionToken */: // foo?
- case 30 /* EqualsEqualsToken */: // foo ==
- case 32 /* EqualsEqualsEqualsToken */: // foo ===
- case 31 /* ExclamationEqualsToken */: // foo !=
- case 33 /* ExclamationEqualsEqualsToken */: // foo !==
- case 51 /* AmpersandAmpersandToken */: // foo &&
- case 52 /* BarBarToken */: // foo ||
- case 48 /* CaretToken */: // foo ^
- case 46 /* AmpersandToken */: // foo &
- case 47 /* BarToken */: // foo |
- case 16 /* CloseBraceToken */: // foo }
- case 1 /* EndOfFileToken */:
- // these cases can't legally follow a type arg list. However, they're not legal
- // expressions either. The user is probably in the middle of a generic type. So
- // treat it as such.
+ case 55 /* AtToken */:
+ case 23 /* SemicolonToken */:
+ case 15 /* OpenBraceToken */:
+ case 102 /* VarKeyword */:
+ case 108 /* LetKeyword */:
+ case 87 /* FunctionKeyword */:
+ case 73 /* ClassKeyword */:
+ case 81 /* EnumKeyword */:
+ case 88 /* IfKeyword */:
+ case 79 /* DoKeyword */:
+ case 104 /* WhileKeyword */:
+ case 86 /* ForKeyword */:
+ case 75 /* ContinueKeyword */:
+ case 70 /* BreakKeyword */:
+ case 94 /* ReturnKeyword */:
+ case 105 /* WithKeyword */:
+ case 96 /* SwitchKeyword */:
+ case 98 /* ThrowKeyword */:
+ case 100 /* TryKeyword */:
+ case 76 /* DebuggerKeyword */:
+ // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
+ // however, we say they are here so that we may gracefully parse them and error later.
+ case 72 /* CatchKeyword */:
+ case 85 /* FinallyKeyword */:
return true;
- case 24 /* CommaToken */: // foo,
- case 15 /* OpenBraceToken */: // foo {
- // We don't want to treat these as type arguments. Otherwise we'll parse this
- // as an invocation expression. Instead, we want to parse out the expression
- // in isolation from the type arguments.
+ case 74 /* ConstKeyword */:
+ case 82 /* ExportKeyword */:
+ case 89 /* ImportKeyword */:
+ return isStartOfDeclaration();
+ case 118 /* AsyncKeyword */:
+ case 122 /* DeclareKeyword */:
+ case 107 /* InterfaceKeyword */:
+ case 125 /* ModuleKeyword */:
+ case 126 /* NamespaceKeyword */:
+ case 132 /* TypeKeyword */:
+ // When these don't start a declaration, they're an identifier in an expression statement
+ return true;
+ case 112 /* PublicKeyword */:
+ case 110 /* PrivateKeyword */:
+ case 111 /* ProtectedKeyword */:
+ case 113 /* StaticKeyword */:
+ // When these don't start a declaration, they may be the start of a class member if an identifier
+ // immediately follows. Otherwise they're an identifier in an expression statement.
+ return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
default:
- // Anything else treat as an expression.
- return false;
+ return isStartOfExpression();
}
}
- function parsePrimaryExpression() {
+ function nextTokenIsIdentifierOrStartOfDestructuring() {
+ nextToken();
+ return isIdentifier() || token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */;
+ }
+ function isLetDeclaration() {
+ // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
+ // or [.
+ return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
+ }
+ function parseStatement() {
switch (token) {
- case 8 /* NumericLiteral */:
- case 9 /* StringLiteral */:
- case 11 /* NoSubstitutionTemplateLiteral */:
- return parseLiteralNode();
- case 97 /* ThisKeyword */:
- case 95 /* SuperKeyword */:
- case 93 /* NullKeyword */:
- case 99 /* TrueKeyword */:
- case 84 /* FalseKeyword */:
- return parseTokenNode();
- case 17 /* OpenParenToken */:
- return parseParenthesizedExpression();
- case 19 /* OpenBracketToken */:
- return parseArrayLiteralExpression();
+ case 23 /* SemicolonToken */:
+ return parseEmptyStatement();
case 15 /* OpenBraceToken */:
- return parseObjectLiteralExpression();
- case 118 /* AsyncKeyword */:
- // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
- // If we encounter `async [no LineTerminator here] function` then this is an async
- // function; otherwise, its an identifier.
- if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
- break;
+ return parseBlock(/*ignoreMissingOpenBrace*/ false);
+ case 102 /* VarKeyword */:
+ return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+ case 108 /* LetKeyword */:
+ if (isLetDeclaration()) {
+ return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
}
- return parseFunctionExpression();
- case 73 /* ClassKeyword */:
- return parseClassExpression();
+ break;
case 87 /* FunctionKeyword */:
- return parseFunctionExpression();
- case 92 /* NewKeyword */:
- return parseNewExpression();
- case 39 /* SlashToken */:
- case 61 /* SlashEqualsToken */:
- if (reScanSlashToken() === 10 /* RegularExpressionLiteral */) {
- return parseLiteralNode();
+ return parseFunctionDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+ case 73 /* ClassKeyword */:
+ return parseClassDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
+ case 88 /* IfKeyword */:
+ return parseIfStatement();
+ case 79 /* DoKeyword */:
+ return parseDoStatement();
+ case 104 /* WhileKeyword */:
+ return parseWhileStatement();
+ case 86 /* ForKeyword */:
+ return parseForOrForInOrForOfStatement();
+ case 75 /* ContinueKeyword */:
+ return parseBreakOrContinueStatement(202 /* ContinueStatement */);
+ case 70 /* BreakKeyword */:
+ return parseBreakOrContinueStatement(203 /* BreakStatement */);
+ case 94 /* ReturnKeyword */:
+ return parseReturnStatement();
+ case 105 /* WithKeyword */:
+ return parseWithStatement();
+ case 96 /* SwitchKeyword */:
+ return parseSwitchStatement();
+ case 98 /* ThrowKeyword */:
+ return parseThrowStatement();
+ case 100 /* TryKeyword */:
+ // Include 'catch' and 'finally' for error recovery.
+ case 72 /* CatchKeyword */:
+ case 85 /* FinallyKeyword */:
+ return parseTryStatement();
+ case 76 /* DebuggerKeyword */:
+ return parseDebuggerStatement();
+ case 55 /* AtToken */:
+ return parseDeclaration();
+ case 118 /* AsyncKeyword */:
+ case 107 /* InterfaceKeyword */:
+ case 132 /* TypeKeyword */:
+ case 125 /* ModuleKeyword */:
+ case 126 /* NamespaceKeyword */:
+ case 122 /* DeclareKeyword */:
+ case 74 /* ConstKeyword */:
+ case 81 /* EnumKeyword */:
+ case 82 /* ExportKeyword */:
+ case 89 /* ImportKeyword */:
+ case 110 /* PrivateKeyword */:
+ case 111 /* ProtectedKeyword */:
+ case 112 /* PublicKeyword */:
+ case 115 /* AbstractKeyword */:
+ case 113 /* StaticKeyword */:
+ if (isStartOfDeclaration()) {
+ return parseDeclaration();
}
break;
- case 12 /* TemplateHead */:
- return parseTemplateExpression();
}
- return parseIdentifier(ts.Diagnostics.Expression_expected);
- }
- function parseParenthesizedExpression() {
- var node = createNode(172 /* ParenthesizedExpression */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- return finishNode(node);
- }
- function parseSpreadElement() {
- var node = createNode(185 /* SpreadElementExpression */);
- parseExpected(22 /* DotDotDotToken */);
- node.expression = parseAssignmentExpressionOrHigher();
- return finishNode(node);
- }
- function parseArgumentOrArrayLiteralElement() {
- return token === 22 /* DotDotDotToken */ ? parseSpreadElement() :
- token === 24 /* CommaToken */ ? createNode(187 /* OmittedExpression */) :
- parseAssignmentExpressionOrHigher();
+ return parseExpressionOrLabeledStatement();
}
- function parseArgumentExpression() {
- return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
+ function parseDeclaration() {
+ var fullStart = getNodePos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ switch (token) {
+ case 102 /* VarKeyword */:
+ case 108 /* LetKeyword */:
+ case 74 /* ConstKeyword */:
+ return parseVariableStatement(fullStart, decorators, modifiers);
+ case 87 /* FunctionKeyword */:
+ return parseFunctionDeclaration(fullStart, decorators, modifiers);
+ case 73 /* ClassKeyword */:
+ return parseClassDeclaration(fullStart, decorators, modifiers);
+ case 107 /* InterfaceKeyword */:
+ return parseInterfaceDeclaration(fullStart, decorators, modifiers);
+ case 132 /* TypeKeyword */:
+ return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
+ case 81 /* EnumKeyword */:
+ return parseEnumDeclaration(fullStart, decorators, modifiers);
+ case 125 /* ModuleKeyword */:
+ case 126 /* NamespaceKeyword */:
+ return parseModuleDeclaration(fullStart, decorators, modifiers);
+ case 89 /* ImportKeyword */:
+ return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
+ case 82 /* ExportKeyword */:
+ nextToken();
+ return token === 77 /* DefaultKeyword */ || token === 56 /* EqualsToken */ ?
+ parseExportAssignment(fullStart, decorators, modifiers) :
+ parseExportDeclaration(fullStart, decorators, modifiers);
+ default:
+ if (decorators || modifiers) {
+ // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
+ // would follow. For recovery and error reporting purposes, return an incomplete declaration.
+ var node = createMissingNode(231 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
+ node.pos = fullStart;
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ return finishNode(node);
+ }
+ }
}
- function parseArrayLiteralExpression() {
- var node = createNode(164 /* ArrayLiteralExpression */);
- parseExpected(19 /* OpenBracketToken */);
- if (scanner.hasPrecedingLineBreak())
- node.flags |= 1024 /* MultiLine */;
- node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
- parseExpected(20 /* CloseBracketToken */);
- return finishNode(node);
+ function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
+ nextToken();
+ return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === 9 /* StringLiteral */);
}
- function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
- if (parseContextualModifier(123 /* GetKeyword */)) {
- return parseAccessorDeclaration(145 /* GetAccessor */, fullStart, decorators, modifiers);
- }
- else if (parseContextualModifier(129 /* SetKeyword */)) {
- return parseAccessorDeclaration(146 /* SetAccessor */, fullStart, decorators, modifiers);
+ function parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage) {
+ if (token !== 15 /* OpenBraceToken */ && canParseSemicolon()) {
+ parseSemicolon();
+ return;
}
- return undefined;
+ return parseFunctionBlock(isGenerator, isAsync, /*ignoreMissingOpenBrace*/ false, diagnosticMessage);
}
- function parseObjectLiteralElement() {
- var fullStart = scanner.getStartPos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
- if (accessor) {
- return accessor;
- }
- var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
- var tokenIsIdentifier = isIdentifier();
- var nameToken = token;
- var propertyName = parsePropertyName();
- // Disallowing of optional property assignments happens in the grammar checker.
- var questionToken = parseOptionalToken(53 /* QuestionToken */);
- if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
- return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
+ // DECLARATIONS
+ function parseArrayBindingElement() {
+ if (token === 24 /* CommaToken */) {
+ return createNode(187 /* OmittedExpression */);
}
- // check if it is short-hand property assignment or normal property assignment
- // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
- // CoverInitializedName[Yield] :
- // IdentifierReference[?Yield] Initializer[In, ?Yield]
- // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
- var isShorthandPropertyAssignment = tokenIsIdentifier && (token === 24 /* CommaToken */ || token === 16 /* CloseBraceToken */ || token === 56 /* EqualsToken */);
- if (isShorthandPropertyAssignment) {
- var shorthandDeclaration = createNode(246 /* ShorthandPropertyAssignment */, fullStart);
- shorthandDeclaration.name = propertyName;
- shorthandDeclaration.questionToken = questionToken;
- var equalsToken = parseOptionalToken(56 /* EqualsToken */);
- if (equalsToken) {
- shorthandDeclaration.equalsToken = equalsToken;
- shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
- }
- return finishNode(shorthandDeclaration);
+ var node = createNode(163 /* BindingElement */);
+ node.dotDotDotToken = parseOptionalToken(22 /* DotDotDotToken */);
+ node.name = parseIdentifierOrPattern();
+ node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
+ return finishNode(node);
+ }
+ function parseObjectBindingElement() {
+ var node = createNode(163 /* BindingElement */);
+ var tokenIsIdentifier = isIdentifier();
+ var propertyName = parsePropertyName();
+ if (tokenIsIdentifier && token !== 54 /* ColonToken */) {
+ node.name = propertyName;
}
else {
- var propertyAssignment = createNode(245 /* PropertyAssignment */, fullStart);
- propertyAssignment.name = propertyName;
- propertyAssignment.questionToken = questionToken;
parseExpected(54 /* ColonToken */);
- propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
- return finishNode(propertyAssignment);
+ node.propertyName = propertyName;
+ node.name = parseIdentifierOrPattern();
}
+ node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
+ return finishNode(node);
}
- function parseObjectLiteralExpression() {
- var node = createNode(165 /* ObjectLiteralExpression */);
+ function parseObjectBindingPattern() {
+ var node = createNode(161 /* ObjectBindingPattern */);
parseExpected(15 /* OpenBraceToken */);
- if (scanner.hasPrecedingLineBreak()) {
- node.flags |= 1024 /* MultiLine */;
- }
- node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimeter*/ true);
+ node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
parseExpected(16 /* CloseBraceToken */);
return finishNode(node);
}
- function parseFunctionExpression() {
- // GeneratorExpression:
- // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
- //
- // FunctionExpression:
- // function BindingIdentifier[opt](FormalParameters){ FunctionBody }
- var saveDecoratorContext = inDecoratorContext();
- if (saveDecoratorContext) {
- setDecoratorContext(false);
- }
- var node = createNode(173 /* FunctionExpression */);
- setModifiers(node, parseModifiers());
- parseExpected(87 /* FunctionKeyword */);
- node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
- var isGenerator = !!node.asteriskToken;
- var isAsync = !!(node.flags & 256 /* Async */);
- node.name =
- isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
- isGenerator ? doInYieldContext(parseOptionalIdentifier) :
- isAsync ? doInAwaitContext(parseOptionalIdentifier) :
- parseOptionalIdentifier();
- fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
- node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
- if (saveDecoratorContext) {
- setDecoratorContext(true);
- }
+ function parseArrayBindingPattern() {
+ var node = createNode(162 /* ArrayBindingPattern */);
+ parseExpected(19 /* OpenBracketToken */);
+ node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
+ parseExpected(20 /* CloseBracketToken */);
return finishNode(node);
}
- function parseOptionalIdentifier() {
- return isIdentifier() ? parseIdentifier() : undefined;
+ function isIdentifierOrPattern() {
+ return token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */ || isIdentifier();
}
- function parseNewExpression() {
- var node = createNode(169 /* NewExpression */);
- parseExpected(92 /* NewKeyword */);
- node.expression = parseMemberExpressionOrHigher();
- node.typeArguments = tryParse(parseTypeArgumentsInExpression);
- if (node.typeArguments || token === 17 /* OpenParenToken */) {
- node.arguments = parseArgumentList();
+ function parseIdentifierOrPattern() {
+ if (token === 19 /* OpenBracketToken */) {
+ return parseArrayBindingPattern();
+ }
+ if (token === 15 /* OpenBraceToken */) {
+ return parseObjectBindingPattern();
+ }
+ return parseIdentifier();
+ }
+ function parseVariableDeclaration() {
+ var node = createNode(211 /* VariableDeclaration */);
+ node.name = parseIdentifierOrPattern();
+ node.type = parseTypeAnnotation();
+ if (!isInOrOfKeyword(token)) {
+ node.initializer = parseInitializer(/*inParameter*/ false);
}
return finishNode(node);
}
- // STATEMENTS
- function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
- var node = createNode(192 /* Block */);
- if (parseExpected(15 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
- node.statements = parseList(1 /* BlockStatements */, parseStatement);
- parseExpected(16 /* CloseBraceToken */);
+ function parseVariableDeclarationList(inForStatementInitializer) {
+ var node = createNode(212 /* VariableDeclarationList */);
+ switch (token) {
+ case 102 /* VarKeyword */:
+ break;
+ case 108 /* LetKeyword */:
+ node.flags |= 8192 /* Let */;
+ break;
+ case 74 /* ConstKeyword */:
+ node.flags |= 16384 /* Const */;
+ break;
+ default:
+ ts.Debug.fail();
+ }
+ nextToken();
+ // The user may have written the following:
+ //
+ // for (let of X) { }
+ //
+ // In this case, we want to parse an empty declaration list, and then parse 'of'
+ // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
+ // So we need to look ahead to determine if 'of' should be treated as a keyword in
+ // this context.
+ // The checker will then give an error that there is an empty declaration list.
+ if (token === 134 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
+ node.declarations = createMissingList();
}
else {
- node.statements = createMissingList();
+ var savedDisallowIn = inDisallowInContext();
+ setDisallowInContext(inForStatementInitializer);
+ node.declarations = parseDelimitedList(8 /* VariableDeclarations */, parseVariableDeclaration);
+ setDisallowInContext(savedDisallowIn);
}
return finishNode(node);
}
- function parseFunctionBlock(allowYield, allowAwait, ignoreMissingOpenBrace, diagnosticMessage) {
- var savedYieldContext = inYieldContext();
- setYieldContext(allowYield);
- var savedAwaitContext = inAwaitContext();
- setAwaitContext(allowAwait);
- // We may be in a [Decorator] context when parsing a function expression or
- // arrow function. The body of the function is not in [Decorator] context.
- var saveDecoratorContext = inDecoratorContext();
- if (saveDecoratorContext) {
- setDecoratorContext(false);
- }
- var block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
- if (saveDecoratorContext) {
- setDecoratorContext(true);
- }
- setYieldContext(savedYieldContext);
- setAwaitContext(savedAwaitContext);
- return block;
+ function canFollowContextualOfKeyword() {
+ return nextTokenIsIdentifier() && nextToken() === 18 /* CloseParenToken */;
}
- function parseEmptyStatement() {
- var node = createNode(194 /* EmptyStatement */);
- parseExpected(23 /* SemicolonToken */);
+ function parseVariableStatement(fullStart, decorators, modifiers) {
+ var node = createNode(193 /* VariableStatement */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
+ parseSemicolon();
return finishNode(node);
}
- function parseIfStatement() {
- var node = createNode(196 /* IfStatement */);
- parseExpected(88 /* IfKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- node.thenStatement = parseStatement();
- node.elseStatement = parseOptional(80 /* ElseKeyword */) ? parseStatement() : undefined;
+ function parseFunctionDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(213 /* FunctionDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(87 /* FunctionKeyword */);
+ node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
+ node.name = node.flags & 512 /* Default */ ? parseOptionalIdentifier() : parseIdentifier();
+ var isGenerator = !!node.asteriskToken;
+ var isAsync = !!(node.flags & 256 /* Async */);
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
+ node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, ts.Diagnostics.or_expected);
return finishNode(node);
}
- function parseDoStatement() {
- var node = createNode(197 /* DoStatement */);
- parseExpected(79 /* DoKeyword */);
- node.statement = parseStatement();
- parseExpected(104 /* WhileKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
- // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
- // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
- // do;while(0)x will have a semicolon inserted before x.
- parseOptional(23 /* SemicolonToken */);
+ function parseConstructorDeclaration(pos, decorators, modifiers) {
+ var node = createNode(144 /* Constructor */, pos);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(121 /* ConstructorKeyword */);
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
+ node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false, ts.Diagnostics.or_expected);
return finishNode(node);
}
- function parseWhileStatement() {
- var node = createNode(198 /* WhileStatement */);
- parseExpected(104 /* WhileKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- node.statement = parseStatement();
+ function parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, diagnosticMessage) {
+ var method = createNode(143 /* MethodDeclaration */, fullStart);
+ method.decorators = decorators;
+ setModifiers(method, modifiers);
+ method.asteriskToken = asteriskToken;
+ method.name = name;
+ method.questionToken = questionToken;
+ var isGenerator = !!asteriskToken;
+ var isAsync = !!(method.flags & 256 /* Async */);
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, method);
+ method.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage);
+ return finishNode(method);
+ }
+ function parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken) {
+ var property = createNode(141 /* PropertyDeclaration */, fullStart);
+ property.decorators = decorators;
+ setModifiers(property, modifiers);
+ property.name = name;
+ property.questionToken = questionToken;
+ property.type = parseTypeAnnotation();
+ // For instance properties specifically, since they are evaluated inside the constructor,
+ // we do *not * want to parse yield expressions, so we specifically turn the yield context
+ // off. The grammar would look something like this:
+ //
+ // MemberVariableDeclaration[Yield]:
+ // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initialiser_opt[In];
+ // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initialiser_opt[In, ?Yield];
+ //
+ // The checker may still error in the static case to explicitly disallow the yield expression.
+ property.initializer = modifiers && modifiers.flags & 64 /* Static */
+ ? allowInAnd(parseNonParameterInitializer)
+ : doOutsideOfContext(2 /* Yield */ | 1 /* DisallowIn */, parseNonParameterInitializer);
+ parseSemicolon();
+ return finishNode(property);
+ }
+ function parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers) {
+ var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
+ var name = parsePropertyName();
+ // Note: this is not legal as per the grammar. But we allow it in the parser and
+ // report an error in the grammar checker.
+ var questionToken = parseOptionalToken(53 /* QuestionToken */);
+ if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
+ return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, ts.Diagnostics.or_expected);
+ }
+ else {
+ return parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken);
+ }
+ }
+ function parseNonParameterInitializer() {
+ return parseInitializer(/*inParameter*/ false);
+ }
+ function parseAccessorDeclaration(kind, fullStart, decorators, modifiers) {
+ var node = createNode(kind, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.name = parsePropertyName();
+ fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
+ node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false);
return finishNode(node);
}
- function parseForOrForInOrForOfStatement() {
- var pos = getNodePos();
- parseExpected(86 /* ForKeyword */);
- parseExpected(17 /* OpenParenToken */);
- var initializer = undefined;
- if (token !== 23 /* SemicolonToken */) {
- if (token === 102 /* VarKeyword */ || token === 108 /* LetKeyword */ || token === 74 /* ConstKeyword */) {
- initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
+ function isClassMemberModifier(idToken) {
+ switch (idToken) {
+ case 112 /* PublicKeyword */:
+ case 110 /* PrivateKeyword */:
+ case 111 /* ProtectedKeyword */:
+ case 113 /* StaticKeyword */:
+ return true;
+ default:
+ return false;
+ }
+ }
+ function isClassMemberStart() {
+ var idToken;
+ if (token === 55 /* AtToken */) {
+ return true;
+ }
+ // Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
+ while (ts.isModifier(token)) {
+ idToken = token;
+ // If the idToken is a class modifier (protected, private, public, and static), it is
+ // certain that we are starting to parse class member. This allows better error recovery
+ // Example:
+ // public foo() ... // true
+ // public @dec blah ... // true; we will then report an error later
+ // export public ... // true; we will then report an error later
+ if (isClassMemberModifier(idToken)) {
+ return true;
}
- else {
- initializer = disallowInAnd(parseExpression);
+ nextToken();
+ }
+ if (token === 37 /* AsteriskToken */) {
+ return true;
+ }
+ // Try to get the first property-like token following all modifiers.
+ // This can either be an identifier or the 'get' or 'set' keywords.
+ if (isLiteralPropertyName()) {
+ idToken = token;
+ nextToken();
+ }
+ // Index signatures and computed properties are class members; we can parse.
+ if (token === 19 /* OpenBracketToken */) {
+ return true;
+ }
+ // If we were able to get any potential identifier...
+ if (idToken !== undefined) {
+ // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
+ if (!ts.isKeyword(idToken) || idToken === 129 /* SetKeyword */ || idToken === 123 /* GetKeyword */) {
+ return true;
+ }
+ // If it *is* a keyword, but not an accessor, check a little farther along
+ // to see if it should actually be parsed as a class member.
+ switch (token) {
+ case 17 /* OpenParenToken */: // Method declaration
+ case 25 /* LessThanToken */: // Generic Method declaration
+ case 54 /* ColonToken */: // Type Annotation for declaration
+ case 56 /* EqualsToken */: // Initializer for declaration
+ case 53 /* QuestionToken */:
+ return true;
+ default:
+ // Covers
+ // - Semicolons (declaration termination)
+ // - Closing braces (end-of-class, must be declaration)
+ // - End-of-files (not valid, but permitted so that it gets caught later on)
+ // - Line-breaks (enabling *automatic semicolon insertion*)
+ return canParseSemicolon();
}
}
- var forOrForInOrForOfStatement;
- if (parseOptional(90 /* InKeyword */)) {
- var forInStatement = createNode(200 /* ForInStatement */, pos);
- forInStatement.initializer = initializer;
- forInStatement.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- forOrForInOrForOfStatement = forInStatement;
+ return false;
+ }
+ function parseDecorators() {
+ var decorators;
+ while (true) {
+ var decoratorStart = getNodePos();
+ if (!parseOptional(55 /* AtToken */)) {
+ break;
+ }
+ if (!decorators) {
+ decorators = [];
+ decorators.pos = scanner.getStartPos();
+ }
+ var decorator = createNode(139 /* Decorator */, decoratorStart);
+ decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
+ decorators.push(finishNode(decorator));
}
- else if (parseOptional(134 /* OfKeyword */)) {
- var forOfStatement = createNode(201 /* ForOfStatement */, pos);
- forOfStatement.initializer = initializer;
- forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
- parseExpected(18 /* CloseParenToken */);
- forOrForInOrForOfStatement = forOfStatement;
+ if (decorators) {
+ decorators.end = getNodeEnd();
}
- else {
- var forStatement = createNode(199 /* ForStatement */, pos);
- forStatement.initializer = initializer;
- parseExpected(23 /* SemicolonToken */);
- if (token !== 23 /* SemicolonToken */ && token !== 18 /* CloseParenToken */) {
- forStatement.condition = allowInAnd(parseExpression);
+ return decorators;
+ }
+ function parseModifiers() {
+ var flags = 0;
+ var modifiers;
+ while (true) {
+ var modifierStart = scanner.getStartPos();
+ var modifierKind = token;
+ if (!parseAnyContextualModifier()) {
+ break;
}
- parseExpected(23 /* SemicolonToken */);
- if (token !== 18 /* CloseParenToken */) {
- forStatement.incrementor = allowInAnd(parseExpression);
+ if (!modifiers) {
+ modifiers = [];
+ modifiers.pos = modifierStart;
}
- parseExpected(18 /* CloseParenToken */);
- forOrForInOrForOfStatement = forStatement;
+ flags |= ts.modifierToFlag(modifierKind);
+ modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
}
- forOrForInOrForOfStatement.statement = parseStatement();
- return finishNode(forOrForInOrForOfStatement);
+ if (modifiers) {
+ modifiers.flags = flags;
+ modifiers.end = scanner.getStartPos();
+ }
+ return modifiers;
}
- function parseBreakOrContinueStatement(kind) {
- var node = createNode(kind);
- parseExpected(kind === 203 /* BreakStatement */ ? 70 /* BreakKeyword */ : 75 /* ContinueKeyword */);
- if (!canParseSemicolon()) {
- node.label = parseIdentifier();
+ function parseModifiersForArrowFunction() {
+ var flags = 0;
+ var modifiers;
+ if (token === 118 /* AsyncKeyword */) {
+ var modifierStart = scanner.getStartPos();
+ var modifierKind = token;
+ nextToken();
+ modifiers = [];
+ modifiers.pos = modifierStart;
+ flags |= ts.modifierToFlag(modifierKind);
+ modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
+ modifiers.flags = flags;
+ modifiers.end = scanner.getStartPos();
}
- parseSemicolon();
- return finishNode(node);
+ return modifiers;
}
- function parseReturnStatement() {
- var node = createNode(204 /* ReturnStatement */);
- parseExpected(94 /* ReturnKeyword */);
- if (!canParseSemicolon()) {
- node.expression = allowInAnd(parseExpression);
+ function parseClassElement() {
+ if (token === 23 /* SemicolonToken */) {
+ var result = createNode(191 /* SemicolonClassElement */);
+ nextToken();
+ return finishNode(result);
}
- parseSemicolon();
- return finishNode(node);
+ var fullStart = getNodePos();
+ var decorators = parseDecorators();
+ var modifiers = parseModifiers();
+ var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
+ if (accessor) {
+ return accessor;
+ }
+ if (token === 121 /* ConstructorKeyword */) {
+ return parseConstructorDeclaration(fullStart, decorators, modifiers);
+ }
+ if (isIndexSignature()) {
+ return parseIndexSignatureDeclaration(fullStart, decorators, modifiers);
+ }
+ // It is very important that we check this *after* checking indexers because
+ // the [ token can start an index signature or a computed property name
+ if (ts.tokenIsIdentifierOrKeyword(token) ||
+ token === 9 /* StringLiteral */ ||
+ token === 8 /* NumericLiteral */ ||
+ token === 37 /* AsteriskToken */ ||
+ token === 19 /* OpenBracketToken */) {
+ return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
+ }
+ if (decorators || modifiers) {
+ // treat this as a property declaration with a missing name.
+ var name_7 = createMissingNode(69 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
+ return parsePropertyDeclaration(fullStart, decorators, modifiers, name_7, /*questionToken*/ undefined);
+ }
+ // 'isClassMemberStart' should have hinted not to attempt parsing.
+ ts.Debug.fail("Should not have attempted to parse class member declaration.");
}
- function parseWithStatement() {
- var node = createNode(205 /* WithStatement */);
- parseExpected(105 /* WithKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- node.statement = parseStatement();
+ function parseClassExpression() {
+ return parseClassDeclarationOrExpression(
+ /*fullStart*/ scanner.getStartPos(),
+ /*decorators*/ undefined,
+ /*modifiers*/ undefined, 186 /* ClassExpression */);
+ }
+ function parseClassDeclaration(fullStart, decorators, modifiers) {
+ return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 214 /* ClassDeclaration */);
+ }
+ function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
+ var node = createNode(kind, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(73 /* ClassKeyword */);
+ node.name = parseNameOfClassDeclarationOrExpression();
+ node.typeParameters = parseTypeParameters();
+ node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
+ if (parseExpected(15 /* OpenBraceToken */)) {
+ // ClassTail[Yield,Await] : (Modified) See 14.5
+ // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
+ node.members = parseClassMembers();
+ parseExpected(16 /* CloseBraceToken */);
+ }
+ else {
+ node.members = createMissingList();
+ }
return finishNode(node);
}
- function parseCaseClause() {
- var node = createNode(241 /* CaseClause */);
- parseExpected(71 /* CaseKeyword */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(54 /* ColonToken */);
- node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
- return finishNode(node);
+ function parseNameOfClassDeclarationOrExpression() {
+ // implements is a future reserved word so
+ // 'class implements' might mean either
+ // - class expression with omitted name, 'implements' starts heritage clause
+ // - class with name 'implements'
+ // 'isImplementsClause' helps to disambiguate between these two cases
+ return isIdentifier() && !isImplementsClause()
+ ? parseIdentifier()
+ : undefined;
+ }
+ function isImplementsClause() {
+ return token === 106 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
+ }
+ function parseHeritageClauses(isClassHeritageClause) {
+ // ClassTail[Yield,Await] : (Modified) See 14.5
+ // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
+ if (isHeritageClause()) {
+ return parseList(20 /* HeritageClauses */, parseHeritageClause);
+ }
+ return undefined;
+ }
+ function parseHeritageClausesWorker() {
+ return parseList(20 /* HeritageClauses */, parseHeritageClause);
+ }
+ function parseHeritageClause() {
+ if (token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */) {
+ var node = createNode(243 /* HeritageClause */);
+ node.token = token;
+ nextToken();
+ node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
+ return finishNode(node);
+ }
+ return undefined;
}
- function parseDefaultClause() {
- var node = createNode(242 /* DefaultClause */);
- parseExpected(77 /* DefaultKeyword */);
- parseExpected(54 /* ColonToken */);
- node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
+ function parseExpressionWithTypeArguments() {
+ var node = createNode(188 /* ExpressionWithTypeArguments */);
+ node.expression = parseLeftHandSideExpressionOrHigher();
+ if (token === 25 /* LessThanToken */) {
+ node.typeArguments = parseBracketedList(18 /* TypeArguments */, parseType, 25 /* LessThanToken */, 27 /* GreaterThanToken */);
+ }
return finishNode(node);
}
- function parseCaseOrDefaultClause() {
- return token === 71 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
+ function isHeritageClause() {
+ return token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
}
- function parseSwitchStatement() {
- var node = createNode(206 /* SwitchStatement */);
- parseExpected(96 /* SwitchKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = allowInAnd(parseExpression);
- parseExpected(18 /* CloseParenToken */);
- var caseBlock = createNode(220 /* CaseBlock */, scanner.getStartPos());
- parseExpected(15 /* OpenBraceToken */);
- caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
- parseExpected(16 /* CloseBraceToken */);
- node.caseBlock = finishNode(caseBlock);
+ function parseClassMembers() {
+ return parseList(5 /* ClassMembers */, parseClassElement);
+ }
+ function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(215 /* InterfaceDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(107 /* InterfaceKeyword */);
+ node.name = parseIdentifier();
+ node.typeParameters = parseTypeParameters();
+ node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false);
+ node.members = parseObjectTypeMembers();
return finishNode(node);
}
- function parseThrowStatement() {
- // ThrowStatement[Yield] :
- // throw [no LineTerminator here]Expression[In, ?Yield];
- // Because of automatic semicolon insertion, we need to report error if this
- // throw could be terminated with a semicolon. Note: we can't call 'parseExpression'
- // directly as that might consume an expression on the following line.
- // We just return 'undefined' in that case. The actual error will be reported in the
- // grammar walker.
- var node = createNode(208 /* ThrowStatement */);
- parseExpected(98 /* ThrowKeyword */);
- node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
+ function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(216 /* TypeAliasDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(132 /* TypeKeyword */);
+ node.name = parseIdentifier();
+ node.typeParameters = parseTypeParameters();
+ parseExpected(56 /* EqualsToken */);
+ node.type = parseType();
parseSemicolon();
return finishNode(node);
}
- // TODO: Review for error recovery
- function parseTryStatement() {
- var node = createNode(209 /* TryStatement */);
- parseExpected(100 /* TryKeyword */);
- node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
- node.catchClause = token === 72 /* CatchKeyword */ ? parseCatchClause() : undefined;
- // If we don't have a catch clause, then we must have a finally clause. Try to parse
- // one out no matter what.
- if (!node.catchClause || token === 85 /* FinallyKeyword */) {
- parseExpected(85 /* FinallyKeyword */);
- node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
- }
+ // In an ambient declaration, the grammar only allows integer literals as initializers.
+ // In a non-ambient declaration, the grammar allows uninitialized members only in a
+ // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
+ // or any time an integer literal initializer is encountered.
+ function parseEnumMember() {
+ var node = createNode(247 /* EnumMember */, scanner.getStartPos());
+ node.name = parsePropertyName();
+ node.initializer = allowInAnd(parseNonParameterInitializer);
return finishNode(node);
}
- function parseCatchClause() {
- var result = createNode(244 /* CatchClause */);
- parseExpected(72 /* CatchKeyword */);
- if (parseExpected(17 /* OpenParenToken */)) {
- result.variableDeclaration = parseVariableDeclaration();
+ function parseEnumDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(217 /* EnumDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ parseExpected(81 /* EnumKeyword */);
+ node.name = parseIdentifier();
+ if (parseExpected(15 /* OpenBraceToken */)) {
+ node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember);
+ parseExpected(16 /* CloseBraceToken */);
+ }
+ else {
+ node.members = createMissingList();
}
- parseExpected(18 /* CloseParenToken */);
- result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
- return finishNode(result);
- }
- function parseDebuggerStatement() {
- var node = createNode(210 /* DebuggerStatement */);
- parseExpected(76 /* DebuggerKeyword */);
- parseSemicolon();
return finishNode(node);
}
- function parseExpressionOrLabeledStatement() {
- // Avoiding having to do the lookahead for a labeled statement by just trying to parse
- // out an expression, seeing if it is identifier and then seeing if it is followed by
- // a colon.
- var fullStart = scanner.getStartPos();
- var expression = allowInAnd(parseExpression);
- if (expression.kind === 69 /* Identifier */ && parseOptional(54 /* ColonToken */)) {
- var labeledStatement = createNode(207 /* LabeledStatement */, fullStart);
- labeledStatement.label = expression;
- labeledStatement.statement = parseStatement();
- return finishNode(labeledStatement);
+ function parseModuleBlock() {
+ var node = createNode(219 /* ModuleBlock */, scanner.getStartPos());
+ if (parseExpected(15 /* OpenBraceToken */)) {
+ node.statements = parseList(1 /* BlockStatements */, parseStatement);
+ parseExpected(16 /* CloseBraceToken */);
}
else {
- var expressionStatement = createNode(195 /* ExpressionStatement */, fullStart);
- expressionStatement.expression = expression;
- parseSemicolon();
- return finishNode(expressionStatement);
+ node.statements = createMissingList();
}
+ return finishNode(node);
}
- function nextTokenIsIdentifierOrKeywordOnSameLine() {
- nextToken();
- return ts.tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
- }
- function nextTokenIsFunctionKeywordOnSameLine() {
- nextToken();
- return token === 87 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
+ function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
+ var node = createNode(218 /* ModuleDeclaration */, fullStart);
+ // If we are parsing a dotted namespace name, we want to
+ // propagate the 'Namespace' flag across the names if set.
+ var namespaceFlag = flags & 65536 /* Namespace */;
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.flags |= flags;
+ node.name = parseIdentifier();
+ node.body = parseOptional(21 /* DotToken */)
+ ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, 2 /* Export */ | namespaceFlag)
+ : parseModuleBlock();
+ return finishNode(node);
}
- function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
- nextToken();
- return (ts.tokenIsIdentifierOrKeyword(token) || token === 8 /* NumericLiteral */) && !scanner.hasPrecedingLineBreak();
+ function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(218 /* ModuleDeclaration */, fullStart);
+ node.decorators = decorators;
+ setModifiers(node, modifiers);
+ node.name = parseLiteralNode(/*internName*/ true);
+ node.body = parseModuleBlock();
+ return finishNode(node);
}
- function isDeclaration() {
- while (true) {
- switch (token) {
- case 102 /* VarKeyword */:
- case 108 /* LetKeyword */:
- case 74 /* ConstKeyword */:
- case 87 /* FunctionKeyword */:
- case 73 /* ClassKeyword */:
- case 81 /* EnumKeyword */:
- return true;
- // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
- // however, an identifier cannot be followed by another identifier on the same line. This is what we
- // count on to parse out the respective declarations. For instance, we exploit this to say that
- //
- // namespace n
- //
- // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
- //
- // namespace
- // n
- //
- // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
- // We need to look one token ahead to see if it permissible to try parsing a declaration.
- //
- // *Note*: 'interface' is actually a strict mode reserved word. So while
- //
- // "use strict"
- // interface
- // I {}
- //
- // could be legal, it would add complexity for very little gain.
- case 107 /* InterfaceKeyword */:
- case 132 /* TypeKeyword */:
- return nextTokenIsIdentifierOnSameLine();
- case 125 /* ModuleKeyword */:
- case 126 /* NamespaceKeyword */:
- return nextTokenIsIdentifierOrStringLiteralOnSameLine();
- case 115 /* AbstractKeyword */:
- case 118 /* AsyncKeyword */:
- case 122 /* DeclareKeyword */:
- case 110 /* PrivateKeyword */:
- case 111 /* ProtectedKeyword */:
- case 112 /* PublicKeyword */:
- nextToken();
- // ASI takes effect for this modifier.
- if (scanner.hasPrecedingLineBreak()) {
- return false;
- }
- continue;
- case 89 /* ImportKeyword */:
- nextToken();
- return token === 9 /* StringLiteral */ || token === 37 /* AsteriskToken */ ||
- token === 15 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token);
- case 82 /* ExportKeyword */:
- nextToken();
- if (token === 56 /* EqualsToken */ || token === 37 /* AsteriskToken */ ||
- token === 15 /* OpenBraceToken */ || token === 77 /* DefaultKeyword */) {
- return true;
- }
- continue;
- case 113 /* StaticKeyword */:
- nextToken();
- continue;
- default:
- return false;
- }
+ function parseModuleDeclaration(fullStart, decorators, modifiers) {
+ var flags = modifiers ? modifiers.flags : 0;
+ if (parseOptional(126 /* NamespaceKeyword */)) {
+ flags |= 65536 /* Namespace */;
}
- }
- function isStartOfDeclaration() {
- return lookAhead(isDeclaration);
- }
- function isStartOfStatement() {
- switch (token) {
- case 55 /* AtToken */:
- case 23 /* SemicolonToken */:
- case 15 /* OpenBraceToken */:
- case 102 /* VarKeyword */:
- case 108 /* LetKeyword */:
- case 87 /* FunctionKeyword */:
- case 73 /* ClassKeyword */:
- case 81 /* EnumKeyword */:
- case 88 /* IfKeyword */:
- case 79 /* DoKeyword */:
- case 104 /* WhileKeyword */:
- case 86 /* ForKeyword */:
- case 75 /* ContinueKeyword */:
- case 70 /* BreakKeyword */:
- case 94 /* ReturnKeyword */:
- case 105 /* WithKeyword */:
- case 96 /* SwitchKeyword */:
- case 98 /* ThrowKeyword */:
- case 100 /* TryKeyword */:
- case 76 /* DebuggerKeyword */:
- // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
- // however, we say they are here so that we may gracefully parse them and error later.
- case 72 /* CatchKeyword */:
- case 85 /* FinallyKeyword */:
- return true;
- case 74 /* ConstKeyword */:
- case 82 /* ExportKeyword */:
- case 89 /* ImportKeyword */:
- return isStartOfDeclaration();
- case 118 /* AsyncKeyword */:
- case 122 /* DeclareKeyword */:
- case 107 /* InterfaceKeyword */:
- case 125 /* ModuleKeyword */:
- case 126 /* NamespaceKeyword */:
- case 132 /* TypeKeyword */:
- // When these don't start a declaration, they're an identifier in an expression statement
- return true;
- case 112 /* PublicKeyword */:
- case 110 /* PrivateKeyword */:
- case 111 /* ProtectedKeyword */:
- case 113 /* StaticKeyword */:
- // When these don't start a declaration, they may be the start of a class member if an identifier
- // immediately follows. Otherwise they're an identifier in an expression statement.
- return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
- default:
- return isStartOfExpression();
+ else {
+ parseExpected(125 /* ModuleKeyword */);
+ if (token === 9 /* StringLiteral */) {
+ return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
+ }
}
+ return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
}
- function nextTokenIsIdentifierOrStartOfDestructuring() {
- nextToken();
- return isIdentifier() || token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */;
- }
- function isLetDeclaration() {
- // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
- // or [.
- return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
+ function isExternalModuleReference() {
+ return token === 127 /* RequireKeyword */ &&
+ lookAhead(nextTokenIsOpenParen);
}
- function parseStatement() {
- switch (token) {
- case 23 /* SemicolonToken */:
- return parseEmptyStatement();
- case 15 /* OpenBraceToken */:
- return parseBlock(/*ignoreMissingOpenBrace*/ false);
- case 102 /* VarKeyword */:
- return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
- case 108 /* LetKeyword */:
- if (isLetDeclaration()) {
- return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
- }
- break;
- case 87 /* FunctionKeyword */:
- return parseFunctionDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
- case 73 /* ClassKeyword */:
- return parseClassDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
- case 88 /* IfKeyword */:
- return parseIfStatement();
- case 79 /* DoKeyword */:
- return parseDoStatement();
- case 104 /* WhileKeyword */:
- return parseWhileStatement();
- case 86 /* ForKeyword */:
- return parseForOrForInOrForOfStatement();
- case 75 /* ContinueKeyword */:
- return parseBreakOrContinueStatement(202 /* ContinueStatement */);
- case 70 /* BreakKeyword */:
- return parseBreakOrContinueStatement(203 /* BreakStatement */);
- case 94 /* ReturnKeyword */:
- return parseReturnStatement();
- case 105 /* WithKeyword */:
- return parseWithStatement();
- case 96 /* SwitchKeyword */:
- return parseSwitchStatement();
- case 98 /* ThrowKeyword */:
- return parseThrowStatement();
- case 100 /* TryKeyword */:
- // Include 'catch' and 'finally' for error recovery.
- case 72 /* CatchKeyword */:
- case 85 /* FinallyKeyword */:
- return parseTryStatement();
- case 76 /* DebuggerKeyword */:
- return parseDebuggerStatement();
- case 55 /* AtToken */:
- return parseDeclaration();
- case 118 /* AsyncKeyword */:
- case 107 /* InterfaceKeyword */:
- case 132 /* TypeKeyword */:
- case 125 /* ModuleKeyword */:
- case 126 /* NamespaceKeyword */:
- case 122 /* DeclareKeyword */:
- case 74 /* ConstKeyword */:
- case 81 /* EnumKeyword */:
- case 82 /* ExportKeyword */:
- case 89 /* ImportKeyword */:
- case 110 /* PrivateKeyword */:
- case 111 /* ProtectedKeyword */:
- case 112 /* PublicKeyword */:
- case 115 /* AbstractKeyword */:
- case 113 /* StaticKeyword */:
- if (isStartOfDeclaration()) {
- return parseDeclaration();
- }
- break;
- }
- return parseExpressionOrLabeledStatement();
+ function nextTokenIsOpenParen() {
+ return nextToken() === 17 /* OpenParenToken */;
}
- function parseDeclaration() {
- var fullStart = getNodePos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- switch (token) {
- case 102 /* VarKeyword */:
- case 108 /* LetKeyword */:
- case 74 /* ConstKeyword */:
- return parseVariableStatement(fullStart, decorators, modifiers);
- case 87 /* FunctionKeyword */:
- return parseFunctionDeclaration(fullStart, decorators, modifiers);
- case 73 /* ClassKeyword */:
- return parseClassDeclaration(fullStart, decorators, modifiers);
- case 107 /* InterfaceKeyword */:
- return parseInterfaceDeclaration(fullStart, decorators, modifiers);
- case 132 /* TypeKeyword */:
- return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
- case 81 /* EnumKeyword */:
- return parseEnumDeclaration(fullStart, decorators, modifiers);
- case 125 /* ModuleKeyword */:
- case 126 /* NamespaceKeyword */:
- return parseModuleDeclaration(fullStart, decorators, modifiers);
- case 89 /* ImportKeyword */:
- return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
- case 82 /* ExportKeyword */:
- nextToken();
- return token === 77 /* DefaultKeyword */ || token === 56 /* EqualsToken */ ?
- parseExportAssignment(fullStart, decorators, modifiers) :
- parseExportDeclaration(fullStart, decorators, modifiers);
- default:
- if (decorators || modifiers) {
- // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
- // would follow. For recovery and error reporting purposes, return an incomplete declaration.
- var node = createMissingNode(231 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
- node.pos = fullStart;
- node.decorators = decorators;
- setModifiers(node, modifiers);
- return finishNode(node);
- }
- }
+ function nextTokenIsSlash() {
+ return nextToken() === 39 /* SlashToken */;
}
- function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
+ function nextTokenIsCommaOrFromKeyword() {
nextToken();
- return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === 9 /* StringLiteral */);
+ return token === 24 /* CommaToken */ ||
+ token === 133 /* FromKeyword */;
}
- function parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage) {
- if (token !== 15 /* OpenBraceToken */ && canParseSemicolon()) {
- parseSemicolon();
- return;
+ function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
+ parseExpected(89 /* ImportKeyword */);
+ var afterImportPos = scanner.getStartPos();
+ var identifier;
+ if (isIdentifier()) {
+ identifier = parseIdentifier();
+ if (token !== 24 /* CommaToken */ && token !== 133 /* FromKeyword */) {
+ // ImportEquals declaration of type:
+ // import x = require("mod"); or
+ // import x = M.x;
+ var importEqualsDeclaration = createNode(221 /* ImportEqualsDeclaration */, fullStart);
+ importEqualsDeclaration.decorators = decorators;
+ setModifiers(importEqualsDeclaration, modifiers);
+ importEqualsDeclaration.name = identifier;
+ parseExpected(56 /* EqualsToken */);
+ importEqualsDeclaration.moduleReference = parseModuleReference();
+ parseSemicolon();
+ return finishNode(importEqualsDeclaration);
+ }
}
- return parseFunctionBlock(isGenerator, isAsync, /*ignoreMissingOpenBrace*/ false, diagnosticMessage);
- }
- // DECLARATIONS
- function parseArrayBindingElement() {
- if (token === 24 /* CommaToken */) {
- return createNode(187 /* OmittedExpression */);
+ // Import statement
+ var importDeclaration = createNode(222 /* ImportDeclaration */, fullStart);
+ importDeclaration.decorators = decorators;
+ setModifiers(importDeclaration, modifiers);
+ // ImportDeclaration:
+ // import ImportClause from ModuleSpecifier ;
+ // import ModuleSpecifier;
+ if (identifier ||
+ token === 37 /* AsteriskToken */ ||
+ token === 15 /* OpenBraceToken */) {
+ importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
+ parseExpected(133 /* FromKeyword */);
}
- var node = createNode(163 /* BindingElement */);
- node.dotDotDotToken = parseOptionalToken(22 /* DotDotDotToken */);
- node.name = parseIdentifierOrPattern();
- node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
- return finishNode(node);
+ importDeclaration.moduleSpecifier = parseModuleSpecifier();
+ parseSemicolon();
+ return finishNode(importDeclaration);
}
- function parseObjectBindingElement() {
- var node = createNode(163 /* BindingElement */);
- // TODO(andersh): Handle computed properties
- var tokenIsIdentifier = isIdentifier();
- var propertyName = parsePropertyName();
- if (tokenIsIdentifier && token !== 54 /* ColonToken */) {
- node.name = propertyName;
+ function parseImportClause(identifier, fullStart) {
+ // ImportClause:
+ // ImportedDefaultBinding
+ // NameSpaceImport
+ // NamedImports
+ // ImportedDefaultBinding, NameSpaceImport
+ // ImportedDefaultBinding, NamedImports
+ var importClause = createNode(223 /* ImportClause */, fullStart);
+ if (identifier) {
+ // ImportedDefaultBinding:
+ // ImportedBinding
+ importClause.name = identifier;
}
- else {
- parseExpected(54 /* ColonToken */);
- node.propertyName = propertyName;
- node.name = parseIdentifierOrPattern();
+ // If there was no default import or if there is comma token after default import
+ // parse namespace or named imports
+ if (!importClause.name ||
+ parseOptional(24 /* CommaToken */)) {
+ importClause.namedBindings = token === 37 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(225 /* NamedImports */);
}
- node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
- return finishNode(node);
- }
- function parseObjectBindingPattern() {
- var node = createNode(161 /* ObjectBindingPattern */);
- parseExpected(15 /* OpenBraceToken */);
- node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
- parseExpected(16 /* CloseBraceToken */);
- return finishNode(node);
+ return finishNode(importClause);
}
- function parseArrayBindingPattern() {
- var node = createNode(162 /* ArrayBindingPattern */);
- parseExpected(19 /* OpenBracketToken */);
- node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
- parseExpected(20 /* CloseBracketToken */);
- return finishNode(node);
+ function parseModuleReference() {
+ return isExternalModuleReference()
+ ? parseExternalModuleReference()
+ : parseEntityName(/*allowReservedWords*/ false);
}
- function isIdentifierOrPattern() {
- return token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */ || isIdentifier();
+ function parseExternalModuleReference() {
+ var node = createNode(232 /* ExternalModuleReference */);
+ parseExpected(127 /* RequireKeyword */);
+ parseExpected(17 /* OpenParenToken */);
+ node.expression = parseModuleSpecifier();
+ parseExpected(18 /* CloseParenToken */);
+ return finishNode(node);
}
- function parseIdentifierOrPattern() {
- if (token === 19 /* OpenBracketToken */) {
- return parseArrayBindingPattern();
- }
- if (token === 15 /* OpenBraceToken */) {
- return parseObjectBindingPattern();
+ function parseModuleSpecifier() {
+ // We allow arbitrary expressions here, even though the grammar only allows string
+ // literals. We check to ensure that it is only a string literal later in the grammar
+ // walker.
+ var result = parseExpression();
+ // Ensure the string being required is in our 'identifier' table. This will ensure
+ // that features like 'find refs' will look inside this file when search for its name.
+ if (result.kind === 9 /* StringLiteral */) {
+ internIdentifier(result.text);
}
- return parseIdentifier();
+ return result;
}
- function parseVariableDeclaration() {
- var node = createNode(211 /* VariableDeclaration */);
- node.name = parseIdentifierOrPattern();
- node.type = parseTypeAnnotation();
- if (!isInOrOfKeyword(token)) {
- node.initializer = parseInitializer(/*inParameter*/ false);
- }
+ function parseNamespaceImport() {
+ // NameSpaceImport:
+ // * as ImportedBinding
+ var namespaceImport = createNode(224 /* NamespaceImport */);
+ parseExpected(37 /* AsteriskToken */);
+ parseExpected(116 /* AsKeyword */);
+ namespaceImport.name = parseIdentifier();
+ return finishNode(namespaceImport);
+ }
+ function parseNamedImportsOrExports(kind) {
+ var node = createNode(kind);
+ // NamedImports:
+ // { }
+ // { ImportsList }
+ // { ImportsList, }
+ // ImportsList:
+ // ImportSpecifier
+ // ImportsList, ImportSpecifier
+ node.elements = parseBracketedList(21 /* ImportOrExportSpecifiers */, kind === 225 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 15 /* OpenBraceToken */, 16 /* CloseBraceToken */);
return finishNode(node);
}
- function parseVariableDeclarationList(inForStatementInitializer) {
- var node = createNode(212 /* VariableDeclarationList */);
- switch (token) {
- case 102 /* VarKeyword */:
- break;
- case 108 /* LetKeyword */:
- node.flags |= 8192 /* Let */;
- break;
- case 74 /* ConstKeyword */:
- node.flags |= 16384 /* Const */;
- break;
- default:
- ts.Debug.fail();
- }
- nextToken();
- // The user may have written the following:
- //
- // for (let of X) { }
- //
- // In this case, we want to parse an empty declaration list, and then parse 'of'
- // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
- // So we need to look ahead to determine if 'of' should be treated as a keyword in
- // this context.
- // The checker will then give an error that there is an empty declaration list.
- if (token === 134 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
- node.declarations = createMissingList();
+ function parseExportSpecifier() {
+ return parseImportOrExportSpecifier(230 /* ExportSpecifier */);
+ }
+ function parseImportSpecifier() {
+ return parseImportOrExportSpecifier(226 /* ImportSpecifier */);
+ }
+ function parseImportOrExportSpecifier(kind) {
+ var node = createNode(kind);
+ // ImportSpecifier:
+ // BindingIdentifier
+ // IdentifierName as BindingIdentifier
+ // ExportSpecififer:
+ // IdentifierName
+ // IdentifierName as IdentifierName
+ var checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
+ var checkIdentifierStart = scanner.getTokenPos();
+ var checkIdentifierEnd = scanner.getTextPos();
+ var identifierName = parseIdentifierName();
+ if (token === 116 /* AsKeyword */) {
+ node.propertyName = identifierName;
+ parseExpected(116 /* AsKeyword */);
+ checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
+ checkIdentifierStart = scanner.getTokenPos();
+ checkIdentifierEnd = scanner.getTextPos();
+ node.name = parseIdentifierName();
}
else {
- var savedDisallowIn = inDisallowInContext();
- setDisallowInContext(inForStatementInitializer);
- node.declarations = parseDelimitedList(8 /* VariableDeclarations */, parseVariableDeclaration);
- setDisallowInContext(savedDisallowIn);
+ node.name = identifierName;
+ }
+ if (kind === 226 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
+ // Report error identifier expected
+ parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected);
}
return finishNode(node);
}
- function canFollowContextualOfKeyword() {
- return nextTokenIsIdentifier() && nextToken() === 18 /* CloseParenToken */;
- }
- function parseVariableStatement(fullStart, decorators, modifiers) {
- var node = createNode(193 /* VariableStatement */, fullStart);
+ function parseExportDeclaration(fullStart, decorators, modifiers) {
+ var node = createNode(228 /* ExportDeclaration */, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
- node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
+ if (parseOptional(37 /* AsteriskToken */)) {
+ parseExpected(133 /* FromKeyword */);
+ node.moduleSpecifier = parseModuleSpecifier();
+ }
+ else {
+ node.exportClause = parseNamedImportsOrExports(229 /* NamedExports */);
+ // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
+ // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
+ // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
+ if (token === 133 /* FromKeyword */ || (token === 9 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
+ parseExpected(133 /* FromKeyword */);
+ node.moduleSpecifier = parseModuleSpecifier();
+ }
+ }
parseSemicolon();
return finishNode(node);
}
- function parseFunctionDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(213 /* FunctionDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(87 /* FunctionKeyword */);
- node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
- node.name = node.flags & 512 /* Default */ ? parseOptionalIdentifier() : parseIdentifier();
- var isGenerator = !!node.asteriskToken;
- var isAsync = !!(node.flags & 256 /* Async */);
- fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
- node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, ts.Diagnostics.or_expected);
- return finishNode(node);
- }
- function parseConstructorDeclaration(pos, decorators, modifiers) {
- var node = createNode(144 /* Constructor */, pos);
+ function parseExportAssignment(fullStart, decorators, modifiers) {
+ var node = createNode(227 /* ExportAssignment */, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
- parseExpected(121 /* ConstructorKeyword */);
- fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
- node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false, ts.Diagnostics.or_expected);
- return finishNode(node);
- }
- function parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, diagnosticMessage) {
- var method = createNode(143 /* MethodDeclaration */, fullStart);
- method.decorators = decorators;
- setModifiers(method, modifiers);
- method.asteriskToken = asteriskToken;
- method.name = name;
- method.questionToken = questionToken;
- var isGenerator = !!asteriskToken;
- var isAsync = !!(method.flags & 256 /* Async */);
- fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, method);
- method.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage);
- return finishNode(method);
- }
- function parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken) {
- var property = createNode(141 /* PropertyDeclaration */, fullStart);
- property.decorators = decorators;
- setModifiers(property, modifiers);
- property.name = name;
- property.questionToken = questionToken;
- property.type = parseTypeAnnotation();
- // For instance properties specifically, since they are evaluated inside the constructor,
- // we do *not * want to parse yield expressions, so we specifically turn the yield context
- // off. The grammar would look something like this:
- //
- // MemberVariableDeclaration[Yield]:
- // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initialiser_opt[In];
- // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initialiser_opt[In, ?Yield];
- //
- // The checker may still error in the static case to explicitly disallow the yield expression.
- property.initializer = modifiers && modifiers.flags & 64 /* Static */
- ? allowInAnd(parseNonParameterInitializer)
- : doOutsideOfContext(2 /* Yield */ | 1 /* DisallowIn */, parseNonParameterInitializer);
- parseSemicolon();
- return finishNode(property);
- }
- function parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers) {
- var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
- var name = parsePropertyName();
- // Note: this is not legal as per the grammar. But we allow it in the parser and
- // report an error in the grammar checker.
- var questionToken = parseOptionalToken(53 /* QuestionToken */);
- if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
- return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, ts.Diagnostics.or_expected);
+ if (parseOptional(56 /* EqualsToken */)) {
+ node.isExportEquals = true;
}
else {
- return parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken);
+ parseExpected(77 /* DefaultKeyword */);
}
- }
- function parseNonParameterInitializer() {
- return parseInitializer(/*inParameter*/ false);
- }
- function parseAccessorDeclaration(kind, fullStart, decorators, modifiers) {
- var node = createNode(kind, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.name = parsePropertyName();
- fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
- node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false);
+ node.expression = parseAssignmentExpressionOrHigher();
+ parseSemicolon();
return finishNode(node);
}
- function isClassMemberModifier(idToken) {
- switch (idToken) {
- case 112 /* PublicKeyword */:
- case 110 /* PrivateKeyword */:
- case 111 /* ProtectedKeyword */:
- case 113 /* StaticKeyword */:
- return true;
- default:
- return false;
+ function processReferenceComments(sourceFile) {
+ var triviaScanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, 0 /* Standard */, sourceText);
+ var referencedFiles = [];
+ var amdDependencies = [];
+ var amdModuleName;
+ // Keep scanning all the leading trivia in the file until we get to something that
+ // isn't trivia. Any single line comment will be analyzed to see if it is a
+ // reference comment.
+ while (true) {
+ var kind = triviaScanner.scan();
+ if (kind === 5 /* WhitespaceTrivia */ || kind === 4 /* NewLineTrivia */ || kind === 3 /* MultiLineCommentTrivia */) {
+ continue;
+ }
+ if (kind !== 2 /* SingleLineCommentTrivia */) {
+ break;
+ }
+ var range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
+ var comment = sourceText.substring(range.pos, range.end);
+ var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range);
+ if (referencePathMatchResult) {
+ var fileReference = referencePathMatchResult.fileReference;
+ sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
+ var diagnosticMessage = referencePathMatchResult.diagnosticMessage;
+ if (fileReference) {
+ referencedFiles.push(fileReference);
+ }
+ if (diagnosticMessage) {
+ parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage));
+ }
+ }
+ else {
+ var amdModuleNameRegEx = /^\/\/\/\s*".length;
+ return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
}
+ }
+ function parseQualifiedName(left) {
+ var result = createNode(135 /* QualifiedName */, left.pos);
+ result.left = left;
+ result.right = parseIdentifierName();
+ return finishNode(result);
+ }
+ function parseJSDocRecordType() {
+ var result = createNode(257 /* JSDocRecordType */);
nextToken();
+ result.members = parseDelimitedList(24 /* JSDocRecordMembers */, parseJSDocRecordMember);
+ checkForTrailingComma(result.members);
+ parseExpected(16 /* CloseBraceToken */);
+ return finishNode(result);
}
- if (token === 37 /* AsteriskToken */) {
- return true;
+ function parseJSDocRecordMember() {
+ var result = createNode(258 /* JSDocRecordMember */);
+ result.name = parseSimplePropertyName();
+ if (token === 54 /* ColonToken */) {
+ nextToken();
+ result.type = parseJSDocType();
+ }
+ return finishNode(result);
}
- // Try to get the first property-like token following all modifiers.
- // This can either be an identifier or the 'get' or 'set' keywords.
- if (isLiteralPropertyName()) {
- idToken = token;
+ function parseJSDocNonNullableType() {
+ var result = createNode(256 /* JSDocNonNullableType */);
nextToken();
+ result.type = parseJSDocType();
+ return finishNode(result);
}
- // Index signatures and computed properties are class members; we can parse.
- if (token === 19 /* OpenBracketToken */) {
- return true;
+ function parseJSDocTupleType() {
+ var result = createNode(254 /* JSDocTupleType */);
+ nextToken();
+ result.types = parseDelimitedList(25 /* JSDocTupleTypes */, parseJSDocType);
+ checkForTrailingComma(result.types);
+ parseExpected(20 /* CloseBracketToken */);
+ return finishNode(result);
}
- // If we were able to get any potential identifier...
- if (idToken !== undefined) {
- // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
- if (!ts.isKeyword(idToken) || idToken === 129 /* SetKeyword */ || idToken === 123 /* GetKeyword */) {
- return true;
- }
- // If it *is* a keyword, but not an accessor, check a little farther along
- // to see if it should actually be parsed as a class member.
- switch (token) {
- case 17 /* OpenParenToken */: // Method declaration
- case 25 /* LessThanToken */: // Generic Method declaration
- case 54 /* ColonToken */: // Type Annotation for declaration
- case 56 /* EqualsToken */: // Initializer for declaration
- case 53 /* QuestionToken */:
- return true;
- default:
- // Covers
- // - Semicolons (declaration termination)
- // - Closing braces (end-of-class, must be declaration)
- // - End-of-files (not valid, but permitted so that it gets caught later on)
- // - Line-breaks (enabling *automatic semicolon insertion*)
- return canParseSemicolon();
+ function checkForTrailingComma(list) {
+ if (parseDiagnostics.length === 0 && list.hasTrailingComma) {
+ var start = list.end - ",".length;
+ parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed);
}
}
- return false;
- }
- function parseDecorators() {
- var decorators;
- while (true) {
- var decoratorStart = getNodePos();
- if (!parseOptional(55 /* AtToken */)) {
- break;
- }
- if (!decorators) {
- decorators = [];
- decorators.pos = scanner.getStartPos();
+ function parseJSDocUnionType() {
+ var result = createNode(253 /* JSDocUnionType */);
+ nextToken();
+ result.types = parseJSDocTypeList(parseJSDocType());
+ parseExpected(18 /* CloseParenToken */);
+ return finishNode(result);
+ }
+ function parseJSDocTypeList(firstType) {
+ ts.Debug.assert(!!firstType);
+ var types = [];
+ types.pos = firstType.pos;
+ types.push(firstType);
+ while (parseOptional(47 /* BarToken */)) {
+ types.push(parseJSDocType());
}
- var decorator = createNode(139 /* Decorator */, decoratorStart);
- decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
- decorators.push(finishNode(decorator));
+ types.end = scanner.getStartPos();
+ return types;
}
- if (decorators) {
- decorators.end = getNodeEnd();
+ function parseJSDocAllType() {
+ var result = createNode(250 /* JSDocAllType */);
+ nextToken();
+ return finishNode(result);
}
- return decorators;
- }
- function parseModifiers() {
- var flags = 0;
- var modifiers;
- while (true) {
- var modifierStart = scanner.getStartPos();
- var modifierKind = token;
- if (!parseAnyContextualModifier()) {
- break;
+ function parseJSDocUnknownOrNullableType() {
+ var pos = scanner.getStartPos();
+ // skip the ?
+ nextToken();
+ // Need to lookahead to decide if this is a nullable or unknown type.
+ // Here are cases where we'll pick the unknown type:
+ //
+ // Foo(?,
+ // { a: ? }
+ // Foo(?)
+ // Foo>
+ // Foo(?=
+ // (?|
+ if (token === 24 /* CommaToken */ ||
+ token === 16 /* CloseBraceToken */ ||
+ token === 18 /* CloseParenToken */ ||
+ token === 27 /* GreaterThanToken */ ||
+ token === 56 /* EqualsToken */ ||
+ token === 47 /* BarToken */) {
+ var result = createNode(251 /* JSDocUnknownType */, pos);
+ return finishNode(result);
}
- if (!modifiers) {
- modifiers = [];
- modifiers.pos = modifierStart;
+ else {
+ var result = createNode(255 /* JSDocNullableType */, pos);
+ result.type = parseJSDocType();
+ return finishNode(result);
}
- flags |= ts.modifierToFlag(modifierKind);
- modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
}
- if (modifiers) {
- modifiers.flags = flags;
- modifiers.end = scanner.getStartPos();
+ function parseIsolatedJSDocComment(content, start, length) {
+ initializeState("file.js", content, 2 /* Latest */, /*isJavaScriptFile*/ true, /*_syntaxCursor:*/ undefined);
+ var jsDocComment = parseJSDocComment(/*parent:*/ undefined, start, length);
+ var diagnostics = parseDiagnostics;
+ clearState();
+ return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined;
}
- return modifiers;
- }
- function parseModifiersForArrowFunction() {
- var flags = 0;
- var modifiers;
- if (token === 118 /* AsyncKeyword */) {
- var modifierStart = scanner.getStartPos();
- var modifierKind = token;
- nextToken();
- modifiers = [];
- modifiers.pos = modifierStart;
- flags |= ts.modifierToFlag(modifierKind);
- modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
- modifiers.flags = flags;
- modifiers.end = scanner.getStartPos();
+ JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
+ function parseJSDocComment(parent, start, length) {
+ var comment = parseJSDocCommentWorker(start, length);
+ if (comment) {
+ fixupParentReferences(comment);
+ comment.parent = parent;
+ }
+ return comment;
}
- return modifiers;
- }
- function parseClassElement() {
- if (token === 23 /* SemicolonToken */) {
- var result = createNode(191 /* SemicolonClassElement */);
- nextToken();
- return finishNode(result);
+ JSDocParser.parseJSDocComment = parseJSDocComment;
+ function parseJSDocCommentWorker(start, length) {
+ var content = sourceText;
+ start = start || 0;
+ var end = length === undefined ? content.length : start + length;
+ length = end - start;
+ ts.Debug.assert(start >= 0);
+ ts.Debug.assert(start <= end);
+ ts.Debug.assert(end <= content.length);
+ var tags;
+ var pos;
+ // NOTE(cyrusn): This is essentially a handwritten scanner for JSDocComments. I
+ // considered using an actual Scanner, but this would complicate things. The
+ // scanner would need to know it was in a Doc Comment. Otherwise, it would then
+ // produce comments *inside* the doc comment. In the end it was just easier to
+ // write a simple scanner rather than go that route.
+ if (length >= "/** */".length) {
+ if (content.charCodeAt(start) === 47 /* slash */ &&
+ content.charCodeAt(start + 1) === 42 /* asterisk */ &&
+ content.charCodeAt(start + 2) === 42 /* asterisk */ &&
+ content.charCodeAt(start + 3) !== 42 /* asterisk */) {
+ // Initially we can parse out a tag. We also have seen a starting asterisk.
+ // This is so that /** * @type */ doesn't parse.
+ var canParseTag = true;
+ var seenAsterisk = true;
+ for (pos = start + "/**".length; pos < end;) {
+ var ch = content.charCodeAt(pos);
+ pos++;
+ if (ch === 64 /* at */ && canParseTag) {
+ parseTag();
+ // Once we parse out a tag, we cannot keep parsing out tags on this line.
+ canParseTag = false;
+ continue;
+ }
+ if (ts.isLineBreak(ch)) {
+ // After a line break, we can parse a tag, and we haven't seen as asterisk
+ // on the next line yet.
+ canParseTag = true;
+ seenAsterisk = false;
+ continue;
+ }
+ if (ts.isWhiteSpace(ch)) {
+ // Whitespace doesn't affect any of our parsing.
+ continue;
+ }
+ // Ignore the first asterisk on a line.
+ if (ch === 42 /* asterisk */) {
+ if (seenAsterisk) {
+ // If we've already seen an asterisk, then we can no longer parse a tag
+ // on this line.
+ canParseTag = false;
+ }
+ seenAsterisk = true;
+ continue;
+ }
+ // Anything else is doc comment text. We can't do anything with it. Because it
+ // wasn't a tag, we can no longer parse a tag on this line until we hit the next
+ // line break.
+ canParseTag = false;
+ }
+ }
+ }
+ return createJSDocComment();
+ function createJSDocComment() {
+ if (!tags) {
+ return undefined;
+ }
+ var result = createNode(265 /* JSDocComment */, start);
+ result.tags = tags;
+ return finishNode(result, end);
+ }
+ function skipWhitespace() {
+ while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) {
+ pos++;
+ }
+ }
+ function parseTag() {
+ ts.Debug.assert(content.charCodeAt(pos - 1) === 64 /* at */);
+ var atToken = createNode(55 /* AtToken */, pos - 1);
+ atToken.end = pos;
+ var tagName = scanIdentifier();
+ if (!tagName) {
+ return;
+ }
+ var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName);
+ addTag(tag);
+ }
+ function handleTag(atToken, tagName) {
+ if (tagName) {
+ switch (tagName.text) {
+ case "param":
+ return handleParamTag(atToken, tagName);
+ case "return":
+ case "returns":
+ return handleReturnTag(atToken, tagName);
+ case "template":
+ return handleTemplateTag(atToken, tagName);
+ case "type":
+ return handleTypeTag(atToken, tagName);
+ }
+ }
+ return undefined;
+ }
+ function handleUnknownTag(atToken, tagName) {
+ var result = createNode(266 /* JSDocTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ return finishNode(result, pos);
+ }
+ function addTag(tag) {
+ if (tag) {
+ if (!tags) {
+ tags = [];
+ tags.pos = tag.pos;
+ }
+ tags.push(tag);
+ tags.end = tag.end;
+ }
+ }
+ function tryParseTypeExpression() {
+ skipWhitespace();
+ if (content.charCodeAt(pos) !== 123 /* openBrace */) {
+ return undefined;
+ }
+ var typeExpression = parseJSDocTypeExpression(pos, end - pos);
+ pos = typeExpression.end;
+ return typeExpression;
+ }
+ function handleParamTag(atToken, tagName) {
+ var typeExpression = tryParseTypeExpression();
+ skipWhitespace();
+ var name;
+ var isBracketed;
+ if (content.charCodeAt(pos) === 91 /* openBracket */) {
+ pos++;
+ skipWhitespace();
+ name = scanIdentifier();
+ isBracketed = true;
+ }
+ else {
+ name = scanIdentifier();
+ }
+ if (!name) {
+ parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected);
+ }
+ var preName, postName;
+ if (typeExpression) {
+ postName = name;
+ }
+ else {
+ preName = name;
+ }
+ if (!typeExpression) {
+ typeExpression = tryParseTypeExpression();
+ }
+ var result = createNode(267 /* JSDocParameterTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.preParameterName = preName;
+ result.typeExpression = typeExpression;
+ result.postParameterName = postName;
+ result.isBracketed = isBracketed;
+ return finishNode(result, pos);
+ }
+ function handleReturnTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 268 /* JSDocReturnTag */; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var result = createNode(268 /* JSDocReturnTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeExpression = tryParseTypeExpression();
+ return finishNode(result, pos);
+ }
+ function handleTypeTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 269 /* JSDocTypeTag */; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var result = createNode(269 /* JSDocTypeTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeExpression = tryParseTypeExpression();
+ return finishNode(result, pos);
+ }
+ function handleTemplateTag(atToken, tagName) {
+ if (ts.forEach(tags, function (t) { return t.kind === 270 /* JSDocTemplateTag */; })) {
+ parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ var typeParameters = [];
+ typeParameters.pos = pos;
+ while (true) {
+ skipWhitespace();
+ var startPos = pos;
+ var name_8 = scanIdentifier();
+ if (!name_8) {
+ parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected);
+ return undefined;
+ }
+ var typeParameter = createNode(137 /* TypeParameter */, name_8.pos);
+ typeParameter.name = name_8;
+ finishNode(typeParameter, pos);
+ typeParameters.push(typeParameter);
+ skipWhitespace();
+ if (content.charCodeAt(pos) !== 44 /* comma */) {
+ break;
+ }
+ pos++;
+ }
+ typeParameters.end = pos;
+ var result = createNode(270 /* JSDocTemplateTag */, atToken.pos);
+ result.atToken = atToken;
+ result.tagName = tagName;
+ result.typeParameters = typeParameters;
+ return finishNode(result, pos);
+ }
+ function scanIdentifier() {
+ var startPos = pos;
+ for (; pos < end; pos++) {
+ var ch = content.charCodeAt(pos);
+ if (pos === startPos && ts.isIdentifierStart(ch, 2 /* Latest */)) {
+ continue;
+ }
+ else if (pos > startPos && ts.isIdentifierPart(ch, 2 /* Latest */)) {
+ continue;
+ }
+ break;
+ }
+ if (startPos === pos) {
+ return undefined;
+ }
+ var result = createNode(69 /* Identifier */, startPos);
+ result.text = content.substring(startPos, pos);
+ return finishNode(result, pos);
+ }
}
- var fullStart = getNodePos();
- var decorators = parseDecorators();
- var modifiers = parseModifiers();
- var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
- if (accessor) {
- return accessor;
+ JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
+ })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
+ })(Parser || (Parser = {}));
+ var IncrementalParser;
+ (function (IncrementalParser) {
+ function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
+ aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
+ checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
+ if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
+ // if the text didn't change, then we can just return our current source file as-is.
+ return sourceFile;
}
- if (token === 121 /* ConstructorKeyword */) {
- return parseConstructorDeclaration(fullStart, decorators, modifiers);
+ if (sourceFile.statements.length === 0) {
+ // If we don't have any statements in the current source file, then there's no real
+ // way to incrementally parse. So just do a full parse instead.
+ return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setNodeParents*/ true);
+ }
+ // Make sure we're not trying to incrementally update a source file more than once. Once
+ // we do an update the original source file is considered unusbale from that point onwards.
+ //
+ // This is because we do incremental parsing in-place. i.e. we take nodes from the old
+ // tree and give them new positions and parents. From that point on, trusting the old
+ // tree at all is not possible as far too much of it may violate invariants.
+ var incrementalSourceFile = sourceFile;
+ ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
+ incrementalSourceFile.hasBeenIncrementallyParsed = true;
+ var oldText = sourceFile.text;
+ var syntaxCursor = createSyntaxCursor(sourceFile);
+ // Make the actual change larger so that we know to reparse anything whose lookahead
+ // might have intersected the change.
+ var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
+ checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
+ // Ensure that extending the affected range only moved the start of the change range
+ // earlier in the file.
+ ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
+ ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
+ ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
+ // The is the amount the nodes after the edit range need to be adjusted. It can be
+ // positive (if the edit added characters), negative (if the edit deleted characters)
+ // or zero (if this was a pure overwrite with nothing added/removed).
+ var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
+ // If we added or removed characters during the edit, then we need to go and adjust all
+ // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they
+ // may move backward (if we deleted chars).
+ //
+ // Doing this helps us out in two ways. First, it means that any nodes/tokens we want
+ // to reuse are already at the appropriate position in the new text. That way when we
+ // reuse them, we don't have to figure out if they need to be adjusted. Second, it makes
+ // it very easy to determine if we can reuse a node. If the node's position is at where
+ // we are in the text, then we can reuse it. Otherwise we can't. If the node's position
+ // is ahead of us, then we'll need to rescan tokens. If the node's position is behind
+ // us, then we'll need to skip it or crumble it as appropriate
+ //
+ // We will also adjust the positions of nodes that intersect the change range as well.
+ // By doing this, we ensure that all the positions in the old tree are consistent, not
+ // just the positions of nodes entirely before/after the change range. By being
+ // consistent, we can then easily map from positions to nodes in the old tree easily.
+ //
+ // Also, mark any syntax elements that intersect the changed span. We know, up front,
+ // that we cannot reuse these elements.
+ updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
+ // Now that we've set up our internal incremental state just proceed and parse the
+ // source file in the normal fashion. When possible the parser will retrieve and
+ // reuse nodes from the old tree.
+ //
+ // Note: passing in 'true' for setNodeParents is very important. When incrementally
+ // parsing, we will be reusing nodes from the old tree, and placing it into new
+ // parents. If we don't set the parents now, we'll end up with an observably
+ // inconsistent tree. Setting the parents on the new tree should be very fast. We
+ // will immediately bail out of walking any subtrees when we can see that their parents
+ // are already correct.
+ var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /* setParentNode */ true);
+ return result;
+ }
+ IncrementalParser.updateSourceFile = updateSourceFile;
+ function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
+ if (isArray) {
+ visitArray(element);
}
- if (isIndexSignature()) {
- return parseIndexSignatureDeclaration(fullStart, decorators, modifiers);
+ else {
+ visitNode(element);
}
- // It is very important that we check this *after* checking indexers because
- // the [ token can start an index signature or a computed property name
- if (ts.tokenIsIdentifierOrKeyword(token) ||
- token === 9 /* StringLiteral */ ||
- token === 8 /* NumericLiteral */ ||
- token === 37 /* AsteriskToken */ ||
- token === 19 /* OpenBracketToken */) {
- return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
+ return;
+ function visitNode(node) {
+ var text = "";
+ if (aggressiveChecks && shouldCheckNode(node)) {
+ text = oldText.substring(node.pos, node.end);
+ }
+ // Ditch any existing LS children we may have created. This way we can avoid
+ // moving them forward.
+ if (node._children) {
+ node._children = undefined;
+ }
+ if (node.jsDocComment) {
+ node.jsDocComment = undefined;
+ }
+ node.pos += delta;
+ node.end += delta;
+ if (aggressiveChecks && shouldCheckNode(node)) {
+ ts.Debug.assert(text === newText.substring(node.pos, node.end));
+ }
+ forEachChild(node, visitNode, visitArray);
+ checkNodePositions(node, aggressiveChecks);
}
- if (decorators || modifiers) {
- // treat this as a property declaration with a missing name.
- var name_7 = createMissingNode(69 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
- return parsePropertyDeclaration(fullStart, decorators, modifiers, name_7, /*questionToken*/ undefined);
+ function visitArray(array) {
+ array._children = undefined;
+ array.pos += delta;
+ array.end += delta;
+ for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
+ var node = array_7[_i];
+ visitNode(node);
+ }
}
- // 'isClassMemberStart' should have hinted not to attempt parsing.
- ts.Debug.fail("Should not have attempted to parse class member declaration.");
- }
- function parseClassExpression() {
- return parseClassDeclarationOrExpression(
- /*fullStart*/ scanner.getStartPos(),
- /*decorators*/ undefined,
- /*modifiers*/ undefined, 186 /* ClassExpression */);
}
- function parseClassDeclaration(fullStart, decorators, modifiers) {
- return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 214 /* ClassDeclaration */);
+ function shouldCheckNode(node) {
+ switch (node.kind) {
+ case 9 /* StringLiteral */:
+ case 8 /* NumericLiteral */:
+ case 69 /* Identifier */:
+ return true;
+ }
+ return false;
}
- function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
- var node = createNode(kind, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(73 /* ClassKeyword */);
- node.name = parseNameOfClassDeclarationOrExpression();
- node.typeParameters = parseTypeParameters();
- node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
- if (parseExpected(15 /* OpenBraceToken */)) {
- // ClassTail[Yield,Await] : (Modified) See 14.5
- // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
- node.members = parseClassMembers();
- parseExpected(16 /* CloseBraceToken */);
+ function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
+ ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
+ ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
+ ts.Debug.assert(element.pos <= element.end);
+ // We have an element that intersects the change range in some way. It may have its
+ // start, or its end (or both) in the changed range. We want to adjust any part
+ // that intersects such that the final tree is in a consistent state. i.e. all
+ // chlidren have spans within the span of their parent, and all siblings are ordered
+ // properly.
+ // We may need to update both the 'pos' and the 'end' of the element.
+ // If the 'pos' is before the start of the change, then we don't need to touch it.
+ // If it isn't, then the 'pos' must be inside the change. How we update it will
+ // depend if delta is positive or negative. If delta is positive then we have
+ // something like:
+ //
+ // -------------------AAA-----------------
+ // -------------------BBBCCCCCCC-----------------
+ //
+ // In this case, we consider any node that started in the change range to still be
+ // starting at the same position.
+ //
+ // however, if the delta is negative, then we instead have something like this:
+ //
+ // -------------------XXXYYYYYYY-----------------
+ // -------------------ZZZ-----------------
+ //
+ // In this case, any element that started in the 'X' range will keep its position.
+ // However any element htat started after that will have their pos adjusted to be
+ // at the end of the new range. i.e. any node that started in the 'Y' range will
+ // be adjusted to have their start at the end of the 'Z' range.
+ //
+ // The element will keep its position if possible. Or Move backward to the new-end
+ // if it's in the 'Y' range.
+ element.pos = Math.min(element.pos, changeRangeNewEnd);
+ // If the 'end' is after the change range, then we always adjust it by the delta
+ // amount. However, if the end is in the change range, then how we adjust it
+ // will depend on if delta is positive or negative. If delta is positive then we
+ // have something like:
+ //
+ // -------------------AAA-----------------
+ // -------------------BBBCCCCCCC-----------------
+ //
+ // In this case, we consider any node that ended inside the change range to keep its
+ // end position.
+ //
+ // however, if the delta is negative, then we instead have something like this:
+ //
+ // -------------------XXXYYYYYYY-----------------
+ // -------------------ZZZ-----------------
+ //
+ // In this case, any element that ended in the 'X' range will keep its position.
+ // However any element htat ended after that will have their pos adjusted to be
+ // at the end of the new range. i.e. any node that ended in the 'Y' range will
+ // be adjusted to have their end at the end of the 'Z' range.
+ if (element.end >= changeRangeOldEnd) {
+ // Element ends after the change range. Always adjust the end pos.
+ element.end += delta;
}
else {
- node.members = createMissingList();
+ // Element ends in the change range. The element will keep its position if
+ // possible. Or Move backward to the new-end if it's in the 'Y' range.
+ element.end = Math.min(element.end, changeRangeNewEnd);
}
- return finishNode(node);
- }
- function parseNameOfClassDeclarationOrExpression() {
- // implements is a future reserved word so
- // 'class implements' might mean either
- // - class expression with omitted name, 'implements' starts heritage clause
- // - class with name 'implements'
- // 'isImplementsClause' helps to disambiguate between these two cases
- return isIdentifier() && !isImplementsClause()
- ? parseIdentifier()
- : undefined;
- }
- function isImplementsClause() {
- return token === 106 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
- }
- function parseHeritageClauses(isClassHeritageClause) {
- // ClassTail[Yield,Await] : (Modified) See 14.5
- // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
- if (isHeritageClause()) {
- return parseList(20 /* HeritageClauses */, parseHeritageClause);
+ ts.Debug.assert(element.pos <= element.end);
+ if (element.parent) {
+ ts.Debug.assert(element.pos >= element.parent.pos);
+ ts.Debug.assert(element.end <= element.parent.end);
}
- return undefined;
- }
- function parseHeritageClausesWorker() {
- return parseList(20 /* HeritageClauses */, parseHeritageClause);
}
- function parseHeritageClause() {
- if (token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */) {
- var node = createNode(243 /* HeritageClause */);
- node.token = token;
- nextToken();
- node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
- return finishNode(node);
+ function checkNodePositions(node, aggressiveChecks) {
+ if (aggressiveChecks) {
+ var pos = node.pos;
+ forEachChild(node, function (child) {
+ ts.Debug.assert(child.pos >= pos);
+ pos = child.end;
+ });
+ ts.Debug.assert(pos <= node.end);
}
- return undefined;
}
- function parseExpressionWithTypeArguments() {
- var node = createNode(188 /* ExpressionWithTypeArguments */);
- node.expression = parseLeftHandSideExpressionOrHigher();
- if (token === 25 /* LessThanToken */) {
- node.typeArguments = parseBracketedList(18 /* TypeArguments */, parseType, 25 /* LessThanToken */, 27 /* GreaterThanToken */);
+ function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
+ visitNode(sourceFile);
+ return;
+ function visitNode(child) {
+ ts.Debug.assert(child.pos <= child.end);
+ if (child.pos > changeRangeOldEnd) {
+ // Node is entirely past the change range. We need to move both its pos and
+ // end, forward or backward appropriately.
+ moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
+ return;
+ }
+ // Check if the element intersects the change range. If it does, then it is not
+ // reusable. Also, we'll need to recurse to see what constituent portions we may
+ // be able to use.
+ var fullEnd = child.end;
+ if (fullEnd >= changeStart) {
+ child.intersectsChange = true;
+ child._children = undefined;
+ // Adjust the pos or end (or both) of the intersecting element accordingly.
+ adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
+ forEachChild(child, visitNode, visitArray);
+ checkNodePositions(child, aggressiveChecks);
+ return;
+ }
+ // Otherwise, the node is entirely before the change range. No need to do anything with it.
+ ts.Debug.assert(fullEnd < changeStart);
+ }
+ function visitArray(array) {
+ ts.Debug.assert(array.pos <= array.end);
+ if (array.pos > changeRangeOldEnd) {
+ // Array is entirely after the change range. We need to move it, and move any of
+ // its children.
+ moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
+ return;
+ }
+ // Check if the element intersects the change range. If it does, then it is not
+ // reusable. Also, we'll need to recurse to see what constituent portions we may
+ // be able to use.
+ var fullEnd = array.end;
+ if (fullEnd >= changeStart) {
+ array.intersectsChange = true;
+ array._children = undefined;
+ // Adjust the pos or end (or both) of the intersecting array accordingly.
+ adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
+ for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
+ var node = array_8[_i];
+ visitNode(node);
+ }
+ return;
+ }
+ // Otherwise, the array is entirely before the change range. No need to do anything with it.
+ ts.Debug.assert(fullEnd < changeStart);
}
- return finishNode(node);
- }
- function isHeritageClause() {
- return token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
- }
- function parseClassMembers() {
- return parseList(5 /* ClassMembers */, parseClassElement);
- }
- function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(215 /* InterfaceDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(107 /* InterfaceKeyword */);
- node.name = parseIdentifier();
- node.typeParameters = parseTypeParameters();
- node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false);
- node.members = parseObjectTypeMembers();
- return finishNode(node);
- }
- function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(216 /* TypeAliasDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(132 /* TypeKeyword */);
- node.name = parseIdentifier();
- node.typeParameters = parseTypeParameters();
- parseExpected(56 /* EqualsToken */);
- node.type = parseType();
- parseSemicolon();
- return finishNode(node);
}
- // In an ambient declaration, the grammar only allows integer literals as initializers.
- // In a non-ambient declaration, the grammar allows uninitialized members only in a
- // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
- // or any time an integer literal initializer is encountered.
- function parseEnumMember() {
- var node = createNode(247 /* EnumMember */, scanner.getStartPos());
- node.name = parsePropertyName();
- node.initializer = allowInAnd(parseNonParameterInitializer);
- return finishNode(node);
+ function extendToAffectedRange(sourceFile, changeRange) {
+ // Consider the following code:
+ // void foo() { /; }
+ //
+ // If the text changes with an insertion of / just before the semicolon then we end up with:
+ // void foo() { //; }
+ //
+ // If we were to just use the changeRange a is, then we would not rescan the { token
+ // (as it does not intersect the actual original change range). Because an edit may
+ // change the token touching it, we actually need to look back *at least* one token so
+ // that the prior token sees that change.
+ var maxLookahead = 1;
+ var start = changeRange.span.start;
+ // the first iteration aligns us with the change start. subsequent iteration move us to
+ // the left by maxLookahead tokens. We only need to do this as long as we're not at the
+ // start of the tree.
+ for (var i = 0; start > 0 && i <= maxLookahead; i++) {
+ var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
+ ts.Debug.assert(nearestNode.pos <= start);
+ var position = nearestNode.pos;
+ start = Math.max(0, position - 1);
+ }
+ var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
+ var finalLength = changeRange.newLength + (changeRange.span.start - start);
+ return ts.createTextChangeRange(finalSpan, finalLength);
}
- function parseEnumDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(217 /* EnumDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- parseExpected(81 /* EnumKeyword */);
- node.name = parseIdentifier();
- if (parseExpected(15 /* OpenBraceToken */)) {
- node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember);
- parseExpected(16 /* CloseBraceToken */);
+ function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
+ var bestResult = sourceFile;
+ var lastNodeEntirelyBeforePosition;
+ forEachChild(sourceFile, visit);
+ if (lastNodeEntirelyBeforePosition) {
+ var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition);
+ if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
+ bestResult = lastChildOfLastEntireNodeBeforePosition;
+ }
}
- else {
- node.members = createMissingList();
+ return bestResult;
+ function getLastChild(node) {
+ while (true) {
+ var lastChild = getLastChildWorker(node);
+ if (lastChild) {
+ node = lastChild;
+ }
+ else {
+ return node;
+ }
+ }
}
- return finishNode(node);
- }
- function parseModuleBlock() {
- var node = createNode(219 /* ModuleBlock */, scanner.getStartPos());
- if (parseExpected(15 /* OpenBraceToken */)) {
- node.statements = parseList(1 /* BlockStatements */, parseStatement);
- parseExpected(16 /* CloseBraceToken */);
+ function getLastChildWorker(node) {
+ var last = undefined;
+ forEachChild(node, function (child) {
+ if (ts.nodeIsPresent(child)) {
+ last = child;
+ }
+ });
+ return last;
}
- else {
- node.statements = createMissingList();
+ function visit(child) {
+ if (ts.nodeIsMissing(child)) {
+ // Missing nodes are effectively invisible to us. We never even consider them
+ // When trying to find the nearest node before us.
+ return;
+ }
+ // If the child intersects this position, then this node is currently the nearest
+ // node that starts before the position.
+ if (child.pos <= position) {
+ if (child.pos >= bestResult.pos) {
+ // This node starts before the position, and is closer to the position than
+ // the previous best node we found. It is now the new best node.
+ bestResult = child;
+ }
+ // Now, the node may overlap the position, or it may end entirely before the
+ // position. If it overlaps with the position, then either it, or one of its
+ // children must be the nearest node before the position. So we can just
+ // recurse into this child to see if we can find something better.
+ if (position < child.end) {
+ // The nearest node is either this child, or one of the children inside
+ // of it. We've already marked this child as the best so far. Recurse
+ // in case one of the children is better.
+ forEachChild(child, visit);
+ // Once we look at the children of this node, then there's no need to
+ // continue any further.
+ return true;
+ }
+ else {
+ ts.Debug.assert(child.end <= position);
+ // The child ends entirely before this position. Say you have the following
+ // (where $ is the position)
+ //
+ // ? $ : <...> <...>
+ //
+ // We would want to find the nearest preceding node in "complex expr 2".
+ // To support that, we keep track of this node, and once we're done searching
+ // for a best node, we recurse down this node to see if we can find a good
+ // result in it.
+ //
+ // This approach allows us to quickly skip over nodes that are entirely
+ // before the position, while still allowing us to find any nodes in the
+ // last one that might be what we want.
+ lastNodeEntirelyBeforePosition = child;
+ }
+ }
+ else {
+ ts.Debug.assert(child.pos > position);
+ // We're now at a node that is entirely past the position we're searching for.
+ // This node (and all following nodes) could never contribute to the result,
+ // so just skip them by returning 'true' here.
+ return true;
+ }
}
- return finishNode(node);
- }
- function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
- var node = createNode(218 /* ModuleDeclaration */, fullStart);
- // If we are parsing a dotted namespace name, we want to
- // propagate the 'Namespace' flag across the names if set.
- var namespaceFlag = flags & 65536 /* Namespace */;
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.flags |= flags;
- node.name = parseIdentifier();
- node.body = parseOptional(21 /* DotToken */)
- ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, 2 /* Export */ | namespaceFlag)
- : parseModuleBlock();
- return finishNode(node);
- }
- function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(218 /* ModuleDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- node.name = parseLiteralNode(/*internName*/ true);
- node.body = parseModuleBlock();
- return finishNode(node);
}
- function parseModuleDeclaration(fullStart, decorators, modifiers) {
- var flags = modifiers ? modifiers.flags : 0;
- if (parseOptional(126 /* NamespaceKeyword */)) {
- flags |= 65536 /* Namespace */;
+ function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
+ var oldText = sourceFile.text;
+ if (textChangeRange) {
+ ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
+ if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
+ var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
+ var newTextPrefix = newText.substr(0, textChangeRange.span.start);
+ ts.Debug.assert(oldTextPrefix === newTextPrefix);
+ var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
+ var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
+ ts.Debug.assert(oldTextSuffix === newTextSuffix);
+ }
}
- else {
- parseExpected(125 /* ModuleKeyword */);
- if (token === 9 /* StringLiteral */) {
- return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
+ }
+ function createSyntaxCursor(sourceFile) {
+ var currentArray = sourceFile.statements;
+ var currentArrayIndex = 0;
+ ts.Debug.assert(currentArrayIndex < currentArray.length);
+ var current = currentArray[currentArrayIndex];
+ var lastQueriedPosition = -1 /* Value */;
+ return {
+ currentNode: function (position) {
+ // Only compute the current node if the position is different than the last time
+ // we were asked. The parser commonly asks for the node at the same position
+ // twice. Once to know if can read an appropriate list element at a certain point,
+ // and then to actually read and consume the node.
+ if (position !== lastQueriedPosition) {
+ // Much of the time the parser will need the very next node in the array that
+ // we just returned a node from.So just simply check for that case and move
+ // forward in the array instead of searching for the node again.
+ if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
+ currentArrayIndex++;
+ current = currentArray[currentArrayIndex];
+ }
+ // If we don't have a node, or the node we have isn't in the right position,
+ // then try to find a viable node at the position requested.
+ if (!current || current.pos !== position) {
+ findHighestListElementThatStartsAtPosition(position);
+ }
+ }
+ // Cache this query so that we don't do any extra work if the parser calls back
+ // into us. Note: this is very common as the parser will make pairs of calls like
+ // 'isListElement -> parseListElement'. If we were unable to find a node when
+ // called with 'isListElement', we don't want to redo the work when parseListElement
+ // is called immediately after.
+ lastQueriedPosition = position;
+ // Either we don'd have a node, or we have a node at the position being asked for.
+ ts.Debug.assert(!current || current.pos === position);
+ return current;
+ }
+ };
+ // Finds the highest element in the tree we can find that starts at the provided position.
+ // The element must be a direct child of some node list in the tree. This way after we
+ // return it, we can easily return its next sibling in the list.
+ function findHighestListElementThatStartsAtPosition(position) {
+ // Clear out any cached state about the last node we found.
+ currentArray = undefined;
+ currentArrayIndex = -1 /* Value */;
+ current = undefined;
+ // Recurse into the source file to find the highest node at this position.
+ forEachChild(sourceFile, visitNode, visitArray);
+ return;
+ function visitNode(node) {
+ if (position >= node.pos && position < node.end) {
+ // Position was within this node. Keep searching deeper to find the node.
+ forEachChild(node, visitNode, visitArray);
+ // don't procede any futher in the search.
+ return true;
+ }
+ // position wasn't in this node, have to keep searching.
+ return false;
+ }
+ function visitArray(array) {
+ if (position >= array.pos && position < array.end) {
+ // position was in this array. Search through this array to see if we find a
+ // viable element.
+ for (var i = 0, n = array.length; i < n; i++) {
+ var child = array[i];
+ if (child) {
+ if (child.pos === position) {
+ // Found the right node. We're done.
+ currentArray = array;
+ currentArrayIndex = i;
+ current = child;
+ return true;
+ }
+ else {
+ if (child.pos < position && position < child.end) {
+ // Position in somewhere within this child. Search in it and
+ // stop searching in this array.
+ forEachChild(child, visitNode, visitArray);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ // position wasn't in this array, have to keep searching.
+ return false;
}
}
- return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
- }
- function isExternalModuleReference() {
- return token === 127 /* RequireKeyword */ &&
- lookAhead(nextTokenIsOpenParen);
}
- function nextTokenIsOpenParen() {
- return nextToken() === 17 /* OpenParenToken */;
+ var InvalidPosition;
+ (function (InvalidPosition) {
+ InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
+ })(InvalidPosition || (InvalidPosition = {}));
+ })(IncrementalParser || (IncrementalParser = {}));
+})(ts || (ts = {}));
+///
+///
+/* @internal */
+var ts;
+(function (ts) {
+ ts.bindTime = 0;
+ (function (ModuleInstanceState) {
+ ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
+ ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
+ ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
+ })(ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
+ var ModuleInstanceState = ts.ModuleInstanceState;
+ var Reachability;
+ (function (Reachability) {
+ Reachability[Reachability["Unintialized"] = 1] = "Unintialized";
+ Reachability[Reachability["Reachable"] = 2] = "Reachable";
+ Reachability[Reachability["Unreachable"] = 4] = "Unreachable";
+ Reachability[Reachability["ReportedUnreachable"] = 8] = "ReportedUnreachable";
+ })(Reachability || (Reachability = {}));
+ function or(state1, state2) {
+ return (state1 | state2) & 2 /* Reachable */
+ ? 2 /* Reachable */
+ : (state1 & state2) & 8 /* ReportedUnreachable */
+ ? 8 /* ReportedUnreachable */
+ : 4 /* Unreachable */;
+ }
+ function getModuleInstanceState(node) {
+ // A module is uninstantiated if it contains only
+ // 1. interface declarations, type alias declarations
+ if (node.kind === 215 /* InterfaceDeclaration */ || node.kind === 216 /* TypeAliasDeclaration */) {
+ return 0 /* NonInstantiated */;
}
- function nextTokenIsSlash() {
- return nextToken() === 39 /* SlashToken */;
+ else if (ts.isConstEnumDeclaration(node)) {
+ return 2 /* ConstEnumOnly */;
}
- function nextTokenIsCommaOrFromKeyword() {
- nextToken();
- return token === 24 /* CommaToken */ ||
- token === 133 /* FromKeyword */;
+ else if ((node.kind === 222 /* ImportDeclaration */ || node.kind === 221 /* ImportEqualsDeclaration */) && !(node.flags & 2 /* Export */)) {
+ return 0 /* NonInstantiated */;
}
- function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
- parseExpected(89 /* ImportKeyword */);
- var afterImportPos = scanner.getStartPos();
- var identifier;
- if (isIdentifier()) {
- identifier = parseIdentifier();
- if (token !== 24 /* CommaToken */ && token !== 133 /* FromKeyword */) {
- // ImportEquals declaration of type:
- // import x = require("mod"); or
- // import x = M.x;
- var importEqualsDeclaration = createNode(221 /* ImportEqualsDeclaration */, fullStart);
- importEqualsDeclaration.decorators = decorators;
- setModifiers(importEqualsDeclaration, modifiers);
- importEqualsDeclaration.name = identifier;
- parseExpected(56 /* EqualsToken */);
- importEqualsDeclaration.moduleReference = parseModuleReference();
- parseSemicolon();
- return finishNode(importEqualsDeclaration);
+ else if (node.kind === 219 /* ModuleBlock */) {
+ var state = 0 /* NonInstantiated */;
+ ts.forEachChild(node, function (n) {
+ switch (getModuleInstanceState(n)) {
+ case 0 /* NonInstantiated */:
+ // child is non-instantiated - continue searching
+ return false;
+ case 2 /* ConstEnumOnly */:
+ // child is const enum only - record state and continue searching
+ state = 2 /* ConstEnumOnly */;
+ return false;
+ case 1 /* Instantiated */:
+ // child is instantiated - record state and stop
+ state = 1 /* Instantiated */;
+ return true;
}
- }
- // Import statement
- var importDeclaration = createNode(222 /* ImportDeclaration */, fullStart);
- importDeclaration.decorators = decorators;
- setModifiers(importDeclaration, modifiers);
- // ImportDeclaration:
- // import ImportClause from ModuleSpecifier ;
- // import ModuleSpecifier;
- if (identifier ||
- token === 37 /* AsteriskToken */ ||
- token === 15 /* OpenBraceToken */) {
- importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
- parseExpected(133 /* FromKeyword */);
- }
- importDeclaration.moduleSpecifier = parseModuleSpecifier();
- parseSemicolon();
- return finishNode(importDeclaration);
- }
- function parseImportClause(identifier, fullStart) {
- // ImportClause:
- // ImportedDefaultBinding
- // NameSpaceImport
- // NamedImports
- // ImportedDefaultBinding, NameSpaceImport
- // ImportedDefaultBinding, NamedImports
- var importClause = createNode(223 /* ImportClause */, fullStart);
- if (identifier) {
- // ImportedDefaultBinding:
- // ImportedBinding
- importClause.name = identifier;
- }
- // If there was no default import or if there is comma token after default import
- // parse namespace or named imports
- if (!importClause.name ||
- parseOptional(24 /* CommaToken */)) {
- importClause.namedBindings = token === 37 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(225 /* NamedImports */);
- }
- return finishNode(importClause);
+ });
+ return state;
}
- function parseModuleReference() {
- return isExternalModuleReference()
- ? parseExternalModuleReference()
- : parseEntityName(/*allowReservedWords*/ false);
+ else if (node.kind === 218 /* ModuleDeclaration */) {
+ return getModuleInstanceState(node.body);
}
- function parseExternalModuleReference() {
- var node = createNode(232 /* ExternalModuleReference */);
- parseExpected(127 /* RequireKeyword */);
- parseExpected(17 /* OpenParenToken */);
- node.expression = parseModuleSpecifier();
- parseExpected(18 /* CloseParenToken */);
- return finishNode(node);
+ else {
+ return 1 /* Instantiated */;
}
- function parseModuleSpecifier() {
- // We allow arbitrary expressions here, even though the grammar only allows string
- // literals. We check to ensure that it is only a string literal later in the grammar
- // walker.
- var result = parseExpression();
- // Ensure the string being required is in our 'identifier' table. This will ensure
- // that features like 'find refs' will look inside this file when search for its name.
- if (result.kind === 9 /* StringLiteral */) {
- internIdentifier(result.text);
+ }
+ ts.getModuleInstanceState = getModuleInstanceState;
+ var ContainerFlags;
+ (function (ContainerFlags) {
+ // The current node is not a container, and no container manipulation should happen before
+ // recursing into it.
+ ContainerFlags[ContainerFlags["None"] = 0] = "None";
+ // The current node is a container. It should be set as the current container (and block-
+ // container) before recursing into it. The current node does not have locals. Examples:
+ //
+ // Classes, ObjectLiterals, TypeLiterals, Interfaces...
+ ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
+ // The current node is a block-scoped-container. It should be set as the current block-
+ // container before recursing into it. Examples:
+ //
+ // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
+ ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
+ ContainerFlags[ContainerFlags["HasLocals"] = 4] = "HasLocals";
+ // If the current node is a container that also container that also contains locals. Examples:
+ //
+ // Functions, Methods, Modules, Source-files.
+ ContainerFlags[ContainerFlags["IsContainerWithLocals"] = 5] = "IsContainerWithLocals";
+ })(ContainerFlags || (ContainerFlags = {}));
+ var binder = createBinder();
+ function bindSourceFile(file, options) {
+ var start = new Date().getTime();
+ binder(file, options);
+ ts.bindTime += new Date().getTime() - start;
+ }
+ ts.bindSourceFile = bindSourceFile;
+ function createBinder() {
+ var file;
+ var options;
+ var parent;
+ var container;
+ var blockScopeContainer;
+ var lastContainer;
+ var seenThisKeyword;
+ // state used by reachability checks
+ var hasExplicitReturn;
+ var currentReachabilityState;
+ var labelStack;
+ var labelIndexMap;
+ var implicitLabels;
+ // If this file is an external module, then it is automatically in strict-mode according to
+ // ES6. If it is not an external module, then we'll determine if it is in strict mode or
+ // not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
+ var inStrictMode;
+ var symbolCount = 0;
+ var Symbol;
+ var classifiableNames;
+ function bindSourceFile(f, opts) {
+ file = f;
+ options = opts;
+ inStrictMode = !!file.externalModuleIndicator;
+ classifiableNames = {};
+ Symbol = ts.objectAllocator.getSymbolConstructor();
+ if (!file.locals) {
+ bind(file);
+ file.symbolCount = symbolCount;
+ file.classifiableNames = classifiableNames;
}
- return result;
- }
- function parseNamespaceImport() {
- // NameSpaceImport:
- // * as ImportedBinding
- var namespaceImport = createNode(224 /* NamespaceImport */);
- parseExpected(37 /* AsteriskToken */);
- parseExpected(116 /* AsKeyword */);
- namespaceImport.name = parseIdentifier();
- return finishNode(namespaceImport);
- }
- function parseNamedImportsOrExports(kind) {
- var node = createNode(kind);
- // NamedImports:
- // { }
- // { ImportsList }
- // { ImportsList, }
- // ImportsList:
- // ImportSpecifier
- // ImportsList, ImportSpecifier
- node.elements = parseBracketedList(21 /* ImportOrExportSpecifiers */, kind === 225 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 15 /* OpenBraceToken */, 16 /* CloseBraceToken */);
- return finishNode(node);
- }
- function parseExportSpecifier() {
- return parseImportOrExportSpecifier(230 /* ExportSpecifier */);
- }
- function parseImportSpecifier() {
- return parseImportOrExportSpecifier(226 /* ImportSpecifier */);
+ parent = undefined;
+ container = undefined;
+ blockScopeContainer = undefined;
+ lastContainer = undefined;
+ seenThisKeyword = false;
+ hasExplicitReturn = false;
+ labelStack = undefined;
+ labelIndexMap = undefined;
+ implicitLabels = undefined;
}
- function parseImportOrExportSpecifier(kind) {
- var node = createNode(kind);
- // ImportSpecifier:
- // BindingIdentifier
- // IdentifierName as BindingIdentifier
- // ExportSpecififer:
- // IdentifierName
- // IdentifierName as IdentifierName
- var checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
- var checkIdentifierStart = scanner.getTokenPos();
- var checkIdentifierEnd = scanner.getTextPos();
- var identifierName = parseIdentifierName();
- if (token === 116 /* AsKeyword */) {
- node.propertyName = identifierName;
- parseExpected(116 /* AsKeyword */);
- checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
- checkIdentifierStart = scanner.getTokenPos();
- checkIdentifierEnd = scanner.getTextPos();
- node.name = parseIdentifierName();
- }
- else {
- node.name = identifierName;
- }
- if (kind === 226 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
- // Report error identifier expected
- parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected);
- }
- return finishNode(node);
+ return bindSourceFile;
+ function createSymbol(flags, name) {
+ symbolCount++;
+ return new Symbol(flags, name);
}
- function parseExportDeclaration(fullStart, decorators, modifiers) {
- var node = createNode(228 /* ExportDeclaration */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- if (parseOptional(37 /* AsteriskToken */)) {
- parseExpected(133 /* FromKeyword */);
- node.moduleSpecifier = parseModuleSpecifier();
+ function addDeclarationToSymbol(symbol, node, symbolFlags) {
+ symbol.flags |= symbolFlags;
+ node.symbol = symbol;
+ if (!symbol.declarations) {
+ symbol.declarations = [];
}
- else {
- node.exportClause = parseNamedImportsOrExports(229 /* NamedExports */);
- // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
- // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
- // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
- if (token === 133 /* FromKeyword */ || (token === 9 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
- parseExpected(133 /* FromKeyword */);
- node.moduleSpecifier = parseModuleSpecifier();
- }
+ symbol.declarations.push(node);
+ if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) {
+ symbol.exports = {};
}
- parseSemicolon();
- return finishNode(node);
- }
- function parseExportAssignment(fullStart, decorators, modifiers) {
- var node = createNode(227 /* ExportAssignment */, fullStart);
- node.decorators = decorators;
- setModifiers(node, modifiers);
- if (parseOptional(56 /* EqualsToken */)) {
- node.isExportEquals = true;
+ if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) {
+ symbol.members = {};
}
- else {
- parseExpected(77 /* DefaultKeyword */);
+ if (symbolFlags & 107455 /* Value */ && !symbol.valueDeclaration) {
+ symbol.valueDeclaration = node;
}
- node.expression = parseAssignmentExpressionOrHigher();
- parseSemicolon();
- return finishNode(node);
}
- function processReferenceComments(sourceFile) {
- var triviaScanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, 0 /* Standard */, sourceText);
- var referencedFiles = [];
- var amdDependencies = [];
- var amdModuleName;
- // Keep scanning all the leading trivia in the file until we get to something that
- // isn't trivia. Any single line comment will be analyzed to see if it is a
- // reference comment.
- while (true) {
- var kind = triviaScanner.scan();
- if (kind === 5 /* WhitespaceTrivia */ || kind === 4 /* NewLineTrivia */ || kind === 3 /* MultiLineCommentTrivia */) {
- continue;
- }
- if (kind !== 2 /* SingleLineCommentTrivia */) {
- break;
- }
- var range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
- var comment = sourceText.substring(range.pos, range.end);
- var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range);
- if (referencePathMatchResult) {
- var fileReference = referencePathMatchResult.fileReference;
- sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
- var diagnosticMessage = referencePathMatchResult.diagnosticMessage;
- if (fileReference) {
- referencedFiles.push(fileReference);
- }
- if (diagnosticMessage) {
- parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage));
- }
+ // Should not be called on a declaration with a computed property name,
+ // unless it is a well known Symbol.
+ function getDeclarationName(node) {
+ if (node.name) {
+ if (node.kind === 218 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */) {
+ return "\"" + node.name.text + "\"";
}
- else {
- var amdModuleNameRegEx = /^\/\/\/\s*".length;
- return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
- }
+ container = saveContainer;
+ parent = saveParent;
+ blockScopeContainer = savedBlockScopeContainer;
+ }
+ /**
+ * Returns true if node and its subnodes were successfully traversed.
+ * Returning false means that node was not examined and caller needs to dive into the node himself.
+ */
+ function bindReachableStatement(node) {
+ if (checkUnreachable(node)) {
+ ts.forEachChild(node, bind);
+ return;
}
- function parseQualifiedName(left) {
- var result = createNode(135 /* QualifiedName */, left.pos);
- result.left = left;
- result.right = parseIdentifierName();
- return finishNode(result);
+ switch (node.kind) {
+ case 198 /* WhileStatement */:
+ bindWhileStatement(node);
+ break;
+ case 197 /* DoStatement */:
+ bindDoStatement(node);
+ break;
+ case 199 /* ForStatement */:
+ bindForStatement(node);
+ break;
+ case 200 /* ForInStatement */:
+ case 201 /* ForOfStatement */:
+ bindForInOrForOfStatement(node);
+ break;
+ case 196 /* IfStatement */:
+ bindIfStatement(node);
+ break;
+ case 204 /* ReturnStatement */:
+ case 208 /* ThrowStatement */:
+ bindReturnOrThrow(node);
+ break;
+ case 203 /* BreakStatement */:
+ case 202 /* ContinueStatement */:
+ bindBreakOrContinueStatement(node);
+ break;
+ case 209 /* TryStatement */:
+ bindTryStatement(node);
+ break;
+ case 206 /* SwitchStatement */:
+ bindSwitchStatement(node);
+ break;
+ case 220 /* CaseBlock */:
+ bindCaseBlock(node);
+ break;
+ case 207 /* LabeledStatement */:
+ bindLabeledStatement(node);
+ break;
+ default:
+ ts.forEachChild(node, bind);
+ break;
}
- function parseJSDocRecordType() {
- var result = createNode(257 /* JSDocRecordType */);
- nextToken();
- result.members = parseDelimitedList(24 /* JSDocRecordMembers */, parseJSDocRecordMember);
- checkForTrailingComma(result.members);
- parseExpected(16 /* CloseBraceToken */);
- return finishNode(result);
+ }
+ function bindWhileStatement(n) {
+ var preWhileState = n.expression.kind === 84 /* FalseKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
+ var postWhileState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
+ // bind expressions (don't affect reachability)
+ bind(n.expression);
+ currentReachabilityState = preWhileState;
+ var postWhileLabel = pushImplicitLabel();
+ bind(n.statement);
+ popImplicitLabel(postWhileLabel, postWhileState);
+ }
+ function bindDoStatement(n) {
+ var preDoState = currentReachabilityState;
+ var postDoLabel = pushImplicitLabel();
+ bind(n.statement);
+ var postDoState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : preDoState;
+ popImplicitLabel(postDoLabel, postDoState);
+ // bind expressions (don't affect reachability)
+ bind(n.expression);
+ }
+ function bindForStatement(n) {
+ var preForState = currentReachabilityState;
+ var postForLabel = pushImplicitLabel();
+ // bind expressions (don't affect reachability)
+ bind(n.initializer);
+ bind(n.condition);
+ bind(n.incrementor);
+ bind(n.statement);
+ // for statement is considered infinite when it condition is either omitted or is true keyword
+ // - for(..;;..)
+ // - for(..;true;..)
+ var isInfiniteLoop = (!n.condition || n.condition.kind === 99 /* TrueKeyword */);
+ var postForState = isInfiniteLoop ? 4 /* Unreachable */ : preForState;
+ popImplicitLabel(postForLabel, postForState);
+ }
+ function bindForInOrForOfStatement(n) {
+ var preStatementState = currentReachabilityState;
+ var postStatementLabel = pushImplicitLabel();
+ // bind expressions (don't affect reachability)
+ bind(n.initializer);
+ bind(n.expression);
+ bind(n.statement);
+ popImplicitLabel(postStatementLabel, preStatementState);
+ }
+ function bindIfStatement(n) {
+ // denotes reachability state when entering 'thenStatement' part of the if statement:
+ // i.e. if condition is false then thenStatement is unreachable
+ var ifTrueState = n.expression.kind === 84 /* FalseKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
+ // denotes reachability state when entering 'elseStatement':
+ // i.e. if condition is true then elseStatement is unreachable
+ var ifFalseState = n.expression.kind === 99 /* TrueKeyword */ ? 4 /* Unreachable */ : currentReachabilityState;
+ currentReachabilityState = ifTrueState;
+ // bind expression (don't affect reachability)
+ bind(n.expression);
+ bind(n.thenStatement);
+ if (n.elseStatement) {
+ var preElseState = currentReachabilityState;
+ currentReachabilityState = ifFalseState;
+ bind(n.elseStatement);
+ currentReachabilityState = or(currentReachabilityState, preElseState);
}
- function parseJSDocRecordMember() {
- var result = createNode(258 /* JSDocRecordMember */);
- result.name = parseSimplePropertyName();
- if (token === 54 /* ColonToken */) {
- nextToken();
- result.type = parseJSDocType();
- }
- return finishNode(result);
+ else {
+ currentReachabilityState = or(currentReachabilityState, ifFalseState);
}
- function parseJSDocNonNullableType() {
- var result = createNode(256 /* JSDocNonNullableType */);
- nextToken();
- result.type = parseJSDocType();
- return finishNode(result);
+ }
+ function bindReturnOrThrow(n) {
+ // bind expression (don't affect reachability)
+ bind(n.expression);
+ if (n.kind === 204 /* ReturnStatement */) {
+ hasExplicitReturn = true;
}
- function parseJSDocTupleType() {
- var result = createNode(254 /* JSDocTupleType */);
- nextToken();
- result.types = parseDelimitedList(25 /* JSDocTupleTypes */, parseJSDocType);
- checkForTrailingComma(result.types);
- parseExpected(20 /* CloseBracketToken */);
- return finishNode(result);
+ currentReachabilityState = 4 /* Unreachable */;
+ }
+ function bindBreakOrContinueStatement(n) {
+ // call bind on label (don't affect reachability)
+ bind(n.label);
+ // for continue case touch label so it will be marked a used
+ var isValidJump = jumpToLabel(n.label, n.kind === 203 /* BreakStatement */ ? currentReachabilityState : 4 /* Unreachable */);
+ if (isValidJump) {
+ currentReachabilityState = 4 /* Unreachable */;
}
- function checkForTrailingComma(list) {
- if (parseDiagnostics.length === 0 && list.hasTrailingComma) {
- var start = list.end - ",".length;
- parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed);
+ }
+ function bindTryStatement(n) {
+ // catch\finally blocks has the same reachability as try block
+ var preTryState = currentReachabilityState;
+ bind(n.tryBlock);
+ var postTryState = currentReachabilityState;
+ currentReachabilityState = preTryState;
+ bind(n.catchClause);
+ var postCatchState = currentReachabilityState;
+ currentReachabilityState = preTryState;
+ bind(n.finallyBlock);
+ // post catch/finally state is reachable if
+ // - post try state is reachable - control flow can fall out of try block
+ // - post catch state is reachable - control flow can fall out of catch block
+ currentReachabilityState = or(postTryState, postCatchState);
+ }
+ function bindSwitchStatement(n) {
+ var preSwitchState = currentReachabilityState;
+ var postSwitchLabel = pushImplicitLabel();
+ // bind expression (don't affect reachability)
+ bind(n.expression);
+ bind(n.caseBlock);
+ var hasDefault = ts.forEach(n.caseBlock.clauses, function (c) { return c.kind === 242 /* DefaultClause */; });
+ // post switch state is unreachable if switch is exaustive (has a default case ) and does not have fallthrough from the last case
+ var postSwitchState = hasDefault && currentReachabilityState !== 2 /* Reachable */ ? 4 /* Unreachable */ : preSwitchState;
+ popImplicitLabel(postSwitchLabel, postSwitchState);
+ }
+ function bindCaseBlock(n) {
+ var startState = currentReachabilityState;
+ for (var _i = 0, _a = n.clauses; _i < _a.length; _i++) {
+ var clause = _a[_i];
+ currentReachabilityState = startState;
+ bind(clause);
+ if (clause.statements.length && currentReachabilityState === 2 /* Reachable */ && options.noFallthroughCasesInSwitch) {
+ errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch);
}
}
- function parseJSDocUnionType() {
- var result = createNode(253 /* JSDocUnionType */);
- nextToken();
- result.types = parseJSDocTypeList(parseJSDocType());
- parseExpected(18 /* CloseParenToken */);
- return finishNode(result);
+ }
+ function bindLabeledStatement(n) {
+ // call bind on label (don't affect reachability)
+ bind(n.label);
+ var ok = pushNamedLabel(n.label);
+ bind(n.statement);
+ if (ok) {
+ popNamedLabel(n.label, currentReachabilityState);
}
- function parseJSDocTypeList(firstType) {
- ts.Debug.assert(!!firstType);
- var types = [];
- types.pos = firstType.pos;
- types.push(firstType);
- while (parseOptional(47 /* BarToken */)) {
- types.push(parseJSDocType());
- }
- types.end = scanner.getStartPos();
- return types;
+ }
+ function getContainerFlags(node) {
+ switch (node.kind) {
+ case 186 /* ClassExpression */:
+ case 214 /* ClassDeclaration */:
+ case 215 /* InterfaceDeclaration */:
+ case 217 /* EnumDeclaration */:
+ case 155 /* TypeLiteral */:
+ case 165 /* ObjectLiteralExpression */:
+ return 1 /* IsContainer */;
+ case 147 /* CallSignature */:
+ case 148 /* ConstructSignature */:
+ case 149 /* IndexSignature */:
+ case 143 /* MethodDeclaration */:
+ case 142 /* MethodSignature */:
+ case 213 /* FunctionDeclaration */:
+ case 144 /* Constructor */:
+ case 145 /* GetAccessor */:
+ case 146 /* SetAccessor */:
+ case 152 /* FunctionType */:
+ case 153 /* ConstructorType */:
+ case 173 /* FunctionExpression */:
+ case 174 /* ArrowFunction */:
+ case 218 /* ModuleDeclaration */:
+ case 248 /* SourceFile */:
+ case 216 /* TypeAliasDeclaration */:
+ return 5 /* IsContainerWithLocals */;
+ case 244 /* CatchClause */:
+ case 199 /* ForStatement */:
+ case 200 /* ForInStatement */:
+ case 201 /* ForOfStatement */:
+ case 220 /* CaseBlock */:
+ return 2 /* IsBlockScopedContainer */;
+ case 192 /* Block */:
+ // do not treat blocks directly inside a function as a block-scoped-container.
+ // Locals that reside in this block should go to the function locals. Othewise 'x'
+ // would not appear to be a redeclaration of a block scoped local in the following
+ // example:
+ //
+ // function foo() {
+ // var x;
+ // let x;
+ // }
+ //
+ // If we placed 'var x' into the function locals and 'let x' into the locals of
+ // the block, then there would be no collision.
+ //
+ // By not creating a new block-scoped-container here, we ensure that both 'var x'
+ // and 'let x' go into the Function-container's locals, and we do get a collision
+ // conflict.
+ return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
}
- function parseJSDocAllType() {
- var result = createNode(250 /* JSDocAllType */);
- nextToken();
- return finishNode(result);
+ return 0 /* None */;
+ }
+ function addToContainerChain(next) {
+ if (lastContainer) {
+ lastContainer.nextContainer = next;
}
- function parseJSDocUnknownOrNullableType() {
- var pos = scanner.getStartPos();
- // skip the ?
- nextToken();
- // Need to lookahead to decide if this is a nullable or unknown type.
- // Here are cases where we'll pick the unknown type:
- //
- // Foo(?,
- // { a: ? }
- // Foo(?)
- // Foo>
- // Foo(?=
- // (?|
- if (token === 24 /* CommaToken */ ||
- token === 16 /* CloseBraceToken */ ||
- token === 18 /* CloseParenToken */ ||
- token === 27 /* GreaterThanToken */ ||
- token === 56 /* EqualsToken */ ||
- token === 47 /* BarToken */) {
- var result = createNode(251 /* JSDocUnknownType */, pos);
- return finishNode(result);
- }
- else {
- var result = createNode(255 /* JSDocNullableType */, pos);
- result.type = parseJSDocType();
- return finishNode(result);
+ lastContainer = next;
+ }
+ function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
+ // Just call this directly so that the return type of this function stays "void".
+ declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes);
+ }
+ function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) {
+ switch (container.kind) {
+ // Modules, source files, and classes need specialized handling for how their
+ // members are declared (for example, a member of a class will go into a specific
+ // symbol table depending on if it is static or not). We defer to specialized
+ // handlers to take care of declaring these child members.
+ case 218 /* ModuleDeclaration */:
+ return declareModuleMember(node, symbolFlags, symbolExcludes);
+ case 248 /* SourceFile */:
+ return declareSourceFileMember(node, symbolFlags, symbolExcludes);
+ case 186 /* ClassExpression */:
+ case 214 /* ClassDeclaration */:
+ return declareClassMember(node, symbolFlags, symbolExcludes);
+ case 217 /* EnumDeclaration */:
+ return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
+ case 155 /* TypeLiteral */:
+ case 165 /* ObjectLiteralExpression */:
+ case 215 /* InterfaceDeclaration */:
+ // Interface/Object-types always have their children added to the 'members' of
+ // their container. They are only accessible through an instance of their
+ // container, and are never in scope otherwise (even inside the body of the
+ // object / type / interface declaring them). An exception is type parameters,
+ // which are in scope without qualification (similar to 'locals').
+ return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
+ case 152 /* FunctionType */:
+ case 153 /* ConstructorType */:
+ case 147 /* CallSignature */:
+ case 148 /* ConstructSignature */:
+ case 149 /* IndexSignature */:
+ case 143 /* MethodDeclaration */:
+ case 142 /* MethodSignature */:
+ case 144 /* Constructor */:
+ case 145 /* GetAccessor */:
+ case 146 /* SetAccessor */:
+ case 213 /* FunctionDeclaration */:
+ case 173 /* FunctionExpression */:
+ case 174 /* ArrowFunction */:
+ case 216 /* TypeAliasDeclaration */:
+ // All the children of these container types are never visible through another
+ // symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
+ // they're only accessed 'lexically' (i.e. from code that exists underneath
+ // their container in the tree. To accomplish this, we simply add their declared
+ // symbol to the 'locals' of the container. These symbols can then be found as
+ // the type checker walks up the containers, checking them for matching names.
+ return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ }
+ function declareClassMember(node, symbolFlags, symbolExcludes) {
+ return node.flags & 64 /* Static */
+ ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
+ : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
+ }
+ function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
+ return ts.isExternalModule(file)
+ ? declareModuleMember(node, symbolFlags, symbolExcludes)
+ : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ function hasExportDeclarations(node) {
+ var body = node.kind === 248 /* SourceFile */ ? node : node.body;
+ if (body.kind === 248 /* SourceFile */ || body.kind === 219 /* ModuleBlock */) {
+ for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
+ var stat = _a[_i];
+ if (stat.kind === 228 /* ExportDeclaration */ || stat.kind === 227 /* ExportAssignment */) {
+ return true;
+ }
}
}
- function parseIsolatedJSDocComment(content, start, length) {
- initializeState("file.js", content, 2 /* Latest */, /*_syntaxCursor:*/ undefined);
- var jsDocComment = parseJSDocComment(/*parent:*/ undefined, start, length);
- var diagnostics = parseDiagnostics;
- clearState();
- return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined;
+ return false;
+ }
+ function setExportContextFlag(node) {
+ // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
+ // declarations with export modifiers) is an export context in which declarations are implicitly exported.
+ if (ts.isInAmbientContext(node) && !hasExportDeclarations(node)) {
+ node.flags |= 131072 /* ExportContext */;
}
- JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
- function parseJSDocComment(parent, start, length) {
- var comment = parseJSDocCommentWorker(start, length);
- if (comment) {
- fixupParentReferences(comment);
- comment.parent = parent;
- }
- return comment;
+ else {
+ node.flags &= ~131072 /* ExportContext */;
}
- JSDocParser.parseJSDocComment = parseJSDocComment;
- function parseJSDocCommentWorker(start, length) {
- var content = sourceText;
- start = start || 0;
- var end = length === undefined ? content.length : start + length;
- length = end - start;
- ts.Debug.assert(start >= 0);
- ts.Debug.assert(start <= end);
- ts.Debug.assert(end <= content.length);
- var tags;
- var pos;
- // NOTE(cyrusn): This is essentially a handwritten scanner for JSDocComments. I
- // considered using an actual Scanner, but this would complicate things. The
- // scanner would need to know it was in a Doc Comment. Otherwise, it would then
- // produce comments *inside* the doc comment. In the end it was just easier to
- // write a simple scanner rather than go that route.
- if (length >= "/** */".length) {
- if (content.charCodeAt(start) === 47 /* slash */ &&
- content.charCodeAt(start + 1) === 42 /* asterisk */ &&
- content.charCodeAt(start + 2) === 42 /* asterisk */ &&
- content.charCodeAt(start + 3) !== 42 /* asterisk */) {
- // Initially we can parse out a tag. We also have seen a starting asterisk.
- // This is so that /** * @type */ doesn't parse.
- var canParseTag = true;
- var seenAsterisk = true;
- for (pos = start + "/**".length; pos < end;) {
- var ch = content.charCodeAt(pos);
- pos++;
- if (ch === 64 /* at */ && canParseTag) {
- parseTag();
- // Once we parse out a tag, we cannot keep parsing out tags on this line.
- canParseTag = false;
- continue;
- }
- if (ts.isLineBreak(ch)) {
- // After a line break, we can parse a tag, and we haven't seen as asterisk
- // on the next line yet.
- canParseTag = true;
- seenAsterisk = false;
- continue;
- }
- if (ts.isWhiteSpace(ch)) {
- // Whitespace doesn't affect any of our parsing.
- continue;
- }
- // Ignore the first asterisk on a line.
- if (ch === 42 /* asterisk */) {
- if (seenAsterisk) {
- // If we've already seen an asterisk, then we can no longer parse a tag
- // on this line.
- canParseTag = false;
- }
- seenAsterisk = true;
- continue;
- }
- // Anything else is doc comment text. We can't do anything with it. Because it
- // wasn't a tag, we can no longer parse a tag on this line until we hit the next
- // line break.
- canParseTag = false;
- }
- }
- }
- return createJSDocComment();
- function createJSDocComment() {
- if (!tags) {
- return undefined;
- }
- var result = createNode(265 /* JSDocComment */, start);
- result.tags = tags;
- return finishNode(result, end);
- }
- function skipWhitespace() {
- while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) {
- pos++;
- }
+ }
+ function bindModuleDeclaration(node) {
+ setExportContextFlag(node);
+ if (node.name.kind === 9 /* StringLiteral */) {
+ declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
+ }
+ else {
+ var state = getModuleInstanceState(node);
+ if (state === 0 /* NonInstantiated */) {
+ declareSymbolAndAddToSymbolTable(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */);
}
- function parseTag() {
- ts.Debug.assert(content.charCodeAt(pos - 1) === 64 /* at */);
- var atToken = createNode(55 /* AtToken */, pos - 1);
- atToken.end = pos;
- var tagName = scanIdentifier();
- if (!tagName) {
- return;
+ else {
+ declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
+ if (node.symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)) {
+ // if module was already merged with some function, class or non-const enum
+ // treat is a non-const-enum-only
+ node.symbol.constEnumOnlyModule = false;
}
- var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName);
- addTag(tag);
- }
- function handleTag(atToken, tagName) {
- if (tagName) {
- switch (tagName.text) {
- case "param":
- return handleParamTag(atToken, tagName);
- case "return":
- case "returns":
- return handleReturnTag(atToken, tagName);
- case "template":
- return handleTemplateTag(atToken, tagName);
- case "type":
- return handleTypeTag(atToken, tagName);
+ else {
+ var currentModuleIsConstEnumOnly = state === 2 /* ConstEnumOnly */;
+ if (node.symbol.constEnumOnlyModule === undefined) {
+ // non-merged case - use the current state
+ node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
}
- }
- return undefined;
- }
- function handleUnknownTag(atToken, tagName) {
- var result = createNode(266 /* JSDocTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- return finishNode(result, pos);
- }
- function addTag(tag) {
- if (tag) {
- if (!tags) {
- tags = [];
- tags.pos = tag.pos;
+ else {
+ // merged case: module is const enum only if all its pieces are non-instantiated or const enum
+ node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
}
- tags.push(tag);
- tags.end = tag.end;
- }
- }
- function tryParseTypeExpression() {
- skipWhitespace();
- if (content.charCodeAt(pos) !== 123 /* openBrace */) {
- return undefined;
- }
- var typeExpression = parseJSDocTypeExpression(pos, end - pos);
- pos = typeExpression.end;
- return typeExpression;
- }
- function handleParamTag(atToken, tagName) {
- var typeExpression = tryParseTypeExpression();
- skipWhitespace();
- var name;
- var isBracketed;
- if (content.charCodeAt(pos) === 91 /* openBracket */) {
- pos++;
- skipWhitespace();
- name = scanIdentifier();
- isBracketed = true;
- }
- else {
- name = scanIdentifier();
- }
- if (!name) {
- parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected);
- }
- var preName, postName;
- if (typeExpression) {
- postName = name;
- }
- else {
- preName = name;
- }
- if (!typeExpression) {
- typeExpression = tryParseTypeExpression();
- }
- var result = createNode(267 /* JSDocParameterTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.preParameterName = preName;
- result.typeExpression = typeExpression;
- result.postParameterName = postName;
- result.isBracketed = isBracketed;
- return finishNode(result, pos);
- }
- function handleReturnTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 268 /* JSDocReturnTag */; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
}
- var result = createNode(268 /* JSDocReturnTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeExpression = tryParseTypeExpression();
- return finishNode(result, pos);
}
- function handleTypeTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 269 /* JSDocTypeTag */; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ }
+ }
+ function bindFunctionOrConstructorType(node) {
+ // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
+ // to the one we would get for: { <...>(...): T }
+ //
+ // We do that by making an anonymous type literal symbol, and then setting the function
+ // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
+ // from an actual type literal symbol you would have gotten had you used the long form.
+ var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node));
+ addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
+ var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type");
+ addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
+ typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a);
+ var _a;
+ }
+ function bindObjectLiteralExpression(node) {
+ var ElementKind;
+ (function (ElementKind) {
+ ElementKind[ElementKind["Property"] = 1] = "Property";
+ ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
+ })(ElementKind || (ElementKind = {}));
+ if (inStrictMode) {
+ var seen = {};
+ for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
+ var prop = _a[_i];
+ if (prop.name.kind !== 69 /* Identifier */) {
+ continue;
}
- var result = createNode(269 /* JSDocTypeTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeExpression = tryParseTypeExpression();
- return finishNode(result, pos);
- }
- function handleTemplateTag(atToken, tagName) {
- if (ts.forEach(tags, function (t) { return t.kind === 270 /* JSDocTemplateTag */; })) {
- parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
+ var identifier = prop.name;
+ // ECMA-262 11.1.5 Object Initialiser
+ // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
+ // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
+ // IsDataDescriptor(propId.descriptor) is true.
+ // b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
+ // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
+ // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
+ // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
+ var currentKind = prop.kind === 245 /* PropertyAssignment */ || prop.kind === 246 /* ShorthandPropertyAssignment */ || prop.kind === 143 /* MethodDeclaration */
+ ? 1 /* Property */
+ : 2 /* Accessor */;
+ var existingKind = seen[identifier.text];
+ if (!existingKind) {
+ seen[identifier.text] = currentKind;
+ continue;
}
- var typeParameters = [];
- typeParameters.pos = pos;
- while (true) {
- skipWhitespace();
- var startPos = pos;
- var name_8 = scanIdentifier();
- if (!name_8) {
- parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected);
- return undefined;
- }
- var typeParameter = createNode(137 /* TypeParameter */, name_8.pos);
- typeParameter.name = name_8;
- finishNode(typeParameter, pos);
- typeParameters.push(typeParameter);
- skipWhitespace();
- if (content.charCodeAt(pos) !== 44 /* comma */) {
- break;
- }
- pos++;
+ if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
+ var span = ts.getErrorSpanForNode(file, identifier);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
}
- typeParameters.end = pos;
- var result = createNode(270 /* JSDocTemplateTag */, atToken.pos);
- result.atToken = atToken;
- result.tagName = tagName;
- result.typeParameters = typeParameters;
- return finishNode(result, pos);
}
- function scanIdentifier() {
- var startPos = pos;
- for (; pos < end; pos++) {
- var ch = content.charCodeAt(pos);
- if (pos === startPos && ts.isIdentifierStart(ch, 2 /* Latest */)) {
- continue;
- }
- else if (pos > startPos && ts.isIdentifierPart(ch, 2 /* Latest */)) {
- continue;
- }
+ }
+ return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object");
+ }
+ function bindAnonymousDeclaration(node, symbolFlags, name) {
+ var symbol = createSymbol(symbolFlags, name);
+ addDeclarationToSymbol(symbol, node, symbolFlags);
+ }
+ function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
+ switch (blockScopeContainer.kind) {
+ case 218 /* ModuleDeclaration */:
+ declareModuleMember(node, symbolFlags, symbolExcludes);
+ break;
+ case 248 /* SourceFile */:
+ if (ts.isExternalModule(container)) {
+ declareModuleMember(node, symbolFlags, symbolExcludes);
break;
}
- if (startPos === pos) {
- return undefined;
- }
- var result = createNode(69 /* Identifier */, startPos);
- result.text = content.substring(startPos, pos);
- return finishNode(result, pos);
+ // fall through.
+ default:
+ if (!blockScopeContainer.locals) {
+ blockScopeContainer.locals = {};
+ addToContainerChain(blockScopeContainer);
+ }
+ declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
+ }
+ }
+ function bindBlockScopedVariableDeclaration(node) {
+ bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
+ }
+ // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
+ // check for reserved words used as identifiers in strict mode code.
+ function checkStrictModeIdentifier(node) {
+ if (inStrictMode &&
+ node.originalKeywordKind >= 106 /* FirstFutureReservedWord */ &&
+ node.originalKeywordKind <= 114 /* LastFutureReservedWord */ &&
+ !ts.isIdentifierName(node)) {
+ // Report error only if there are no parse errors in file
+ if (!file.parseDiagnostics.length) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
}
}
- JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker;
- })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
- })(Parser || (Parser = {}));
- var IncrementalParser;
- (function (IncrementalParser) {
- function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
- aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
- checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
- if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
- // if the text didn't change, then we can just return our current source file as-is.
- return sourceFile;
+ }
+ function getStrictModeIdentifierMessage(node) {
+ // Provide specialized messages to help the user understand why we think they're in
+ // strict mode.
+ if (ts.getContainingClass(node)) {
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
}
- if (sourceFile.statements.length === 0) {
- // If we don't have any statements in the current source file, then there's no real
- // way to incrementally parse. So just do a full parse instead.
- return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setNodeParents*/ true);
+ if (file.externalModuleIndicator) {
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
}
- // Make sure we're not trying to incrementally update a source file more than once. Once
- // we do an update the original source file is considered unusbale from that point onwards.
- //
- // This is because we do incremental parsing in-place. i.e. we take nodes from the old
- // tree and give them new positions and parents. From that point on, trusting the old
- // tree at all is not possible as far too much of it may violate invariants.
- var incrementalSourceFile = sourceFile;
- ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
- incrementalSourceFile.hasBeenIncrementallyParsed = true;
- var oldText = sourceFile.text;
- var syntaxCursor = createSyntaxCursor(sourceFile);
- // Make the actual change larger so that we know to reparse anything whose lookahead
- // might have intersected the change.
- var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
- checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
- // Ensure that extending the affected range only moved the start of the change range
- // earlier in the file.
- ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
- ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
- ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
- // The is the amount the nodes after the edit range need to be adjusted. It can be
- // positive (if the edit added characters), negative (if the edit deleted characters)
- // or zero (if this was a pure overwrite with nothing added/removed).
- var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
- // If we added or removed characters during the edit, then we need to go and adjust all
- // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they
- // may move backward (if we deleted chars).
- //
- // Doing this helps us out in two ways. First, it means that any nodes/tokens we want
- // to reuse are already at the appropriate position in the new text. That way when we
- // reuse them, we don't have to figure out if they need to be adjusted. Second, it makes
- // it very easy to determine if we can reuse a node. If the node's position is at where
- // we are in the text, then we can reuse it. Otherwise we can't. If the node's position
- // is ahead of us, then we'll need to rescan tokens. If the node's position is behind
- // us, then we'll need to skip it or crumble it as appropriate
- //
- // We will also adjust the positions of nodes that intersect the change range as well.
- // By doing this, we ensure that all the positions in the old tree are consistent, not
- // just the positions of nodes entirely before/after the change range. By being
- // consistent, we can then easily map from positions to nodes in the old tree easily.
- //
- // Also, mark any syntax elements that intersect the changed span. We know, up front,
- // that we cannot reuse these elements.
- updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
- // Now that we've set up our internal incremental state just proceed and parse the
- // source file in the normal fashion. When possible the parser will retrieve and
- // reuse nodes from the old tree.
- //
- // Note: passing in 'true' for setNodeParents is very important. When incrementally
- // parsing, we will be reusing nodes from the old tree, and placing it into new
- // parents. If we don't set the parents now, we'll end up with an observably
- // inconsistent tree. Setting the parents on the new tree should be very fast. We
- // will immediately bail out of walking any subtrees when we can see that their parents
- // are already correct.
- var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /* setParentNode */ true);
- return result;
+ return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
}
- IncrementalParser.updateSourceFile = updateSourceFile;
- function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
- if (isArray) {
- visitArray(element);
+ function checkStrictModeBinaryExpression(node) {
+ if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
+ // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
+ // Assignment operator(11.13) or of a PostfixExpression(11.3)
+ checkStrictModeEvalOrArguments(node, node.left);
}
- else {
- visitNode(element);
+ }
+ function checkStrictModeCatchClause(node) {
+ // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
+ // Catch production is eval or arguments
+ if (inStrictMode && node.variableDeclaration) {
+ checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
}
- return;
- function visitNode(node) {
- var text = "";
- if (aggressiveChecks && shouldCheckNode(node)) {
- text = oldText.substring(node.pos, node.end);
- }
- // Ditch any existing LS children we may have created. This way we can avoid
- // moving them forward.
- if (node._children) {
- node._children = undefined;
- }
- if (node.jsDocComment) {
- node.jsDocComment = undefined;
- }
- node.pos += delta;
- node.end += delta;
- if (aggressiveChecks && shouldCheckNode(node)) {
- ts.Debug.assert(text === newText.substring(node.pos, node.end));
- }
- forEachChild(node, visitNode, visitArray);
- checkNodePositions(node, aggressiveChecks);
+ }
+ function checkStrictModeDeleteExpression(node) {
+ // Grammar checking
+ if (inStrictMode && node.expression.kind === 69 /* Identifier */) {
+ // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
+ // UnaryExpression is a direct reference to a variable, function argument, or function name
+ var span = ts.getErrorSpanForNode(file, node.expression);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
}
- function visitArray(array) {
- array._children = undefined;
- array.pos += delta;
- array.end += delta;
- for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
- var node = array_7[_i];
- visitNode(node);
+ }
+ function isEvalOrArgumentsIdentifier(node) {
+ return node.kind === 69 /* Identifier */ &&
+ (node.text === "eval" || node.text === "arguments");
+ }
+ function checkStrictModeEvalOrArguments(contextNode, name) {
+ if (name && name.kind === 69 /* Identifier */) {
+ var identifier = name;
+ if (isEvalOrArgumentsIdentifier(identifier)) {
+ // We check first if the name is inside class declaration or class expression; if so give explicit message
+ // otherwise report generic error message.
+ var span = ts.getErrorSpanForNode(file, name);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
}
}
}
- function shouldCheckNode(node) {
- switch (node.kind) {
- case 9 /* StringLiteral */:
- case 8 /* NumericLiteral */:
- case 69 /* Identifier */:
- return true;
+ function getStrictModeEvalOrArgumentsMessage(node) {
+ // Provide specialized messages to help the user understand why we think they're in
+ // strict mode.
+ if (ts.getContainingClass(node)) {
+ return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
}
- return false;
+ if (file.externalModuleIndicator) {
+ return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
+ }
+ return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
}
- function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
- ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
- ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
- ts.Debug.assert(element.pos <= element.end);
- // We have an element that intersects the change range in some way. It may have its
- // start, or its end (or both) in the changed range. We want to adjust any part
- // that intersects such that the final tree is in a consistent state. i.e. all
- // chlidren have spans within the span of their parent, and all siblings are ordered
- // properly.
- // We may need to update both the 'pos' and the 'end' of the element.
- // If the 'pos' is before the start of the change, then we don't need to touch it.
- // If it isn't, then the 'pos' must be inside the change. How we update it will
- // depend if delta is positive or negative. If delta is positive then we have
- // something like:
- //
- // -------------------AAA-----------------
- // -------------------BBBCCCCCCC-----------------
- //
- // In this case, we consider any node that started in the change range to still be
- // starting at the same position.
- //
- // however, if the delta is negative, then we instead have something like this:
- //
- // -------------------XXXYYYYYYY-----------------
- // -------------------ZZZ-----------------
- //
- // In this case, any element that started in the 'X' range will keep its position.
- // However any element htat started after that will have their pos adjusted to be
- // at the end of the new range. i.e. any node that started in the 'Y' range will
- // be adjusted to have their start at the end of the 'Z' range.
- //
- // The element will keep its position if possible. Or Move backward to the new-end
- // if it's in the 'Y' range.
- element.pos = Math.min(element.pos, changeRangeNewEnd);
- // If the 'end' is after the change range, then we always adjust it by the delta
- // amount. However, if the end is in the change range, then how we adjust it
- // will depend on if delta is positive or negative. If delta is positive then we
- // have something like:
- //
- // -------------------AAA-----------------
- // -------------------BBBCCCCCCC-----------------
- //
- // In this case, we consider any node that ended inside the change range to keep its
- // end position.
- //
- // however, if the delta is negative, then we instead have something like this:
- //
- // -------------------XXXYYYYYYY-----------------
- // -------------------ZZZ-----------------
- //
- // In this case, any element that ended in the 'X' range will keep its position.
- // However any element htat ended after that will have their pos adjusted to be
- // at the end of the new range. i.e. any node that ended in the 'Y' range will
- // be adjusted to have their end at the end of the 'Z' range.
- if (element.end >= changeRangeOldEnd) {
- // Element ends after the change range. Always adjust the end pos.
- element.end += delta;
+ function checkStrictModeFunctionName(node) {
+ if (inStrictMode) {
+ // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
+ checkStrictModeEvalOrArguments(node, node.name);
}
- else {
- // Element ends in the change range. The element will keep its position if
- // possible. Or Move backward to the new-end if it's in the 'Y' range.
- element.end = Math.min(element.end, changeRangeNewEnd);
+ }
+ function checkStrictModeNumericLiteral(node) {
+ if (inStrictMode && node.flags & 32768 /* OctalLiteral */) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
}
- ts.Debug.assert(element.pos <= element.end);
- if (element.parent) {
- ts.Debug.assert(element.pos >= element.parent.pos);
- ts.Debug.assert(element.end <= element.parent.end);
+ }
+ function checkStrictModePostfixUnaryExpression(node) {
+ // Grammar checking
+ // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
+ // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
+ // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
+ if (inStrictMode) {
+ checkStrictModeEvalOrArguments(node, node.operand);
}
}
- function checkNodePositions(node, aggressiveChecks) {
- if (aggressiveChecks) {
- var pos = node.pos;
- forEachChild(node, function (child) {
- ts.Debug.assert(child.pos >= pos);
- pos = child.end;
- });
- ts.Debug.assert(pos <= node.end);
+ function checkStrictModePrefixUnaryExpression(node) {
+ // Grammar checking
+ if (inStrictMode) {
+ if (node.operator === 41 /* PlusPlusToken */ || node.operator === 42 /* MinusMinusToken */) {
+ checkStrictModeEvalOrArguments(node, node.operand);
+ }
}
}
- function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
- visitNode(sourceFile);
- return;
- function visitNode(child) {
- ts.Debug.assert(child.pos <= child.end);
- if (child.pos > changeRangeOldEnd) {
- // Node is entirely past the change range. We need to move both its pos and
- // end, forward or backward appropriately.
- moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
+ function checkStrictModeWithStatement(node) {
+ // Grammar checking for withStatement
+ if (inStrictMode) {
+ errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
+ }
+ }
+ function errorOnFirstToken(node, message, arg0, arg1, arg2) {
+ var span = ts.getSpanOfTokenAtPosition(file, node.pos);
+ file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
+ }
+ function getDestructuringParameterName(node) {
+ return "__" + ts.indexOf(node.parent.parameters, node);
+ }
+ function bind(node) {
+ if (!node) {
+ return;
+ }
+ node.parent = parent;
+ var savedInStrictMode = inStrictMode;
+ if (!savedInStrictMode) {
+ updateStrictMode(node);
+ }
+ // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
+ // and then potentially add the symbol to an appropriate symbol table. Possible
+ // destination symbol tables are:
+ //
+ // 1) The 'exports' table of the current container's symbol.
+ // 2) The 'members' table of the current container's symbol.
+ // 3) The 'locals' table of the current container.
+ //
+ // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
+ // (like TypeLiterals for example) will not be put in any table.
+ bindWorker(node);
+ // Then we recurse into the children of the node to bind them as well. For certain
+ // symbols we do specialized work when we recurse. For example, we'll keep track of
+ // the current 'container' node when it changes. This helps us know which symbol table
+ // a local should go into for example.
+ bindChildren(node);
+ inStrictMode = savedInStrictMode;
+ }
+ function updateStrictMode(node) {
+ switch (node.kind) {
+ case 248 /* SourceFile */:
+ case 219 /* ModuleBlock */:
+ updateStrictModeStatementList(node.statements);
return;
- }
- // Check if the element intersects the change range. If it does, then it is not
- // reusable. Also, we'll need to recurse to see what constituent portions we may
- // be able to use.
- var fullEnd = child.end;
- if (fullEnd >= changeStart) {
- child.intersectsChange = true;
- child._children = undefined;
- // Adjust the pos or end (or both) of the intersecting element accordingly.
- adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
- forEachChild(child, visitNode, visitArray);
- checkNodePositions(child, aggressiveChecks);
+ case 192 /* Block */:
+ if (ts.isFunctionLike(node.parent)) {
+ updateStrictModeStatementList(node.statements);
+ }
+ return;
+ case 214 /* ClassDeclaration */:
+ case 186 /* ClassExpression */:
+ // All classes are automatically in strict mode in ES6.
+ inStrictMode = true;
return;
- }
- // Otherwise, the node is entirely before the change range. No need to do anything with it.
- ts.Debug.assert(fullEnd < changeStart);
}
- function visitArray(array) {
- ts.Debug.assert(array.pos <= array.end);
- if (array.pos > changeRangeOldEnd) {
- // Array is entirely after the change range. We need to move it, and move any of
- // its children.
- moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
+ }
+ function updateStrictModeStatementList(statements) {
+ for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
+ var statement = statements_1[_i];
+ if (!ts.isPrologueDirective(statement)) {
return;
}
- // Check if the element intersects the change range. If it does, then it is not
- // reusable. Also, we'll need to recurse to see what constituent portions we may
- // be able to use.
- var fullEnd = array.end;
- if (fullEnd >= changeStart) {
- array.intersectsChange = true;
- array._children = undefined;
- // Adjust the pos or end (or both) of the intersecting array accordingly.
- adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
- for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
- var node = array_8[_i];
- visitNode(node);
- }
+ if (isUseStrictPrologueDirective(statement)) {
+ inStrictMode = true;
return;
}
- // Otherwise, the array is entirely before the change range. No need to do anything with it.
- ts.Debug.assert(fullEnd < changeStart);
}
}
- function extendToAffectedRange(sourceFile, changeRange) {
- // Consider the following code:
- // void foo() { /; }
- //
- // If the text changes with an insertion of / just before the semicolon then we end up with:
- // void foo() { //; }
- //
- // If we were to just use the changeRange a is, then we would not rescan the { token
- // (as it does not intersect the actual original change range). Because an edit may
- // change the token touching it, we actually need to look back *at least* one token so
- // that the prior token sees that change.
- var maxLookahead = 1;
- var start = changeRange.span.start;
- // the first iteration aligns us with the change start. subsequent iteration move us to
- // the left by maxLookahead tokens. We only need to do this as long as we're not at the
- // start of the tree.
- for (var i = 0; start > 0 && i <= maxLookahead; i++) {
- var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
- ts.Debug.assert(nearestNode.pos <= start);
- var position = nearestNode.pos;
- start = Math.max(0, position - 1);
+ /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
+ function isUseStrictPrologueDirective(node) {
+ var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression);
+ // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
+ // string to contain unicode escapes (as per ES5).
+ return nodeText === "\"use strict\"" || nodeText === "'use strict'";
+ }
+ function bindWorker(node) {
+ switch (node.kind) {
+ /* Strict mode checks */
+ case 69 /* Identifier */:
+ return checkStrictModeIdentifier(node);
+ case 181 /* BinaryExpression */:
+ if (ts.isInJavaScriptFile(node)) {
+ if (ts.isExportsPropertyAssignment(node)) {
+ bindExportsPropertyAssignment(node);
+ }
+ else if (ts.isModuleExportsAssignment(node)) {
+ bindModuleExportsAssignment(node);
+ }
+ }
+ return checkStrictModeBinaryExpression(node);
+ case 244 /* CatchClause */:
+ return checkStrictModeCatchClause(node);
+ case 175 /* DeleteExpression */:
+ return checkStrictModeDeleteExpression(node);
+ case 8 /* NumericLiteral */:
+ return checkStrictModeNumericLiteral(node);
+ case 180 /* PostfixUnaryExpression */:
+ return checkStrictModePostfixUnaryExpression(node);
+ case 179 /* PrefixUnaryExpression */:
+ return checkStrictModePrefixUnaryExpression(node);
+ case 205 /* WithStatement */:
+ return checkStrictModeWithStatement(node);
+ case 97 /* ThisKeyword */:
+ seenThisKeyword = true;
+ return;
+ case 137 /* TypeParameter */:
+ return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */);
+ case 138 /* Parameter */:
+ return bindParameter(node);
+ case 211 /* VariableDeclaration */:
+ case 163 /* BindingElement */:
+ return bindVariableDeclarationOrBindingElement(node);
+ case 141 /* PropertyDeclaration */:
+ case 140 /* PropertySignature */:
+ return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 107455 /* PropertyExcludes */);
+ case 245 /* PropertyAssignment */:
+ case 246 /* ShorthandPropertyAssignment */:
+ return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */);
+ case 247 /* EnumMember */:
+ return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */);
+ case 147 /* CallSignature */:
+ case 148 /* ConstructSignature */:
+ case 149 /* IndexSignature */:
+ return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
+ case 143 /* MethodDeclaration */:
+ case 142 /* MethodSignature */:
+ // If this is an ObjectLiteralExpression method, then it sits in the same space
+ // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes
+ // so that it will conflict with any other object literal members with the same
+ // name.
+ return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */);
+ case 213 /* FunctionDeclaration */:
+ checkStrictModeFunctionName(node);
+ return declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */);
+ case 144 /* Constructor */:
+ return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
+ case 145 /* GetAccessor */:
+ return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */);
+ case 146 /* SetAccessor */:
+ return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */);
+ case 152 /* FunctionType */:
+ case 153 /* ConstructorType */:
+ return bindFunctionOrConstructorType(node);
+ case 155 /* TypeLiteral */:
+ return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type");
+ case 165 /* ObjectLiteralExpression */:
+ return bindObjectLiteralExpression(node);
+ case 173 /* FunctionExpression */:
+ case 174 /* ArrowFunction */:
+ checkStrictModeFunctionName(node);
+ var bindingName = node.name ? node.name.text : "__function";
+ return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
+ case 168 /* CallExpression */:
+ if (ts.isInJavaScriptFile(node)) {
+ bindCallExpression(node);
+ }
+ break;
+ // Members of classes, interfaces, and modules
+ case 186 /* ClassExpression */:
+ case 214 /* ClassDeclaration */:
+ return bindClassLikeDeclaration(node);
+ case 215 /* InterfaceDeclaration */:
+ return bindBlockScopedDeclaration(node, 64 /* Interface */, 792960 /* InterfaceExcludes */);
+ case 216 /* TypeAliasDeclaration */:
+ return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */);
+ case 217 /* EnumDeclaration */:
+ return bindEnumDeclaration(node);
+ case 218 /* ModuleDeclaration */:
+ return bindModuleDeclaration(node);
+ // Imports and exports
+ case 221 /* ImportEqualsDeclaration */:
+ case 224 /* NamespaceImport */:
+ case 226 /* ImportSpecifier */:
+ case 230 /* ExportSpecifier */:
+ return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
+ case 223 /* ImportClause */:
+ return bindImportClause(node);
+ case 228 /* ExportDeclaration */:
+ return bindExportDeclaration(node);
+ case 227 /* ExportAssignment */:
+ return bindExportAssignment(node);
+ case 248 /* SourceFile */:
+ return bindSourceFileIfExternalModule();
+ }
+ }
+ function bindSourceFileIfExternalModule() {
+ setExportContextFlag(file);
+ if (ts.isExternalModule(file)) {
+ bindSourceFileAsExternalModule();
+ }
+ }
+ function bindSourceFileAsExternalModule() {
+ bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
+ }
+ function bindExportAssignment(node) {
+ var boundExpression = node.kind === 227 /* ExportAssignment */ ? node.expression : node.right;
+ if (!container.symbol || !container.symbol.exports) {
+ // Export assignment in some sort of block construct
+ bindAnonymousDeclaration(node, 8388608 /* Alias */, getDeclarationName(node));
+ }
+ else if (boundExpression.kind === 69 /* Identifier */) {
+ // An export default clause with an identifier exports all meanings of that identifier
+ declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
+ }
+ else {
+ // An export default clause with an expression exports a value
+ declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
+ }
+ }
+ function bindExportDeclaration(node) {
+ if (!container.symbol || !container.symbol.exports) {
+ // Export * in some sort of block construct
+ bindAnonymousDeclaration(node, 1073741824 /* ExportStar */, getDeclarationName(node));
+ }
+ else if (!node.exportClause) {
+ // All export * declarations are collected in an __export symbol
+ declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0 /* None */);
}
- var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
- var finalLength = changeRange.newLength + (changeRange.span.start - start);
- return ts.createTextChangeRange(finalSpan, finalLength);
}
- function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
- var bestResult = sourceFile;
- var lastNodeEntirelyBeforePosition;
- forEachChild(sourceFile, visit);
- if (lastNodeEntirelyBeforePosition) {
- var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition);
- if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
- bestResult = lastChildOfLastEntireNodeBeforePosition;
+ function bindImportClause(node) {
+ if (node.name) {
+ declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
+ }
+ }
+ function setCommonJsModuleIndicator(node) {
+ if (!file.commonJsModuleIndicator) {
+ file.commonJsModuleIndicator = node;
+ bindSourceFileAsExternalModule();
+ }
+ }
+ function bindExportsPropertyAssignment(node) {
+ // When we create a property via 'exports.foo = bar', the 'exports.foo' property access
+ // expression is the declaration
+ setCommonJsModuleIndicator(node);
+ declareSymbol(file.symbol.exports, file.symbol, node.left, 4 /* Property */ | 7340032 /* Export */, 0 /* None */);
+ }
+ function bindModuleExportsAssignment(node) {
+ // 'module.exports = expr' assignment
+ setCommonJsModuleIndicator(node);
+ bindExportAssignment(node);
+ }
+ function bindCallExpression(node) {
+ // We're only inspecting call expressions to detect CommonJS modules, so we can skip
+ // this check if we've already seen the module indicator
+ if (!file.commonJsModuleIndicator && ts.isRequireCall(node)) {
+ setCommonJsModuleIndicator(node);
+ }
+ }
+ function bindClassLikeDeclaration(node) {
+ if (node.kind === 214 /* ClassDeclaration */) {
+ bindBlockScopedDeclaration(node, 32 /* Class */, 899519 /* ClassExcludes */);
+ }
+ else {
+ var bindingName = node.name ? node.name.text : "__class";
+ bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
+ // Add name of class expression into the map for semantic classifier
+ if (node.name) {
+ classifiableNames[node.name.text] = node.name.text;
}
}
- return bestResult;
- function getLastChild(node) {
- while (true) {
- var lastChild = getLastChildWorker(node);
- if (lastChild) {
- node = lastChild;
- }
- else {
- return node;
- }
+ var symbol = node.symbol;
+ // TypeScript 1.0 spec (April 2014): 8.4
+ // Every class automatically contains a static property member named 'prototype', the
+ // type of which is an instantiation of the class type with type Any supplied as a type
+ // argument for each type parameter. It is an error to explicitly declare a static
+ // property member with the name 'prototype'.
+ //
+ // Note: we check for this here because this class may be merging into a module. The
+ // module might have an exported variable called 'prototype'. We can't allow that as
+ // that would clash with the built-in 'prototype' for the class.
+ var prototypeSymbol = createSymbol(4 /* Property */ | 134217728 /* Prototype */, "prototype");
+ if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) {
+ if (node.name) {
+ node.name.parent = node;
}
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
}
- function getLastChildWorker(node) {
- var last = undefined;
- forEachChild(node, function (child) {
- if (ts.nodeIsPresent(child)) {
- last = child;
- }
- });
- return last;
+ symbol.exports[prototypeSymbol.name] = prototypeSymbol;
+ prototypeSymbol.parent = symbol;
+ }
+ function bindEnumDeclaration(node) {
+ return ts.isConst(node)
+ ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */)
+ : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */);
+ }
+ function bindVariableDeclarationOrBindingElement(node) {
+ if (inStrictMode) {
+ checkStrictModeEvalOrArguments(node, node.name);
}
- function visit(child) {
- if (ts.nodeIsMissing(child)) {
- // Missing nodes are effectively invisible to us. We never even consider them
- // When trying to find the nearest node before us.
- return;
+ if (!ts.isBindingPattern(node.name)) {
+ if (ts.isBlockOrCatchScoped(node)) {
+ bindBlockScopedVariableDeclaration(node);
}
- // If the child intersects this position, then this node is currently the nearest
- // node that starts before the position.
- if (child.pos <= position) {
- if (child.pos >= bestResult.pos) {
- // This node starts before the position, and is closer to the position than
- // the previous best node we found. It is now the new best node.
- bestResult = child;
- }
- // Now, the node may overlap the position, or it may end entirely before the
- // position. If it overlaps with the position, then either it, or one of its
- // children must be the nearest node before the position. So we can just
- // recurse into this child to see if we can find something better.
- if (position < child.end) {
- // The nearest node is either this child, or one of the children inside
- // of it. We've already marked this child as the best so far. Recurse
- // in case one of the children is better.
- forEachChild(child, visit);
- // Once we look at the children of this node, then there's no need to
- // continue any further.
- return true;
- }
- else {
- ts.Debug.assert(child.end <= position);
- // The child ends entirely before this position. Say you have the following
- // (where $ is the position)
- //
- // ? $ : <...> <...>
- //
- // We would want to find the nearest preceding node in "complex expr 2".
- // To support that, we keep track of this node, and once we're done searching
- // for a best node, we recurse down this node to see if we can find a good
- // result in it.
- //
- // This approach allows us to quickly skip over nodes that are entirely
- // before the position, while still allowing us to find any nodes in the
- // last one that might be what we want.
- lastNodeEntirelyBeforePosition = child;
- }
+ else if (ts.isParameterDeclaration(node)) {
+ // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
+ // because its parent chain has already been set up, since parents are set before descending into children.
+ //
+ // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
+ // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
+ // For example:
+ // function foo([a,a]) {} // Duplicate Identifier error
+ // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
+ // // which correctly set excluded symbols
+ declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
}
else {
- ts.Debug.assert(child.pos > position);
- // We're now at a node that is entirely past the position we're searching for.
- // This node (and all following nodes) could never contribute to the result,
- // so just skip them by returning 'true' here.
- return true;
+ declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */);
}
}
}
- function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
- var oldText = sourceFile.text;
- if (textChangeRange) {
- ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
- if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
- var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
- var newTextPrefix = newText.substr(0, textChangeRange.span.start);
- ts.Debug.assert(oldTextPrefix === newTextPrefix);
- var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
- var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
- ts.Debug.assert(oldTextSuffix === newTextSuffix);
- }
+ function bindParameter(node) {
+ if (inStrictMode) {
+ // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
+ // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
+ checkStrictModeEvalOrArguments(node, node.name);
+ }
+ if (ts.isBindingPattern(node.name)) {
+ bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, getDestructuringParameterName(node));
+ }
+ else {
+ declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */);
+ }
+ // If this is a property-parameter, then also declare the property symbol into the
+ // containing class.
+ if (node.flags & 56 /* AccessibilityModifier */ &&
+ node.parent.kind === 144 /* Constructor */ &&
+ ts.isClassLike(node.parent.parent)) {
+ var classDeclaration = node.parent.parent;
+ declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */);
}
}
- function createSyntaxCursor(sourceFile) {
- var currentArray = sourceFile.statements;
- var currentArrayIndex = 0;
- ts.Debug.assert(currentArrayIndex < currentArray.length);
- var current = currentArray[currentArrayIndex];
- var lastQueriedPosition = -1 /* Value */;
- return {
- currentNode: function (position) {
- // Only compute the current node if the position is different than the last time
- // we were asked. The parser commonly asks for the node at the same position
- // twice. Once to know if can read an appropriate list element at a certain point,
- // and then to actually read and consume the node.
- if (position !== lastQueriedPosition) {
- // Much of the time the parser will need the very next node in the array that
- // we just returned a node from.So just simply check for that case and move
- // forward in the array instead of searching for the node again.
- if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
- currentArrayIndex++;
- current = currentArray[currentArrayIndex];
- }
- // If we don't have a node, or the node we have isn't in the right position,
- // then try to find a viable node at the position requested.
- if (!current || current.pos !== position) {
- findHighestListElementThatStartsAtPosition(position);
- }
- }
- // Cache this query so that we don't do any extra work if the parser calls back
- // into us. Note: this is very common as the parser will make pairs of calls like
- // 'isListElement -> parseListElement'. If we were unable to find a node when
- // called with 'isListElement', we don't want to redo the work when parseListElement
- // is called immediately after.
- lastQueriedPosition = position;
- // Either we don'd have a node, or we have a node at the position being asked for.
- ts.Debug.assert(!current || current.pos === position);
- return current;
- }
- };
- // Finds the highest element in the tree we can find that starts at the provided position.
- // The element must be a direct child of some node list in the tree. This way after we
- // return it, we can easily return its next sibling in the list.
- function findHighestListElementThatStartsAtPosition(position) {
- // Clear out any cached state about the last node we found.
- currentArray = undefined;
- currentArrayIndex = -1 /* Value */;
- current = undefined;
- // Recurse into the source file to find the highest node at this position.
- forEachChild(sourceFile, visitNode, visitArray);
- return;
- function visitNode(node) {
- if (position >= node.pos && position < node.end) {
- // Position was within this node. Keep searching deeper to find the node.
- forEachChild(node, visitNode, visitArray);
- // don't procede any futher in the search.
- return true;
- }
- // position wasn't in this node, have to keep searching.
- return false;
+ function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
+ return ts.hasDynamicName(node)
+ ? bindAnonymousDeclaration(node, symbolFlags, "__computed")
+ : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
+ }
+ // reachability checks
+ function pushNamedLabel(name) {
+ initializeReachabilityStateIfNecessary();
+ if (ts.hasProperty(labelIndexMap, name.text)) {
+ return false;
+ }
+ labelIndexMap[name.text] = labelStack.push(1 /* Unintialized */) - 1;
+ return true;
+ }
+ function pushImplicitLabel() {
+ initializeReachabilityStateIfNecessary();
+ var index = labelStack.push(1 /* Unintialized */) - 1;
+ implicitLabels.push(index);
+ return index;
+ }
+ function popNamedLabel(label, outerState) {
+ var index = labelIndexMap[label.text];
+ ts.Debug.assert(index !== undefined);
+ ts.Debug.assert(labelStack.length == index + 1);
+ labelIndexMap[label.text] = undefined;
+ setCurrentStateAtLabel(labelStack.pop(), outerState, label);
+ }
+ function popImplicitLabel(implicitLabelIndex, outerState) {
+ if (labelStack.length !== implicitLabelIndex + 1) {
+ ts.Debug.assert(false, "Label stack: " + labelStack.length + ", index:" + implicitLabelIndex);
+ }
+ var i = implicitLabels.pop();
+ if (implicitLabelIndex !== i) {
+ ts.Debug.assert(false, "i: " + i + ", index: " + implicitLabelIndex);
+ }
+ setCurrentStateAtLabel(labelStack.pop(), outerState, /*name*/ undefined);
+ }
+ function setCurrentStateAtLabel(innerMergedState, outerState, label) {
+ if (innerMergedState === 1 /* Unintialized */) {
+ if (label && !options.allowUnusedLabels) {
+ file.bindDiagnostics.push(ts.createDiagnosticForNode(label, ts.Diagnostics.Unused_label));
}
- function visitArray(array) {
- if (position >= array.pos && position < array.end) {
- // position was in this array. Search through this array to see if we find a
- // viable element.
- for (var i = 0, n = array.length; i < n; i++) {
- var child = array[i];
- if (child) {
- if (child.pos === position) {
- // Found the right node. We're done.
- currentArray = array;
- currentArrayIndex = i;
- current = child;
- return true;
- }
- else {
- if (child.pos < position && position < child.end) {
- // Position in somewhere within this child. Search in it and
- // stop searching in this array.
- forEachChild(child, visitNode, visitArray);
- return true;
- }
- }
- }
+ currentReachabilityState = outerState;
+ }
+ else {
+ currentReachabilityState = or(innerMergedState, outerState);
+ }
+ }
+ function jumpToLabel(label, outerState) {
+ initializeReachabilityStateIfNecessary();
+ var index = label ? labelIndexMap[label.text] : ts.lastOrUndefined(implicitLabels);
+ if (index === undefined) {
+ // reference to unknown label or
+ // break/continue used outside of loops
+ return false;
+ }
+ var stateAtLabel = labelStack[index];
+ labelStack[index] = stateAtLabel === 1 /* Unintialized */ ? outerState : or(stateAtLabel, outerState);
+ return true;
+ }
+ function checkUnreachable(node) {
+ switch (currentReachabilityState) {
+ case 4 /* Unreachable */:
+ var reportError =
+ // report error on all statements except empty ones
+ (ts.isStatement(node) && node.kind !== 194 /* EmptyStatement */) ||
+ // report error on class declarations
+ node.kind === 214 /* ClassDeclaration */ ||
+ // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
+ (node.kind === 218 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node)) ||
+ // report error on regular enums and const enums if preserveConstEnums is set
+ (node.kind === 217 /* EnumDeclaration */ && (!ts.isConstEnumDeclaration(node) || options.preserveConstEnums));
+ if (reportError) {
+ currentReachabilityState = 8 /* ReportedUnreachable */;
+ // unreachable code is reported if
+ // - user has explicitly asked about it AND
+ // - statement is in not ambient context (statements in ambient context is already an error
+ // so we should not report extras) AND
+ // - node is not variable statement OR
+ // - node is block scoped variable statement OR
+ // - node is not block scoped variable statement and at least one variable declaration has initializer
+ // Rationale: we don't want to report errors on non-initialized var's since they are hoisted
+ // On the other side we do want to report errors on non-initialized 'lets' because of TDZ
+ var reportUnreachableCode = !options.allowUnreachableCode &&
+ !ts.isInAmbientContext(node) &&
+ (node.kind !== 193 /* VariableStatement */ ||
+ ts.getCombinedNodeFlags(node.declarationList) & 24576 /* BlockScoped */ ||
+ ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
+ if (reportUnreachableCode) {
+ errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
}
}
- // position wasn't in this array, have to keep searching.
+ case 8 /* ReportedUnreachable */:
+ return true;
+ default:
return false;
- }
+ }
+ function shouldReportErrorOnModuleDeclaration(node) {
+ var instanceState = getModuleInstanceState(node);
+ return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && options.preserveConstEnums);
}
}
- var InvalidPosition;
- (function (InvalidPosition) {
- InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
- })(InvalidPosition || (InvalidPosition = {}));
- })(IncrementalParser || (IncrementalParser = {}));
+ function initializeReachabilityStateIfNecessary() {
+ if (labelIndexMap) {
+ return;
+ }
+ currentReachabilityState = 2 /* Reachable */;
+ labelIndexMap = {};
+ labelStack = [];
+ implicitLabels = [];
+ }
+ }
})(ts || (ts = {}));
///
/* @internal */
@@ -13755,7 +13918,7 @@ var ts;
symbolToString: symbolToString,
getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
getRootSymbols: getRootSymbols,
- getContextualType: getContextualType,
+ getContextualType: getApparentTypeOfContextualType,
getFullyQualifiedName: getFullyQualifiedName,
getResolvedSignature: getResolvedSignature,
getConstantValue: getConstantValue,
@@ -14025,7 +14188,7 @@ var ts;
return ts.getAncestor(node, 248 /* SourceFile */);
}
function isGlobalSourceFile(node) {
- return node.kind === 248 /* SourceFile */ && !ts.isExternalModule(node);
+ return node.kind === 248 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node);
}
function getSymbol(symbols, name, meaning) {
if (meaning && ts.hasProperty(symbols, name)) {
@@ -14127,15 +14290,24 @@ var ts;
}
switch (location.kind) {
case 248 /* SourceFile */:
- if (!ts.isExternalModule(location))
+ if (!ts.isExternalOrCommonJsModule(location))
break;
case 218 /* ModuleDeclaration */:
var moduleExports = getSymbolOfNode(location).exports;
if (location.kind === 248 /* SourceFile */ ||
(location.kind === 218 /* ModuleDeclaration */ && location.name.kind === 9 /* StringLiteral */)) {
- // It's an external module. Because of module/namespace merging, a module's exports are in scope,
- // yet we never want to treat an export specifier as putting a member in scope. Therefore,
- // if the name we find is purely an export specifier, it is not actually considered in scope.
+ // It's an external module. First see if the module has an export default and if the local
+ // name of that export default matches.
+ if (result = moduleExports["default"]) {
+ var localSymbol = ts.getLocalSymbolForExportDefault(result);
+ if (localSymbol && (result.flags & meaning) && localSymbol.name === name) {
+ break loop;
+ }
+ result = undefined;
+ }
+ // Because of module/namespace merging, a module's exports are in scope,
+ // yet we never want to treat an export specifier as putting a member in scope.
+ // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
// Two things to note about this:
// 1. We have to check this without calling getSymbol. The problem with calling getSymbol
// on an export specifier is that it might find the export specifier itself, and try to
@@ -14149,12 +14321,6 @@ var ts;
ts.getDeclarationOfKind(moduleExports[name], 230 /* ExportSpecifier */)) {
break;
}
- result = moduleExports["default"];
- var localSymbol = ts.getLocalSymbolForExportDefault(result);
- if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
- break loop;
- }
- result = undefined;
}
if (result = getSymbol(moduleExports, name, meaning & 8914931 /* ModuleMember */)) {
break loop;
@@ -14297,7 +14463,7 @@ var ts;
// declare module foo {
// interface bar {}
// }
- // let foo/*1*/: foo/*2*/.bar;
+ // const foo/*1*/: foo/*2*/.bar;
// The foo at /*1*/ and /*2*/ will share same symbol with two meaning
// block - scope variable and namespace module. However, only when we
// try to resolve name in /*1*/ which is used in variable position,
@@ -14601,6 +14767,9 @@ var ts;
if (moduleName === undefined) {
return;
}
+ if (moduleName.indexOf("!") >= 0) {
+ moduleName = moduleName.substr(0, moduleName.indexOf("!"));
+ }
var isRelative = ts.isExternalModuleNameRelative(moduleName);
if (!isRelative) {
var symbol = getSymbol(globals, "\"" + moduleName + "\"", 512 /* ValueModule */);
@@ -14788,7 +14957,7 @@ var ts;
}
switch (location_1.kind) {
case 248 /* SourceFile */:
- if (!ts.isExternalModule(location_1)) {
+ if (!ts.isExternalOrCommonJsModule(location_1)) {
break;
}
case 218 /* ModuleDeclaration */:
@@ -14910,7 +15079,7 @@ var ts;
// export class c {
// }
// }
- // let x: typeof m.c
+ // const x: typeof m.c
// In the above example when we start with checking if typeof m.c symbol is accessible,
// we are going to see if c can be accessed in scope directly.
// But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
@@ -14949,7 +15118,7 @@ var ts;
}
function hasExternalModuleSymbol(declaration) {
return (declaration.kind === 218 /* ModuleDeclaration */ && declaration.name.kind === 9 /* StringLiteral */) ||
- (declaration.kind === 248 /* SourceFile */ && ts.isExternalModule(declaration));
+ (declaration.kind === 248 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
}
function hasVisibleDeclarations(symbol) {
var aliasesToMakeVisible;
@@ -15100,7 +15269,7 @@ var ts;
parentSymbol = symbol;
appendSymbolNameOnly(symbol, writer);
}
- // Let the writer know we just wrote out a symbol. The declaration emitter writer uses
+ // const the writer know we just wrote out a symbol. The declaration emitter writer uses
// this to determine if an import it has previously seen (and not written out) needs
// to be written to the file once the walk of the tree is complete.
//
@@ -15181,7 +15350,7 @@ var ts;
writeAnonymousType(type, flags);
}
else if (type.flags & 256 /* StringLiteral */) {
- writer.writeStringLiteral(type.text);
+ writer.writeStringLiteral("\"" + ts.escapeString(type.text) + "\"");
}
else {
// Should never get here
@@ -15568,7 +15737,7 @@ var ts;
}
}
else if (node.kind === 248 /* SourceFile */) {
- return ts.isExternalModule(node) ? node : undefined;
+ return ts.isExternalOrCommonJsModule(node) ? node : undefined;
}
}
ts.Debug.fail("getContainingModule cant reach here");
@@ -15650,7 +15819,7 @@ var ts;
// Private/protected properties/methods are not visible
return false;
}
- // Public properties/methods are visible if its parents are visible, so let it fall into next case statement
+ // Public properties/methods are visible if its parents are visible, so const it fall into next case statement
case 144 /* Constructor */:
case 148 /* ConstructSignature */:
case 147 /* CallSignature */:
@@ -15678,7 +15847,7 @@ var ts;
// Source file is always visible
case 248 /* SourceFile */:
return true;
- // Export assignements do not create name bindings outside the module
+ // Export assignments do not create name bindings outside the module
case 227 /* ExportAssignment */:
return false;
default:
@@ -15814,6 +15983,23 @@ var ts;
var symbol = getSymbolOfNode(node);
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
}
+ function getTextOfPropertyName(name) {
+ switch (name.kind) {
+ case 69 /* Identifier */:
+ return name.text;
+ case 9 /* StringLiteral */:
+ case 8 /* NumericLiteral */:
+ return name.text;
+ case 136 /* ComputedPropertyName */:
+ if (ts.isStringOrNumericLiteral(name.expression.kind)) {
+ return name.expression.text;
+ }
+ }
+ return undefined;
+ }
+ function isComputedNonLiteralName(name) {
+ return name.kind === 136 /* ComputedPropertyName */ && !ts.isStringOrNumericLiteral(name.expression.kind);
+ }
// Return the inferred type for a binding element
function getTypeForBindingElement(declaration) {
var pattern = declaration.parent;
@@ -15835,10 +16021,15 @@ var ts;
if (pattern.kind === 161 /* ObjectBindingPattern */) {
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
var name_10 = declaration.propertyName || declaration.name;
+ if (isComputedNonLiteralName(name_10)) {
+ // computed properties with non-literal names are treated as 'any'
+ return anyType;
+ }
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
// or otherwise the type of the string index signature.
- type = getTypeOfPropertyOfType(parentType, name_10.text) ||
- isNumericLiteralName(name_10.text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
+ var text = getTextOfPropertyName(name_10);
+ type = getTypeOfPropertyOfType(parentType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
getIndexTypeOfType(parentType, 0 /* String */);
if (!type) {
error(name_10, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_10));
@@ -15938,10 +16129,17 @@ var ts;
// Return the type implied by an object binding pattern
function getTypeFromObjectBindingPattern(pattern, includePatternInType) {
var members = {};
+ var hasComputedProperties = false;
ts.forEach(pattern.elements, function (e) {
- var flags = 4 /* Property */ | 67108864 /* Transient */ | (e.initializer ? 536870912 /* Optional */ : 0);
var name = e.propertyName || e.name;
- var symbol = createSymbol(flags, name.text);
+ if (isComputedNonLiteralName(name)) {
+ // do not include computed properties in the implied type
+ hasComputedProperties = true;
+ return;
+ }
+ var text = getTextOfPropertyName(name);
+ var flags = 4 /* Property */ | 67108864 /* Transient */ | (e.initializer ? 536870912 /* Optional */ : 0);
+ var symbol = createSymbol(flags, text);
symbol.type = getTypeFromBindingElement(e, includePatternInType);
symbol.bindingElement = e;
members[symbol.name] = symbol;
@@ -15950,6 +16148,9 @@ var ts;
if (includePatternInType) {
result.pattern = pattern;
}
+ if (hasComputedProperties) {
+ result.flags |= 67108864 /* ObjectLiteralPatternWithComputedProperties */;
+ }
return result;
}
// Return the type implied by an array binding pattern
@@ -16026,6 +16227,14 @@ var ts;
if (declaration.kind === 227 /* ExportAssignment */) {
return links.type = checkExpression(declaration.expression);
}
+ // Handle module.exports = expr
+ if (declaration.kind === 181 /* BinaryExpression */) {
+ return links.type = checkExpression(declaration.right);
+ }
+ // Handle exports.p = expr
+ if (declaration.kind === 166 /* PropertyAccessExpression */) {
+ return checkExpressionCached(declaration.parent.right);
+ }
// Handle variable, parameter or property
if (!pushTypeResolution(symbol, 0 /* Type */)) {
return unknownType;
@@ -16304,23 +16513,25 @@ var ts;
}
function resolveBaseTypesOfClass(type) {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
- var baseContructorType = getBaseConstructorTypeOfClass(type);
- if (!(baseContructorType.flags & 80896 /* ObjectType */)) {
+ var baseConstructorType = getBaseConstructorTypeOfClass(type);
+ if (!(baseConstructorType.flags & 80896 /* ObjectType */)) {
return;
}
var baseTypeNode = getBaseTypeNodeOfClass(type);
var baseType;
- if (baseContructorType.symbol && baseContructorType.symbol.flags & 32 /* Class */) {
- // When base constructor type is a class we know that the constructors all have the same type parameters as the
+ var originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
+ if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 /* Class */ &&
+ areAllOuterTypeParametersApplied(originalBaseType)) {
+ // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
// class and all return the instance type of the class. There is no need for further checks and we can apply the
// type arguments in the same manner as a type reference to get the same error reporting experience.
- baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseContructorType.symbol);
+ baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
}
else {
// The class derives from a "class-like" constructor function, check that we have at least one construct signature
// with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
// we check that all instantiated signatures return the same type.
- var constructors = getInstantiatedConstructorsForTypeArguments(baseContructorType, baseTypeNode.typeArguments);
+ var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments);
if (!constructors.length) {
error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
return;
@@ -16345,6 +16556,17 @@ var ts;
type.resolvedBaseTypes.push(baseType);
}
}
+ function areAllOuterTypeParametersApplied(type) {
+ // An unapplied type parameter has its symbol still the same as the matching argument symbol.
+ // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
+ var outerTypeParameters = type.outerTypeParameters;
+ if (outerTypeParameters) {
+ var last = outerTypeParameters.length - 1;
+ var typeArguments = type.typeArguments;
+ return outerTypeParameters[last].symbol !== typeArguments[last].symbol;
+ }
+ return true;
+ }
function resolveBaseTypesOfInterface(type) {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
@@ -16424,7 +16646,7 @@ var ts;
type.typeArguments = type.typeParameters;
type.thisType = createType(512 /* TypeParameter */ | 33554432 /* ThisType */);
type.thisType.symbol = symbol;
- type.thisType.constraint = getTypeWithThisArgument(type);
+ type.thisType.constraint = type;
}
}
return links.declaredType;
@@ -16939,6 +17161,20 @@ var ts;
type = getApparentType(type);
return type.flags & 49152 /* UnionOrIntersection */ ? getPropertiesOfUnionOrIntersectionType(type) : getPropertiesOfObjectType(type);
}
+ /**
+ * The apparent type of a type parameter is the base constraint instantiated with the type parameter
+ * as the type argument for the 'this' type.
+ */
+ function getApparentTypeOfTypeParameter(type) {
+ if (!type.resolvedApparentType) {
+ var constraintType = getConstraintOfTypeParameter(type);
+ while (constraintType && constraintType.flags & 512 /* TypeParameter */) {
+ constraintType = getConstraintOfTypeParameter(constraintType);
+ }
+ type.resolvedApparentType = getTypeWithThisArgument(constraintType || emptyObjectType, type);
+ }
+ return type.resolvedApparentType;
+ }
/**
* For a type parameter, return the base constraint of the type parameter. For the string, number,
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
@@ -16946,12 +17182,7 @@ var ts;
*/
function getApparentType(type) {
if (type.flags & 512 /* TypeParameter */) {
- do {
- type = getConstraintOfTypeParameter(type);
- } while (type && type.flags & 512 /* TypeParameter */);
- if (!type) {
- type = emptyObjectType;
- }
+ type = getApparentTypeOfTypeParameter(type);
}
if (type.flags & 258 /* StringLike */) {
type = globalStringType;
@@ -17116,7 +17347,7 @@ var ts;
if (node.initializer) {
var signatureDeclaration = node.parent;
var signature = getSignatureFromDeclaration(signatureDeclaration);
- var parameterIndex = signatureDeclaration.parameters.indexOf(node);
+ var parameterIndex = ts.indexOf(signatureDeclaration.parameters, node);
ts.Debug.assert(parameterIndex >= 0);
return parameterIndex >= signature.minArgumentCount;
}
@@ -17217,6 +17448,16 @@ var ts;
}
return result;
}
+ function resolveExternalModuleTypeByLiteral(name) {
+ var moduleSym = resolveExternalModuleName(name, name);
+ if (moduleSym) {
+ var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
+ if (resolvedModuleSymbol) {
+ return getTypeOfSymbol(resolvedModuleSymbol);
+ }
+ }
+ return anyType;
+ }
function getReturnTypeOfSignature(signature) {
if (!signature.resolvedReturnType) {
if (!pushTypeResolution(signature, 3 /* ResolvedReturnType */)) {
@@ -17740,11 +17981,12 @@ var ts;
return links.resolvedType;
}
function getStringLiteralType(node) {
- if (ts.hasProperty(stringLiteralTypes, node.text)) {
- return stringLiteralTypes[node.text];
+ var text = node.text;
+ if (ts.hasProperty(stringLiteralTypes, text)) {
+ return stringLiteralTypes[text];
}
- var type = stringLiteralTypes[node.text] = createType(256 /* StringLiteral */);
- type.text = ts.getTextOfNode(node);
+ var type = stringLiteralTypes[text] = createType(256 /* StringLiteral */);
+ type.text = text;
return type;
}
function getTypeFromStringLiteral(node) {
@@ -18265,7 +18507,7 @@ var ts;
return false;
}
function hasExcessProperties(source, target, reportErrors) {
- if (someConstituentTypeHasKind(target, 80896 /* ObjectType */)) {
+ if (!(target.flags & 67108864 /* ObjectLiteralPatternWithComputedProperties */) && someConstituentTypeHasKind(target, 80896 /* ObjectType */)) {
for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
var prop = _a[_i];
if (!isKnownProperty(target, prop.name)) {
@@ -18358,9 +18600,6 @@ var ts;
return result;
}
function typeParameterIdenticalTo(source, target) {
- if (source.symbol.name !== target.symbol.name) {
- return 0 /* False */;
- }
// covers case when both type parameters does not have constraint (both equal to noConstraintType)
if (source.constraint === target.constraint) {
return -1 /* True */;
@@ -18852,18 +19091,29 @@ var ts;
}
return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
}
+ function isMatchingSignature(source, target, partialMatch) {
+ // A source signature matches a target signature if the two signatures have the same number of required,
+ // optional, and rest parameters.
+ if (source.parameters.length === target.parameters.length &&
+ source.minArgumentCount === target.minArgumentCount &&
+ source.hasRestParameter === target.hasRestParameter) {
+ return true;
+ }
+ // A source signature partially matches a target signature if the target signature has no fewer required
+ // parameters and no more overall parameters than the source signature (where a signature with a rest
+ // parameter is always considered to have more overall parameters than one without).
+ if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (source.hasRestParameter && !target.hasRestParameter ||
+ source.hasRestParameter === target.hasRestParameter && source.parameters.length >= target.parameters.length)) {
+ return true;
+ }
+ return false;
+ }
function compareSignatures(source, target, partialMatch, ignoreReturnTypes, compareTypes) {
if (source === target) {
return -1 /* True */;
}
- if (source.parameters.length !== target.parameters.length ||
- source.minArgumentCount !== target.minArgumentCount ||
- source.hasRestParameter !== target.hasRestParameter) {
- if (!partialMatch ||
- source.parameters.length < target.parameters.length && !source.hasRestParameter ||
- source.minArgumentCount > target.minArgumentCount) {
- return 0 /* False */;
- }
+ if (!(isMatchingSignature(source, target, partialMatch))) {
+ return 0 /* False */;
}
var result = -1 /* True */;
if (source.typeParameters && target.typeParameters) {
@@ -18957,6 +19207,9 @@ var ts;
function isTupleLikeType(type) {
return !!getPropertyOfType(type, "0");
}
+ function isStringLiteralType(type) {
+ return type.flags & 256 /* StringLiteral */;
+ }
/**
* Check if a Type was written as a tuple type literal.
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
@@ -19629,7 +19882,7 @@ var ts;
}
function narrowTypeByInstanceof(type, expr, assumeTrue) {
// Check that type is not any, assumed result is true, and we have variable symbol on the left
- if (isTypeAny(type) || !assumeTrue || expr.left.kind !== 69 /* Identifier */ || getResolvedSymbol(expr.left) !== symbol) {
+ if (isTypeAny(type) || expr.left.kind !== 69 /* Identifier */ || getResolvedSymbol(expr.left) !== symbol) {
return type;
}
// Check that right operand is a function type with a prototype property
@@ -19660,6 +19913,12 @@ var ts;
}
}
if (targetType) {
+ if (!assumeTrue) {
+ if (type.flags & 16384 /* Union */) {
+ return getUnionType(ts.filter(type.types, function (t) { return !isTypeSubtypeOf(t, targetType); }));
+ }
+ return type;
+ }
return getNarrowedType(type, targetType);
}
return type;
@@ -20129,6 +20388,9 @@ var ts;
function getIndexTypeOfContextualType(type, kind) {
return applyToContextualType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); });
}
+ function contextualTypeIsStringLiteralType(type) {
+ return !!(type.flags & 16384 /* Union */ ? ts.forEach(type.types, isStringLiteralType) : isStringLiteralType(type));
+ }
// Return true if the given contextual type is a tuple-like type
function contextualTypeIsTupleLikeType(type) {
return !!(type.flags & 16384 /* Union */ ? ts.forEach(type.types, isTupleLikeType) : isTupleLikeType(type));
@@ -20150,7 +20412,7 @@ var ts;
}
function getContextualTypeForObjectLiteralElement(element) {
var objectLiteral = element.parent;
- var type = getContextualType(objectLiteral);
+ var type = getApparentTypeOfContextualType(objectLiteral);
if (type) {
if (!ts.hasDynamicName(element)) {
// For a (non-symbol) computed property, there is no reason to look up the name
@@ -20173,7 +20435,7 @@ var ts;
// type of T.
function getContextualTypeForElementExpression(node) {
var arrayLiteral = node.parent;
- var type = getContextualType(arrayLiteral);
+ var type = getApparentTypeOfContextualType(arrayLiteral);
if (type) {
var index = ts.indexOf(arrayLiteral.elements, node);
return getTypeOfPropertyOfContextualType(type, "" + index)
@@ -20206,11 +20468,28 @@ var ts;
}
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
- function getContextualType(node) {
- var type = getContextualTypeWorker(node);
+ function getApparentTypeOfContextualType(node) {
+ var type = getContextualType(node);
return type && getApparentType(type);
}
- function getContextualTypeWorker(node) {
+ /**
+ * Woah! Do you really want to use this function?
+ *
+ * Unless you're trying to get the *non-apparent* type for a
+ * value-literal type or you're authoring relevant portions of this algorithm,
+ * you probably meant to use 'getApparentTypeOfContextualType'.
+ * Otherwise this may not be very useful.
+ *
+ * In cases where you *are* working on this function, you should understand
+ * when it is appropriate to use 'getContextualType' and 'getApparentTypeOfContetxualType'.
+ *
+ * - Use 'getContextualType' when you are simply going to propagate the result to the expression.
+ * - Use 'getApparentTypeOfContextualType' when you're going to need the members of the type.
+ *
+ * @param node the expression whose contextual type will be returned.
+ * @returns the contextual type of an expression.
+ */
+ function getContextualType(node) {
if (isInsideWithStatementBody(node)) {
// We cannot answer semantic questions within a with block, do not proceed any further
return undefined;
@@ -20285,7 +20564,7 @@ var ts;
ts.Debug.assert(node.kind !== 143 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
var type = ts.isObjectLiteralMethod(node)
? getContextualTypeForObjectLiteralMethod(node)
- : getContextualType(node);
+ : getApparentTypeOfContextualType(node);
if (!type) {
return undefined;
}
@@ -20411,7 +20690,7 @@ var ts;
type.pattern = node;
return type;
}
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
var pattern = contextualType.pattern;
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
@@ -20494,10 +20773,11 @@ var ts;
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
var propertiesTable = {};
var propertiesArray = [];
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
var contextualTypeHasPattern = contextualType && contextualType.pattern &&
(contextualType.pattern.kind === 161 /* ObjectBindingPattern */ || contextualType.pattern.kind === 165 /* ObjectLiteralExpression */);
var typeFlags = 0;
+ var patternWithComputedProperties = false;
for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
var memberDecl = _a[_i];
var member = memberDecl.symbol;
@@ -20525,8 +20805,11 @@ var ts;
if (isOptional) {
prop.flags |= 536870912 /* Optional */;
}
+ if (ts.hasDynamicName(memberDecl)) {
+ patternWithComputedProperties = true;
+ }
}
- else if (contextualTypeHasPattern) {
+ else if (contextualTypeHasPattern && !(contextualType.flags & 67108864 /* ObjectLiteralPatternWithComputedProperties */)) {
// If object literal is contextually typed by the implied type of a binding pattern, and if the
// binding pattern specifies a default value for the property, make the property optional.
var impliedProp = getPropertyOfType(contextualType, member.name);
@@ -20578,7 +20861,7 @@ var ts;
var numberIndexType = getIndexType(1 /* Number */);
var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576 /* FreshObjectLiteral */;
- result.flags |= 524288 /* ObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */);
+ result.flags |= 524288 /* ObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */) | (patternWithComputedProperties ? 67108864 /* ObjectLiteralPatternWithComputedProperties */ : 0);
if (inDestructuringPattern) {
result.pattern = node;
}
@@ -21289,7 +21572,7 @@ var ts;
// so order how inherited signatures are processed is still preserved.
// interface A { (x: string): void }
// interface B extends A { (x: 'foo'): string }
- // let b: B;
+ // const b: B;
// b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
function reorderCandidates(signatures, result) {
var lastParent;
@@ -22247,6 +22530,10 @@ var ts;
return anyType;
}
}
+ // In JavaScript files, calls to any identifier 'require' are treated as external module imports
+ if (ts.isInJavaScriptFile(node) && ts.isRequireCall(node)) {
+ return resolveExternalModuleTypeByLiteral(node.arguments[0]);
+ }
return getReturnTypeOfSignature(signature);
}
function checkTaggedTemplateExpression(node) {
@@ -22257,7 +22544,10 @@ var ts;
var targetType = getTypeFromTypeNode(node.type);
if (produceDiagnostics && targetType !== unknownType) {
var widenedType = getWidenedType(exprType);
- if (!(isTypeAssignableTo(targetType, widenedType))) {
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ var bothAreStringLike = someConstituentTypeHasKind(targetType, 258 /* StringLike */) &&
+ someConstituentTypeHasKind(widenedType, 258 /* StringLike */);
+ if (!bothAreStringLike && !(isTypeAssignableTo(targetType, widenedType))) {
checkTypeAssignableTo(exprType, targetType, node, ts.Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
}
}
@@ -22801,19 +23091,26 @@ var ts;
for (var _i = 0, properties_3 = properties; _i < properties_3.length; _i++) {
var p = properties_3[_i];
if (p.kind === 245 /* PropertyAssignment */ || p.kind === 246 /* ShorthandPropertyAssignment */) {
- // TODO(andersh): Computed property support
var name_13 = p.name;
+ if (name_13.kind === 136 /* ComputedPropertyName */) {
+ checkComputedPropertyName(name_13);
+ }
+ if (isComputedNonLiteralName(name_13)) {
+ continue;
+ }
+ var text = getTextOfPropertyName(name_13);
var type = isTypeAny(sourceType)
? sourceType
- : getTypeOfPropertyOfType(sourceType, name_13.text) ||
- isNumericLiteralName(name_13.text) && getIndexTypeOfType(sourceType, 1 /* Number */) ||
+ : getTypeOfPropertyOfType(sourceType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(sourceType, 1 /* Number */) ||
getIndexTypeOfType(sourceType, 0 /* String */);
if (type) {
if (p.kind === 246 /* ShorthandPropertyAssignment */) {
checkDestructuringAssignment(p, type);
}
else {
- checkDestructuringAssignment(p.initializer || name_13, type);
+ // non-shorthand property assignments should always have initializers
+ checkDestructuringAssignment(p.initializer, type);
}
}
else {
@@ -23014,6 +23311,10 @@ var ts;
case 31 /* ExclamationEqualsToken */:
case 32 /* EqualsEqualsEqualsToken */:
case 33 /* ExclamationEqualsEqualsToken */:
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ if (someConstituentTypeHasKind(leftType, 258 /* StringLike */) && someConstituentTypeHasKind(rightType, 258 /* StringLike */)) {
+ return booleanType;
+ }
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
reportOperatorError();
}
@@ -23137,6 +23438,13 @@ var ts;
var type2 = checkExpression(node.whenFalse, contextualMapper);
return getUnionType([type1, type2]);
}
+ function checkStringLiteralExpression(node) {
+ var contextualType = getContextualType(node);
+ if (contextualType && contextualTypeIsStringLiteralType(contextualType)) {
+ return getStringLiteralType(node);
+ }
+ return stringType;
+ }
function checkTemplateExpression(node) {
// We just want to check each expressions, but we are unconcerned with
// the type of each expression, as any value may be coerced into a string.
@@ -23187,7 +23495,7 @@ var ts;
if (isInferentialContext(contextualMapper)) {
var signature = getSingleCallSignature(type);
if (signature && signature.typeParameters) {
- var contextualType = getContextualType(node);
+ var contextualType = getApparentTypeOfContextualType(node);
if (contextualType) {
var contextualSignature = getSingleCallSignature(contextualType);
if (contextualSignature && !contextualSignature.typeParameters) {
@@ -23251,6 +23559,7 @@ var ts;
case 183 /* TemplateExpression */:
return checkTemplateExpression(node);
case 9 /* StringLiteral */:
+ return checkStringLiteralExpression(node);
case 11 /* NoSubstitutionTemplateLiteral */:
return stringType;
case 10 /* RegularExpressionLiteral */:
@@ -24580,7 +24889,7 @@ var ts;
}
// In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
var parent = getDeclarationContainer(node);
- if (parent.kind === 248 /* SourceFile */ && ts.isExternalModule(parent)) {
+ if (parent.kind === 248 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent)) {
// If the declaration happens to be in external module, report error that require and exports are reserved keywords
error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
}
@@ -24598,15 +24907,15 @@ var ts;
// A non-initialized declaration is a no-op as the block declaration will resolve before the var
// declaration. the problem is if the declaration has an initializer. this will act as a write to the
// block declared value. this is fine for let, but not const.
- // Only consider declarations with initializers, uninitialized let declarations will not
+ // Only consider declarations with initializers, uninitialized const declarations will not
// step on a let/const variable.
- // Do not consider let and const declarations, as duplicate block-scoped declarations
+ // Do not consider const and const declarations, as duplicate block-scoped declarations
// are handled by the binder.
- // We are only looking for let declarations that step on let\const declarations from a
+ // We are only looking for const declarations that step on let\const declarations from a
// different scope. e.g.:
// {
// const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
- // let x = 0; // symbol for this declaration will be 'symbol'
+ // const x = 0; // symbol for this declaration will be 'symbol'
// }
// skip block-scoped variables and parameters
if ((ts.getCombinedNodeFlags(node) & 24576 /* BlockScoped */) !== 0 || ts.isParameterDeclaration(node)) {
@@ -24693,6 +25002,12 @@ var ts;
checkExpressionCached(node.initializer);
}
}
+ if (node.kind === 163 /* BindingElement */) {
+ // check computed properties inside property names of binding elements
+ if (node.propertyName && node.propertyName.kind === 136 /* ComputedPropertyName */) {
+ checkComputedPropertyName(node.propertyName);
+ }
+ }
// For a binding pattern, check contained binding elements
if (ts.isBindingPattern(node.name)) {
ts.forEach(node.name.elements, checkSourceElement);
@@ -25176,6 +25491,7 @@ var ts;
var firstDefaultClause;
var hasDuplicateDefaultClause = false;
var expressionType = checkExpression(node.expression);
+ var expressionTypeIsStringLike = someConstituentTypeHasKind(expressionType, 258 /* StringLike */);
ts.forEach(node.caseBlock.clauses, function (clause) {
// Grammar check for duplicate default clauses, skip if we already report duplicate default clause
if (clause.kind === 242 /* DefaultClause */ && !hasDuplicateDefaultClause) {
@@ -25195,6 +25511,10 @@ var ts;
// TypeScript 1.0 spec (April 2014):5.9
// In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression.
var caseType = checkExpression(caseClause.expression);
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ if (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, 258 /* StringLike */)) {
+ return;
+ }
if (!isTypeAssignableTo(expressionType, caseType)) {
// check 'expressionType isAssignableTo caseType' failed, try the reversed check and report errors if it fails
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
@@ -25659,11 +25979,14 @@ var ts;
var enumIsConst = ts.isConst(node);
for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
var member = _a[_i];
- if (member.name.kind === 136 /* ComputedPropertyName */) {
+ if (isComputedNonLiteralName(member.name)) {
error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
- else if (isNumericLiteralName(member.name.text)) {
- error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ else {
+ var text = getTextOfPropertyName(member.name);
+ if (isNumericLiteralName(text)) {
+ error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ }
}
var previousEnumMemberIsNonConstant = autoValue === undefined;
var initializer = member.initializer;
@@ -26305,8 +26628,8 @@ var ts;
}
// Function and class expression bodies are checked after all statements in the enclosing body. This is
// to ensure constructs like the following are permitted:
- // let foo = function () {
- // let s = foo();
+ // const foo = function () {
+ // const s = foo();
// return "hello";
// }
// Here, performing a full type check of the body of the function expression whilst in the process of
@@ -26421,8 +26744,12 @@ var ts;
if (!(links.flags & 1 /* TypeChecked */)) {
// Check whether the file has declared it is the default lib,
// and whether the user has specifically chosen to avoid checking it.
- if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) {
- return;
+ if (compilerOptions.skipDefaultLibCheck) {
+ // If the user specified '--noLib' and a file has a '/// ',
+ // then we should treat that file as a default lib.
+ if (node.hasNoDefaultLib) {
+ return;
+ }
}
// Grammar checking
checkGrammarSourceFile(node);
@@ -26432,7 +26759,7 @@ var ts;
potentialThisCollisions.length = 0;
ts.forEach(node.statements, checkSourceElement);
checkFunctionAndClassExpressionBodies(node);
- if (ts.isExternalModule(node)) {
+ if (ts.isExternalOrCommonJsModule(node)) {
checkExternalModuleExports(node);
}
if (potentialThisCollisions.length) {
@@ -26515,7 +26842,7 @@ var ts;
}
switch (location.kind) {
case 248 /* SourceFile */:
- if (!ts.isExternalModule(location)) {
+ if (!ts.isExternalOrCommonJsModule(location)) {
break;
}
case 218 /* ModuleDeclaration */:
@@ -27153,9 +27480,18 @@ var ts;
getReferencedValueDeclaration: getReferencedValueDeclaration,
getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
isOptionalParameter: isOptionalParameter,
- isArgumentsLocalBinding: isArgumentsLocalBinding
+ isArgumentsLocalBinding: isArgumentsLocalBinding,
+ getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration
};
}
+ function getExternalModuleFileFromDeclaration(declaration) {
+ var specifier = ts.getExternalModuleName(declaration);
+ var moduleSymbol = getSymbolAtLocation(specifier);
+ if (!moduleSymbol) {
+ return undefined;
+ }
+ return ts.getDeclarationOfKind(moduleSymbol, 248 /* SourceFile */);
+ }
function initializeTypeChecker() {
// Bind all source files and propagate errors
ts.forEach(host.getSourceFiles(), function (file) {
@@ -27163,11 +27499,10 @@ var ts;
});
// Initialize global symbol table
ts.forEach(host.getSourceFiles(), function (file) {
- if (!ts.isExternalModule(file)) {
+ if (!ts.isExternalOrCommonJsModule(file)) {
mergeSymbolTable(globals, file.locals);
}
});
- // Initialize special symbols
getSymbolLinks(undefinedSymbol).type = undefinedType;
getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments");
getSymbolLinks(unknownSymbol).type = unknownType;
@@ -27866,7 +28201,7 @@ var ts;
}
}
function checkGrammarForNonSymbolComputedProperty(node, message) {
- if (node.kind === 136 /* ComputedPropertyName */ && !ts.isWellKnownSymbolSyntactically(node.expression)) {
+ if (ts.isDynamicName(node)) {
return grammarErrorOnNode(node, message);
}
}
@@ -28225,11 +28560,15 @@ var ts;
var writeTextOfNode;
var writer = createAndSetNewTextWriterWithSymbolWriter();
var enclosingDeclaration;
- var currentSourceFile;
+ var currentText;
+ var currentLineMap;
+ var currentIdentifiers;
+ var isCurrentFileExternalModule;
var reportedDeclarationError = false;
var errorNameNode;
var emitJsDocComments = compilerOptions.removeComments ? function (declaration) { } : writeJsDocComments;
var emit = compilerOptions.stripInternal ? stripInternal : emitNode;
+ var noDeclare = !root;
var moduleElementDeclarationEmitInfo = [];
var asynchronousSubModuleDeclarationEmitInfo;
// Contains the reference paths that needs to go in the declaration file.
@@ -28272,23 +28611,56 @@ var ts;
else {
// Emit references corresponding to this file
var emittedReferencedFiles = [];
+ var prevModuleElementDeclarationEmitInfo = [];
ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
+ if (!ts.isDeclarationFile(sourceFile)) {
// Check what references need to be added
if (!compilerOptions.noResolve) {
ts.forEach(sourceFile.referencedFiles, function (fileReference) {
var referencedFile = ts.tryResolveScriptReference(host, sourceFile, fileReference);
- // If the reference file is a declaration file or an external module, emit that reference
- if (referencedFile && (ts.isExternalModuleOrDeclarationFile(referencedFile) &&
+ // If the reference file is a declaration file, emit that reference
+ if (referencedFile && (ts.isDeclarationFile(referencedFile) &&
!ts.contains(emittedReferencedFiles, referencedFile))) {
writeReferencePath(referencedFile);
emittedReferencedFiles.push(referencedFile);
}
});
}
+ }
+ if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
+ noDeclare = false;
+ emitSourceFile(sourceFile);
+ }
+ else if (ts.isExternalModule(sourceFile)) {
+ noDeclare = true;
+ write("declare module \"" + ts.getResolvedExternalModuleName(host, sourceFile) + "\" {");
+ writeLine();
+ increaseIndent();
emitSourceFile(sourceFile);
+ decreaseIndent();
+ write("}");
+ writeLine();
+ // create asynchronous output for the importDeclarations
+ if (moduleElementDeclarationEmitInfo.length) {
+ var oldWriter = writer;
+ ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) {
+ if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
+ ts.Debug.assert(aliasEmitInfo.node.kind === 222 /* ImportDeclaration */);
+ createAndSetNewTextWriterWithSymbolWriter();
+ ts.Debug.assert(aliasEmitInfo.indent === 1);
+ increaseIndent();
+ writeImportDeclaration(aliasEmitInfo.node);
+ aliasEmitInfo.asynchronousOutput = writer.getText();
+ decreaseIndent();
+ }
+ });
+ setWriter(oldWriter);
+ }
+ prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
+ moduleElementDeclarationEmitInfo = [];
}
});
+ moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo);
}
return {
reportedDeclarationError: reportedDeclarationError,
@@ -28297,13 +28669,12 @@ var ts;
referencePathsOutput: referencePathsOutput
};
function hasInternalAnnotation(range) {
- var text = currentSourceFile.text;
- var comment = text.substring(range.pos, range.end);
+ var comment = currentText.substring(range.pos, range.end);
return comment.indexOf("@internal") >= 0;
}
function stripInternal(node) {
if (node) {
- var leadingCommentRanges = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
+ var leadingCommentRanges = ts.getLeadingCommentRanges(currentText, node.pos);
if (ts.forEach(leadingCommentRanges, hasInternalAnnotation)) {
return;
}
@@ -28395,7 +28766,7 @@ var ts;
var errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
if (errorInfo) {
if (errorInfo.typeName) {
- diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
+ diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNodeFromSourceText(currentText, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
}
else {
diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
@@ -28461,10 +28832,10 @@ var ts;
}
function writeJsDocComments(declaration) {
if (declaration) {
- var jsDocComments = ts.getJsDocComments(declaration, currentSourceFile);
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, declaration, jsDocComments);
+ var jsDocComments = ts.getJsDocCommentsFromText(declaration, currentText);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
// jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
- ts.emitComments(currentSourceFile, writer, jsDocComments, /*trailingSeparator*/ true, newLine, ts.writeCommentRange);
+ ts.emitComments(currentText, currentLineMap, writer, jsDocComments, /*trailingSeparator*/ true, newLine, ts.writeCommentRange);
}
}
function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type, getSymbolAccessibilityDiagnostic) {
@@ -28481,7 +28852,7 @@ var ts;
case 103 /* VoidKeyword */:
case 97 /* ThisKeyword */:
case 9 /* StringLiteral */:
- return writeTextOfNode(currentSourceFile, type);
+ return writeTextOfNode(currentText, type);
case 188 /* ExpressionWithTypeArguments */:
return emitExpressionWithTypeArguments(type);
case 151 /* TypeReference */:
@@ -28512,14 +28883,14 @@ var ts;
}
function writeEntityName(entityName) {
if (entityName.kind === 69 /* Identifier */) {
- writeTextOfNode(currentSourceFile, entityName);
+ writeTextOfNode(currentText, entityName);
}
else {
var left = entityName.kind === 135 /* QualifiedName */ ? entityName.left : entityName.expression;
var right = entityName.kind === 135 /* QualifiedName */ ? entityName.right : entityName.name;
writeEntityName(left);
write(".");
- writeTextOfNode(currentSourceFile, right);
+ writeTextOfNode(currentText, right);
}
}
function emitEntityName(entityName) {
@@ -28549,7 +28920,7 @@ var ts;
}
}
function emitTypePredicate(type) {
- writeTextOfNode(currentSourceFile, type.parameterName);
+ writeTextOfNode(currentText, type.parameterName);
write(" is ");
emitType(type.type);
}
@@ -28590,9 +28961,12 @@ var ts;
}
}
function emitSourceFile(node) {
- currentSourceFile = node;
+ currentText = node.text;
+ currentLineMap = ts.getLineStarts(node);
+ currentIdentifiers = node.identifiers;
+ isCurrentFileExternalModule = ts.isExternalModule(node);
enclosingDeclaration = node;
- ts.emitDetachedComments(currentSourceFile, writer, ts.writeCommentRange, node, newLine, true /* remove comments */);
+ ts.emitDetachedComments(currentText, currentLineMap, writer, ts.writeCommentRange, node, newLine, true /* remove comments */);
emitLines(node.statements);
}
// Return a temp variable name to be used in `export default` statements.
@@ -28601,13 +28975,13 @@ var ts;
// do not need to keep track of created temp names.
function getExportDefaultTempVariableName() {
var baseName = "_default";
- if (!ts.hasProperty(currentSourceFile.identifiers, baseName)) {
+ if (!ts.hasProperty(currentIdentifiers, baseName)) {
return baseName;
}
var count = 0;
while (true) {
var name_18 = baseName + "_" + (++count);
- if (!ts.hasProperty(currentSourceFile.identifiers, name_18)) {
+ if (!ts.hasProperty(currentIdentifiers, name_18)) {
return name_18;
}
}
@@ -28615,7 +28989,7 @@ var ts;
function emitExportAssignment(node) {
if (node.expression.kind === 69 /* Identifier */) {
write(node.isExportEquals ? "export = " : "export default ");
- writeTextOfNode(currentSourceFile, node.expression);
+ writeTextOfNode(currentText, node.expression);
}
else {
// Expression
@@ -28653,7 +29027,7 @@ var ts;
writeModuleElement(node);
}
else if (node.kind === 221 /* ImportEqualsDeclaration */ ||
- (node.parent.kind === 248 /* SourceFile */ && ts.isExternalModule(currentSourceFile))) {
+ (node.parent.kind === 248 /* SourceFile */ && isCurrentFileExternalModule)) {
var isVisible;
if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== 248 /* SourceFile */) {
// Import declaration of another module that is visited async so lets put it in right spot
@@ -28707,7 +29081,7 @@ var ts;
}
function emitModuleElementDeclarationFlags(node) {
// If the node is parented in the current source file we need to emit export declare or just export
- if (node.parent === currentSourceFile) {
+ if (node.parent.kind === 248 /* SourceFile */) {
// If the node is exported
if (node.flags & 2 /* Export */) {
write("export ");
@@ -28715,7 +29089,7 @@ var ts;
if (node.flags & 512 /* Default */) {
write("default ");
}
- else if (node.kind !== 215 /* InterfaceDeclaration */) {
+ else if (node.kind !== 215 /* InterfaceDeclaration */ && !noDeclare) {
write("declare ");
}
}
@@ -28742,7 +29116,7 @@ var ts;
write("export ");
}
write("import ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
write(" = ");
if (ts.isInternalModuleImportEqualsDeclaration(node)) {
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError);
@@ -28750,7 +29124,7 @@ var ts;
}
else {
write("require(");
- writeTextOfNode(currentSourceFile, ts.getExternalModuleImportEqualsDeclarationExpression(node));
+ writeTextOfNode(currentText, ts.getExternalModuleImportEqualsDeclarationExpression(node));
write(");");
}
writer.writeLine();
@@ -28785,7 +29159,7 @@ var ts;
if (node.importClause) {
var currentWriterPos = writer.getTextPos();
if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
- writeTextOfNode(currentSourceFile, node.importClause.name);
+ writeTextOfNode(currentText, node.importClause.name);
}
if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
if (currentWriterPos !== writer.getTextPos()) {
@@ -28794,7 +29168,7 @@ var ts;
}
if (node.importClause.namedBindings.kind === 224 /* NamespaceImport */) {
write("* as ");
- writeTextOfNode(currentSourceFile, node.importClause.namedBindings.name);
+ writeTextOfNode(currentText, node.importClause.namedBindings.name);
}
else {
write("{ ");
@@ -28804,16 +29178,28 @@ var ts;
}
write(" from ");
}
- writeTextOfNode(currentSourceFile, node.moduleSpecifier);
+ emitExternalModuleSpecifier(node.moduleSpecifier);
write(";");
writer.writeLine();
}
+ function emitExternalModuleSpecifier(moduleSpecifier) {
+ if (moduleSpecifier.kind === 9 /* StringLiteral */ && (!root) && (compilerOptions.out || compilerOptions.outFile)) {
+ var moduleName = ts.getExternalModuleNameFromDeclaration(host, resolver, moduleSpecifier.parent);
+ if (moduleName) {
+ write("\"");
+ write(moduleName);
+ write("\"");
+ return;
+ }
+ }
+ writeTextOfNode(currentText, moduleSpecifier);
+ }
function emitImportOrExportSpecifier(node) {
if (node.propertyName) {
- writeTextOfNode(currentSourceFile, node.propertyName);
+ writeTextOfNode(currentText, node.propertyName);
write(" as ");
}
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
function emitExportSpecifier(node) {
emitImportOrExportSpecifier(node);
@@ -28835,7 +29221,7 @@ var ts;
}
if (node.moduleSpecifier) {
write(" from ");
- writeTextOfNode(currentSourceFile, node.moduleSpecifier);
+ emitExternalModuleSpecifier(node.moduleSpecifier);
}
write(";");
writer.writeLine();
@@ -28849,11 +29235,11 @@ var ts;
else {
write("module ");
}
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
while (node.body.kind !== 219 /* ModuleBlock */) {
node = node.body;
write(".");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
@@ -28872,7 +29258,7 @@ var ts;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("type ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
emitTypeParameters(node.typeParameters);
write(" = ");
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
@@ -28894,7 +29280,7 @@ var ts;
write("const ");
}
write("enum ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
write(" {");
writeLine();
increaseIndent();
@@ -28905,7 +29291,7 @@ var ts;
}
function emitEnumMemberDeclaration(node) {
emitJsDocComments(node);
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var enumMemberValue = resolver.getConstantValue(node);
if (enumMemberValue !== undefined) {
write(" = ");
@@ -28922,7 +29308,7 @@ var ts;
increaseIndent();
emitJsDocComments(node);
decreaseIndent();
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
// If there is constraint present and this is not a type parameter of the private method emit the constraint
if (node.constraint && !isPrivateMethodTypeParameter(node)) {
write(" extends ");
@@ -29037,7 +29423,7 @@ var ts;
write("abstract ");
}
write("class ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitTypeParameters(node.typeParameters);
@@ -29060,7 +29446,7 @@ var ts;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("interface ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
var prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitTypeParameters(node.typeParameters);
@@ -29095,7 +29481,7 @@ var ts;
// If this node is a computed name, it can only be a symbol, because we've already skipped
// it if it's not a well known symbol. In that case, the text of the name will be exactly
// what we want, namely the name expression enclosed in brackets.
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
// If optional property emit ?
if ((node.kind === 141 /* PropertyDeclaration */ || node.kind === 140 /* PropertySignature */) && ts.hasQuestionToken(node)) {
write("?");
@@ -29177,7 +29563,7 @@ var ts;
emitBindingPattern(bindingElement.name);
}
else {
- writeTextOfNode(currentSourceFile, bindingElement.name);
+ writeTextOfNode(currentText, bindingElement.name);
writeTypeOfDeclaration(bindingElement, /*type*/ undefined, getBindingElementTypeVisibilityError);
}
}
@@ -29221,7 +29607,7 @@ var ts;
emitJsDocComments(accessors.getAccessor);
emitJsDocComments(accessors.setAccessor);
emitClassMemberDeclarationFlags(node);
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (!(node.flags & 16 /* Private */)) {
accessorWithTypeAnnotation = node;
var type = getTypeAnnotationFromAccessor(node);
@@ -29307,13 +29693,13 @@ var ts;
}
if (node.kind === 213 /* FunctionDeclaration */) {
write("function ");
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
else if (node.kind === 144 /* Constructor */) {
write("constructor");
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
if (ts.hasQuestionToken(node)) {
write("?");
}
@@ -29437,7 +29823,7 @@ var ts;
emitBindingPattern(node.name);
}
else {
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
}
if (resolver.isOptionalParameter(node)) {
write("?");
@@ -29552,7 +29938,7 @@ var ts;
// Example:
// original: function foo({y: [a,b,c]}) {}
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
- writeTextOfNode(currentSourceFile, bindingElement.propertyName);
+ writeTextOfNode(currentText, bindingElement.propertyName);
write(": ");
}
if (bindingElement.name) {
@@ -29575,7 +29961,7 @@ var ts;
if (bindingElement.dotDotDotToken) {
write("...");
}
- writeTextOfNode(currentSourceFile, bindingElement.name);
+ writeTextOfNode(currentText, bindingElement.name);
}
}
}
@@ -29667,6 +30053,18 @@ var ts;
return ts.isExternalModule(sourceFile) || ts.isDeclarationFile(sourceFile);
}
ts.isExternalModuleOrDeclarationFile = isExternalModuleOrDeclarationFile;
+ function getResolvedExternalModuleName(host, file) {
+ return file.moduleName || ts.getExternalModuleNameFromPath(host, file.fileName);
+ }
+ ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
+ function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
+ var file = resolver.getExternalModuleFileFromDeclaration(declaration);
+ if (!file || ts.isDeclarationFile(file)) {
+ return undefined;
+ }
+ return getResolvedExternalModuleName(host, file);
+ }
+ ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
var Jump;
(function (Jump) {
Jump[Jump["Break"] = 2] = "Break";
@@ -29954,15 +30352,19 @@ var ts;
var newLine = host.getNewLine();
var jsxDesugaring = host.getCompilerOptions().jsx !== 1 /* Preserve */;
var shouldEmitJsx = function (s) { return (s.languageVariant === 1 /* JSX */ && !jsxDesugaring); };
+ var outFile = compilerOptions.outFile || compilerOptions.out;
+ var emitJavaScript = createFileEmitter();
if (targetSourceFile === undefined) {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
- var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
- emitFile(jsFilePath, sourceFile);
- }
- });
- if (compilerOptions.outFile || compilerOptions.out) {
- emitFile(compilerOptions.outFile || compilerOptions.out);
+ if (outFile) {
+ emitFile(outFile);
+ }
+ else {
+ ts.forEach(host.getSourceFiles(), function (sourceFile) {
+ if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
+ var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
+ emitFile(jsFilePath, sourceFile);
+ }
+ });
}
}
else {
@@ -29971,8 +30373,8 @@ var ts;
var jsFilePath = ts.getOwnEmitOutputFilePath(targetSourceFile, host, shouldEmitJsx(targetSourceFile) ? ".jsx" : ".js");
emitFile(jsFilePath, targetSourceFile);
}
- else if (!ts.isDeclarationFile(targetSourceFile) && (compilerOptions.outFile || compilerOptions.out)) {
- emitFile(compilerOptions.outFile || compilerOptions.out);
+ else if (!ts.isDeclarationFile(targetSourceFile) && outFile) {
+ emitFile(outFile);
}
}
// Sort and make the unique list of diagnostics
@@ -30024,10 +30426,16 @@ var ts;
}
}
}
- function emitJavaScript(jsFilePath, root) {
+ function createFileEmitter() {
var writer = ts.createTextWriter(newLine);
var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent;
var currentSourceFile;
+ var currentText;
+ var currentLineMap;
+ var currentFileIdentifiers;
+ var renamedDependencies;
+ var isEs6Module;
+ var isCurrentFileExternalModule;
// name of an exporter function if file is a System external module
// System.register([...], function () {...})
// exporting in System modules looks like:
@@ -30035,15 +30443,15 @@ var ts;
// =>
// var x;... exporter("x", x = 1)
var exportFunctionForFile;
- var generatedNameSet = {};
- var nodeToGeneratedName = [];
+ var generatedNameSet;
+ var nodeToGeneratedName;
var computedPropertyNamesToGeneratedNames;
var convertedLoopState;
- var extendsEmitted = false;
- var decorateEmitted = false;
- var paramEmitted = false;
- var awaiterEmitted = false;
- var tempFlags = 0;
+ var extendsEmitted;
+ var decorateEmitted;
+ var paramEmitted;
+ var awaiterEmitted;
+ var tempFlags;
var tempVariables;
var tempParameters;
var externalImports;
@@ -30075,6 +30483,8 @@ var ts;
var scopeEmitEnd = function () { };
/** Sourcemap data that will get encoded */
var sourceMapData;
+ /** The root file passed to the emit function (if present) */
+ var root;
/** If removeComments is true, no leading-comments needed to be emitted **/
var emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos) { } : emitLeadingCommentsOfPositionWorker;
var moduleEmitDelegates = (_a = {},
@@ -30085,31 +30495,77 @@ var ts;
_a[1 /* CommonJS */] = emitCommonJSModule,
_a
);
- if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
- initializeEmitterWithSourceMaps();
- }
- if (root) {
- // Do not call emit directly. It does not set the currentSourceFile.
- emitSourceFile(root);
- }
- else {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!isExternalModuleOrDeclarationFile(sourceFile)) {
- emitSourceFile(sourceFile);
+ var bundleEmitDelegates = (_b = {},
+ _b[5 /* ES6 */] = function () { },
+ _b[2 /* AMD */] = emitAMDModule,
+ _b[4 /* System */] = emitSystemModule,
+ _b[3 /* UMD */] = function () { },
+ _b[1 /* CommonJS */] = function () { },
+ _b
+ );
+ return doEmit;
+ function doEmit(jsFilePath, rootFile) {
+ // reset the state
+ writer.reset();
+ currentSourceFile = undefined;
+ currentText = undefined;
+ currentLineMap = undefined;
+ exportFunctionForFile = undefined;
+ generatedNameSet = {};
+ nodeToGeneratedName = [];
+ computedPropertyNamesToGeneratedNames = undefined;
+ convertedLoopState = undefined;
+ extendsEmitted = false;
+ decorateEmitted = false;
+ paramEmitted = false;
+ awaiterEmitted = false;
+ tempFlags = 0;
+ tempVariables = undefined;
+ tempParameters = undefined;
+ externalImports = undefined;
+ exportSpecifiers = undefined;
+ exportEquals = undefined;
+ hasExportStars = undefined;
+ detachedCommentsInfo = undefined;
+ sourceMapData = undefined;
+ isEs6Module = false;
+ renamedDependencies = undefined;
+ isCurrentFileExternalModule = false;
+ root = rootFile;
+ if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
+ initializeEmitterWithSourceMaps(jsFilePath, root);
+ }
+ if (root) {
+ // Do not call emit directly. It does not set the currentSourceFile.
+ emitSourceFile(root);
+ }
+ else {
+ if (modulekind) {
+ ts.forEach(host.getSourceFiles(), emitEmitHelpers);
}
- });
+ ts.forEach(host.getSourceFiles(), function (sourceFile) {
+ if ((!isExternalModuleOrDeclarationFile(sourceFile)) || (modulekind && ts.isExternalModule(sourceFile))) {
+ emitSourceFile(sourceFile);
+ }
+ });
+ }
+ writeLine();
+ writeEmittedFiles(writer.getText(), jsFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM);
}
- writeLine();
- writeEmittedFiles(writer.getText(), /*writeByteOrderMark*/ compilerOptions.emitBOM);
- return;
function emitSourceFile(sourceFile) {
currentSourceFile = sourceFile;
+ currentText = sourceFile.text;
+ currentLineMap = ts.getLineStarts(sourceFile);
exportFunctionForFile = undefined;
+ isEs6Module = sourceFile.symbol && sourceFile.symbol.exports && !!sourceFile.symbol.exports["___esModule"];
+ renamedDependencies = sourceFile.renamedDependencies;
+ currentFileIdentifiers = sourceFile.identifiers;
+ isCurrentFileExternalModule = ts.isExternalModule(sourceFile);
emit(sourceFile);
}
function isUniqueName(name) {
return !resolver.hasGlobalName(name) &&
- !ts.hasProperty(currentSourceFile.identifiers, name) &&
+ !ts.hasProperty(currentFileIdentifiers, name) &&
!ts.hasProperty(generatedNameSet, name);
}
// Return the next available name in the pattern _a ... _z, _0, _1, ...
@@ -30192,7 +30648,7 @@ var ts;
var id = ts.getNodeId(node);
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = ts.unescapeIdentifier(generateNameForNode(node)));
}
- function initializeEmitterWithSourceMaps() {
+ function initializeEmitterWithSourceMaps(jsFilePath, root) {
var sourceMapDir; // The directory in which sourcemap will be
// Current source map file and its index in the sources list
var sourceMapSourceIndex = -1;
@@ -30280,7 +30736,7 @@ var ts;
}
}
function recordSourceMapSpan(pos) {
- var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSourceFile, pos);
+ var sourceLinePos = ts.computeLineAndCharacterOfPosition(currentLineMap, pos);
// Convert the location to be one-based.
sourceLinePos.line++;
sourceLinePos.character++;
@@ -30314,13 +30770,13 @@ var ts;
}
function recordEmitNodeStartSpan(node) {
// Get the token pos after skipping to the token (ignoring the leading trivia)
- recordSourceMapSpan(ts.skipTrivia(currentSourceFile.text, node.pos));
+ recordSourceMapSpan(ts.skipTrivia(currentText, node.pos));
}
function recordEmitNodeEndSpan(node) {
recordSourceMapSpan(node.end);
}
function writeTextWithSpanRecord(tokenKind, startPos, emitFn) {
- var tokenStartPos = ts.skipTrivia(currentSourceFile.text, startPos);
+ var tokenStartPos = ts.skipTrivia(currentText, startPos);
recordSourceMapSpan(tokenStartPos);
var tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
recordSourceMapSpan(tokenEndPos);
@@ -30402,9 +30858,9 @@ var ts;
sourceMapNameIndices.pop();
}
;
- function writeCommentRangeWithMap(curentSourceFile, writer, comment, newLine) {
+ function writeCommentRangeWithMap(currentText, currentLineMap, writer, comment, newLine) {
recordSourceMapSpan(comment.pos);
- ts.writeCommentRange(currentSourceFile, writer, comment, newLine);
+ ts.writeCommentRange(currentText, currentLineMap, writer, comment, newLine);
recordSourceMapSpan(comment.end);
}
function serializeSourceMapContents(version, file, sourceRoot, sources, names, mappings, sourcesContent) {
@@ -30434,7 +30890,7 @@ var ts;
return output;
}
}
- function writeJavaScriptAndSourceMapFile(emitOutput, writeByteOrderMark) {
+ function writeJavaScriptAndSourceMapFile(emitOutput, jsFilePath, writeByteOrderMark) {
encodeLastRecordedSourceMapSpan();
var sourceMapText = serializeSourceMapContents(3, sourceMapData.sourceMapFile, sourceMapData.sourceMapSourceRoot, sourceMapData.sourceMapSources, sourceMapData.sourceMapNames, sourceMapData.sourceMapMappings, sourceMapData.sourceMapSourcesContent);
sourceMapDataList.push(sourceMapData);
@@ -30450,7 +30906,7 @@ var ts;
sourceMapUrl = "//# sourceMappingURL=" + sourceMapData.jsSourceMappingURL;
}
// Write sourcemap url to the js file and write the js file
- writeJavaScriptFile(emitOutput + sourceMapUrl, writeByteOrderMark);
+ writeJavaScriptFile(emitOutput + sourceMapUrl, jsFilePath, writeByteOrderMark);
}
// Initialize source map data
var sourceMapJsFile = ts.getBaseFileName(ts.normalizeSlashes(jsFilePath));
@@ -30522,7 +30978,7 @@ var ts;
scopeEmitEnd = recordScopeNameEnd;
writeComment = writeCommentRangeWithMap;
}
- function writeJavaScriptFile(emitOutput, writeByteOrderMark) {
+ function writeJavaScriptFile(emitOutput, jsFilePath, writeByteOrderMark) {
ts.writeFile(host, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
}
// Create a temporary variable with a unique unused name.
@@ -30702,7 +31158,7 @@ var ts;
// If we don't need to downlevel and we can reach the original source text using
// the node's parent reference, then simply get the text as it was originally written.
if (node.parent) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+ return ts.getTextOfNodeFromSourceText(currentText, node);
}
// If we can't reach the original source text, use the canonical form if it's a number,
// or an escaped quoted form of the original text if it's string-like.
@@ -30729,7 +31185,7 @@ var ts;
// Find original source text, since we need to emit the raw strings of the tagged template.
// The raw strings contain the (escaped) strings of what the user wrote.
// Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
+ var text = ts.getTextOfNodeFromSourceText(currentText, node);
// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
// thus we need to remove those characters.
// First template piece starts with "`", others with "}"
@@ -31146,7 +31602,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
write("\"");
}
@@ -31246,7 +31702,7 @@ var ts;
// Identifier references named import
write(getGeneratedNameForNode(declaration.parent.parent.parent));
var name_23 = declaration.propertyName || declaration.name;
- var identifier = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, name_23);
+ var identifier = ts.getTextOfNodeFromSourceText(currentText, name_23);
if (languageVersion === 0 /* ES3 */ && identifier === "default") {
write("[\"default\"]");
}
@@ -31270,7 +31726,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
}
function isNameOfNestedRedeclaration(node) {
@@ -31308,7 +31764,7 @@ var ts;
write(node.text);
}
else {
- writeTextOfNode(currentSourceFile, node);
+ writeTextOfNode(currentText, node);
}
}
function emitThis(node) {
@@ -31712,7 +32168,7 @@ var ts;
function emitShorthandPropertyAssignment(node) {
// The name property of a short-hand property assignment is considered an expression position, so here
// we manually emit the identifier to avoid rewriting.
- writeTextOfNode(currentSourceFile, node.name);
+ writeTextOfNode(currentText, node.name);
// If emitting pre-ES6 code, or if the name requires rewriting when resolved as an expression identifier,
// we emit a normal property assignment. For example:
// module m {
@@ -31722,7 +32178,7 @@ var ts;
// let obj = { y };
// }
// Here we need to emit obj = { y : m.y } regardless of the output target.
- if (languageVersion < 2 /* ES6 */ || isNamespaceExportReference(node.name)) {
+ if (modulekind !== 5 /* ES6 */ || isNamespaceExportReference(node.name)) {
// Emit identifier as an identifier
write(": ");
emit(node.name);
@@ -31779,11 +32235,11 @@ var ts;
var indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken);
// 1 .toString is a valid property access, emit a space after the literal
// Also emit a space if expression is a integer const enum value - it will appear in generated code as numeric literal
- var shouldEmitSpace;
+ var shouldEmitSpace = false;
if (!indentedBeforeDot) {
if (node.expression.kind === 8 /* NumericLiteral */) {
// check if numeric literal was originally written with a dot
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node.expression);
+ var text = ts.getTextOfNodeFromSourceText(currentText, node.expression);
shouldEmitSpace = text.indexOf(ts.tokenToString(21 /* DotToken */)) < 0;
}
else {
@@ -32962,16 +33418,16 @@ var ts;
emitToken(16 /* CloseBraceToken */, node.clauses.end);
}
function nodeStartPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node1.pos)) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node1.pos)) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
}
function nodeEndPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, node2.end);
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, node2.end);
}
function nodeEndIsOnSameLineAsNodeStart(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
+ return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
+ ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
}
function emitCaseOrDefaultClause(node) {
if (node.kind === 241 /* CaseClause */) {
@@ -33077,7 +33533,7 @@ var ts;
ts.Debug.assert(!!(node.flags & 512 /* Default */) || node.kind === 227 /* ExportAssignment */);
// only allow export default at a source file level
if (modulekind === 1 /* CommonJS */ || modulekind === 2 /* AMD */ || modulekind === 3 /* UMD */) {
- if (!currentSourceFile.symbol.exports["___esModule"]) {
+ if (!isEs6Module) {
if (languageVersion === 1 /* ES5 */) {
// default value of configurable, enumerable, writable are `false`.
write("Object.defineProperty(exports, \"__esModule\", { value: true });");
@@ -33272,14 +33728,20 @@ var ts;
return node;
}
function createPropertyAccessForDestructuringProperty(object, propName) {
- // We create a synthetic copy of the identifier in order to avoid the rewriting that might
- // otherwise occur when the identifier is emitted.
- var syntheticName = ts.createSynthesizedNode(propName.kind);
- syntheticName.text = propName.text;
- if (syntheticName.kind !== 69 /* Identifier */) {
- return createElementAccessExpression(object, syntheticName);
+ var index;
+ var nameIsComputed = propName.kind === 136 /* ComputedPropertyName */;
+ if (nameIsComputed) {
+ index = ensureIdentifier(propName.expression, /* reuseIdentifierExpression */ false);
+ }
+ else {
+ // We create a synthetic copy of the identifier in order to avoid the rewriting that might
+ // otherwise occur when the identifier is emitted.
+ index = ts.createSynthesizedNode(propName.kind);
+ index.text = propName.text;
}
- return createPropertyAccessExpression(object, syntheticName);
+ return !nameIsComputed && index.kind === 69 /* Identifier */
+ ? createPropertyAccessExpression(object, index)
+ : createElementAccessExpression(object, index);
}
function createSliceCall(value, sliceIndex) {
var call = ts.createSynthesizedNode(168 /* CallExpression */);
@@ -33742,7 +34204,6 @@ var ts;
var promiseConstructor = ts.getEntityNameFromTypeNode(node.type);
var isArrowFunction = node.kind === 174 /* ArrowFunction */;
var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 4096 /* CaptureArguments */) !== 0;
- var args;
// An async function is emit as an outer function that calls an inner
// generator function. To preserve lexical bindings, we pass the current
// `this` and `arguments` objects to `__awaiter`. The generator function
@@ -35197,8 +35658,8 @@ var ts;
* Here we check if alternative name was provided for a given moduleName and return it if possible.
*/
function tryRenameExternalModule(moduleName) {
- if (currentSourceFile.renamedDependencies && ts.hasProperty(currentSourceFile.renamedDependencies, moduleName.text)) {
- return "\"" + currentSourceFile.renamedDependencies[moduleName.text] + "\"";
+ if (renamedDependencies && ts.hasProperty(renamedDependencies, moduleName.text)) {
+ return "\"" + renamedDependencies[moduleName.text] + "\"";
}
return undefined;
}
@@ -35351,7 +35812,7 @@ var ts;
// - current file is not external module
// - import declaration is top level and target is value imported by entity name
if (resolver.isReferencedAliasDeclaration(node) ||
- (!ts.isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
+ (!isCurrentFileExternalModule && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
emitLeadingComments(node);
emitStart(node);
// variable declaration for import-equals declaration can be hoisted in system modules
@@ -35579,7 +36040,7 @@ var ts;
function getLocalNameForExternalImport(node) {
var namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, namespaceDeclaration.name);
+ return ts.getTextOfNodeFromSourceText(currentText, namespaceDeclaration.name);
}
if (node.kind === 222 /* ImportDeclaration */ && node.importClause) {
return getGeneratedNameForNode(node);
@@ -35884,7 +36345,7 @@ var ts;
ts.getEnclosingBlockScopeContainer(node).kind === 248 /* SourceFile */;
}
function isCurrentFileSystemExternalModule() {
- return modulekind === 4 /* System */ && ts.isExternalModule(currentSourceFile);
+ return modulekind === 4 /* System */ && isCurrentFileExternalModule;
}
function emitSystemModuleBody(node, dependencyGroups, startIndex) {
// shape of the body in system modules:
@@ -36054,7 +36515,13 @@ var ts;
writeLine();
write("}"); // execute
}
- function emitSystemModule(node) {
+ function writeModuleName(node, emitRelativePathAsModuleName) {
+ var moduleName = node.moduleName;
+ if (moduleName || (emitRelativePathAsModuleName && (moduleName = getResolvedExternalModuleName(host, node)))) {
+ write("\"" + moduleName + "\", ");
+ }
+ }
+ function emitSystemModule(node, emitRelativePathAsModuleName) {
collectExternalModuleInfo(node);
// System modules has the following shape
// System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
@@ -36069,9 +36536,7 @@ var ts;
exportFunctionForFile = makeUniqueName("exports");
writeLine();
write("System.register(");
- if (node.moduleName) {
- write("\"" + node.moduleName + "\", ");
- }
+ writeModuleName(node, emitRelativePathAsModuleName);
write("[");
var groupIndices = {};
var dependencyGroups = [];
@@ -36090,6 +36555,12 @@ var ts;
if (i !== 0) {
write(", ");
}
+ if (emitRelativePathAsModuleName) {
+ var name_29 = getExternalModuleNameFromDeclaration(host, resolver, externalImports[i]);
+ if (name_29) {
+ text = "\"" + name_29 + "\"";
+ }
+ }
write(text);
}
write("], function(" + exportFunctionForFile + ") {");
@@ -36103,7 +36574,7 @@ var ts;
writeLine();
write("});");
}
- function getAMDDependencyNames(node, includeNonAmdDependencies) {
+ function getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
// names of modules with corresponding parameter in the factory function
var aliasedModuleNames = [];
// names of modules with no corresponding parameters in factory function
@@ -36126,6 +36597,12 @@ var ts;
var importNode = externalImports_4[_c];
// Find the name of the external module
var externalModuleName = getExternalModuleNameText(importNode);
+ if (emitRelativePathAsModuleName) {
+ var name_30 = getExternalModuleNameFromDeclaration(host, resolver, importNode);
+ if (name_30) {
+ externalModuleName = "\"" + name_30 + "\"";
+ }
+ }
// Find the name of the module alias, if there is one
var importAliasName = getLocalNameForExternalImport(importNode);
if (includeNonAmdDependencies && importAliasName) {
@@ -36138,7 +36615,7 @@ var ts;
}
return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
}
- function emitAMDDependencies(node, includeNonAmdDependencies) {
+ function emitAMDDependencies(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
// An AMD define function has the following shape:
// define(id?, dependencies?, factory);
//
@@ -36150,7 +36627,7 @@ var ts;
// To ensure this is true in cases of modules with no aliases, e.g.:
// `import "module"` or ``
// we need to add modules without alias names to the end of the dependencies list
- var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies);
+ var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName);
emitAMDDependencyList(dependencyNames);
write(", ");
emitAMDFactoryHeader(dependencyNames);
@@ -36177,15 +36654,13 @@ var ts;
}
write(") {");
}
- function emitAMDModule(node) {
+ function emitAMDModule(node, emitRelativePathAsModuleName) {
emitEmitHelpers(node);
collectExternalModuleInfo(node);
writeLine();
write("define(");
- if (node.moduleName) {
- write("\"" + node.moduleName + "\", ");
- }
- emitAMDDependencies(node, /*includeNonAmdDependencies*/ true);
+ writeModuleName(node, emitRelativePathAsModuleName);
+ emitAMDDependencies(node, /*includeNonAmdDependencies*/ true, emitRelativePathAsModuleName);
increaseIndent();
var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
emitExportStarHelper();
@@ -36404,8 +36879,13 @@ var ts;
emitShebang();
emitDetachedCommentsAndUpdateCommentsInfo(node);
if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
- var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[1 /* CommonJS */];
- emitModule(node);
+ if (root || (!ts.isExternalModule(node) && compilerOptions.isolatedModules)) {
+ var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[1 /* CommonJS */];
+ emitModule(node);
+ }
+ else {
+ bundleEmitDelegates[modulekind](node, /*emitRelativePathAsModuleName*/ true);
+ }
}
else {
// emit prologue directives prior to __extends
@@ -36666,7 +37146,7 @@ var ts;
}
function getLeadingCommentsWithoutDetachedComments() {
// get the leading comments from detachedPos
- var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
+ var leadingComments = ts.getLeadingCommentRanges(currentText, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
if (detachedCommentsInfo.length - 1) {
detachedCommentsInfo.pop();
}
@@ -36683,10 +37163,10 @@ var ts;
function isTripleSlashComment(comment) {
// Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
// so that we don't end up computing comment string and doing match for all // comments
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 47 /* slash */ &&
+ if (currentText.charCodeAt(comment.pos + 1) === 47 /* slash */ &&
comment.pos + 2 < comment.end &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 47 /* slash */) {
- var textSubStr = currentSourceFile.text.substring(comment.pos, comment.end);
+ currentText.charCodeAt(comment.pos + 2) === 47 /* slash */) {
+ var textSubStr = currentText.substring(comment.pos, comment.end);
return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ?
true : false;
@@ -36703,7 +37183,7 @@ var ts;
}
else {
// get the leading comments from the node
- return ts.getLeadingCommentRangesOfNode(node, currentSourceFile);
+ return ts.getLeadingCommentRangesOfNodeFromText(node, currentText);
}
}
}
@@ -36712,7 +37192,7 @@ var ts;
// Emit the trailing comments only if the parent's pos doesn't match because parent should take care of emitting these comments
if (node.parent) {
if (node.parent.kind === 248 /* SourceFile */ || node.end !== node.parent.end) {
- return ts.getTrailingCommentRanges(currentSourceFile.text, node.end);
+ return ts.getTrailingCommentRanges(currentText, node.end);
}
}
}
@@ -36746,9 +37226,9 @@ var ts;
leadingComments = ts.filter(getLeadingCommentsToEmit(node), isTripleSlashComment);
}
}
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
- ts.emitComments(currentSourceFile, writer, leadingComments, /*trailingSeparator:*/ true, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator:*/ true, newLine, writeComment);
}
function emitTrailingComments(node) {
if (compilerOptions.removeComments) {
@@ -36757,7 +37237,7 @@ var ts;
// Emit the trailing comments only if the parent's end doesn't match
var trailingComments = getTrailingCommentsToEmit(node);
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
- ts.emitComments(currentSourceFile, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment);
}
/**
* Emit trailing comments at the position. The term trailing comment is used here to describe following comment:
@@ -36768,9 +37248,9 @@ var ts;
if (compilerOptions.removeComments) {
return;
}
- var trailingComments = ts.getTrailingCommentRanges(currentSourceFile.text, pos);
+ var trailingComments = ts.getTrailingCommentRanges(currentText, pos);
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
- ts.emitComments(currentSourceFile, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitLeadingCommentsOfPositionWorker(pos) {
if (compilerOptions.removeComments) {
@@ -36783,14 +37263,14 @@ var ts;
}
else {
// get the leading comments from the node
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, pos);
+ leadingComments = ts.getLeadingCommentRanges(currentText, pos);
}
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, { pos: pos, end: pos }, leadingComments);
+ ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
- ts.emitComments(currentSourceFile, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
+ ts.emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitDetachedCommentsAndUpdateCommentsInfo(node) {
- var currentDetachedCommentInfo = ts.emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, compilerOptions.removeComments);
+ var currentDetachedCommentInfo = ts.emitDetachedComments(currentText, currentLineMap, writer, writeComment, node, newLine, compilerOptions.removeComments);
if (currentDetachedCommentInfo) {
if (detachedCommentsInfo) {
detachedCommentsInfo.push(currentDetachedCommentInfo);
@@ -36801,12 +37281,12 @@ var ts;
}
}
function emitShebang() {
- var shebang = ts.getShebang(currentSourceFile.text);
+ var shebang = ts.getShebang(currentText);
if (shebang) {
write(shebang);
}
}
- var _a;
+ var _a, _b;
}
function emitFile(jsFilePath, sourceFile) {
emitJavaScript(jsFilePath, sourceFile);
@@ -36866,11 +37346,11 @@ var ts;
if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
var failedLookupLocations = [];
var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
- var resolvedFileName = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ var resolvedFileName = loadNodeModuleFromFile(ts.supportedJsExtensions, candidate, failedLookupLocations, host);
if (resolvedFileName) {
return { resolvedModule: { resolvedFileName: resolvedFileName }, failedLookupLocations: failedLookupLocations };
}
- resolvedFileName = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ resolvedFileName = loadNodeModuleFromDirectory(ts.supportedJsExtensions, candidate, failedLookupLocations, host);
return resolvedFileName
? { resolvedModule: { resolvedFileName: resolvedFileName }, failedLookupLocations: failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations: failedLookupLocations };
@@ -36880,8 +37360,8 @@ var ts;
}
}
ts.nodeModuleNameResolver = nodeModuleNameResolver;
- function loadNodeModuleFromFile(candidate, failedLookupLocation, host) {
- return ts.forEach(ts.moduleFileExtensions, tryLoad);
+ function loadNodeModuleFromFile(extensions, candidate, failedLookupLocation, host) {
+ return ts.forEach(extensions, tryLoad);
function tryLoad(ext) {
var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
if (host.fileExists(fileName)) {
@@ -36893,7 +37373,7 @@ var ts;
}
}
}
- function loadNodeModuleFromDirectory(candidate, failedLookupLocation, host) {
+ function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, host) {
var packageJsonPath = ts.combinePaths(candidate, "package.json");
if (host.fileExists(packageJsonPath)) {
var jsonContent;
@@ -36906,7 +37386,7 @@ var ts;
jsonContent = { typings: undefined };
}
if (jsonContent.typings) {
- var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
+ var result = loadNodeModuleFromFile(extensions, ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
if (result) {
return result;
}
@@ -36916,7 +37396,7 @@ var ts;
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
failedLookupLocation.push(packageJsonPath);
}
- return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), failedLookupLocation, host);
+ return loadNodeModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocation, host);
}
function loadModuleFromNodeModules(moduleName, directory, host) {
var failedLookupLocations = [];
@@ -36926,11 +37406,11 @@ var ts;
if (baseName !== "node_modules") {
var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName));
- var result = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ var result = loadNodeModuleFromFile(ts.supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations: failedLookupLocations };
}
- result = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ result = loadNodeModuleFromDirectory(ts.supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations: failedLookupLocations };
}
@@ -36956,9 +37436,10 @@ var ts;
var searchName;
var failedLookupLocations = [];
var referencedSourceFile;
+ var extensions = compilerOptions.allowNonTsExtensions ? ts.supportedJsExtensions : ts.supportedExtensions;
while (true) {
searchName = ts.normalizePath(ts.combinePaths(searchPath, moduleName));
- referencedSourceFile = ts.forEach(ts.supportedExtensions, function (extension) {
+ referencedSourceFile = ts.forEach(extensions, function (extension) {
if (extension === ".tsx" && !compilerOptions.jsx) {
// resolve .tsx files only if jsx support is enabled
// 'logical not' handles both undefined and None cases
@@ -36989,10 +37470,8 @@ var ts;
/* @internal */
ts.defaultInitCompilerOptions = {
module: 1 /* CommonJS */,
- target: 0 /* ES3 */,
+ target: 1 /* ES5 */,
noImplicitAny: false,
- outDir: "built",
- rootDir: ".",
sourceMap: false
};
function createCompilerHost(options, setParentNodes) {
@@ -37397,43 +37876,55 @@ var ts;
if (file.imports) {
return;
}
+ var isJavaScriptFile = ts.isSourceFileJavaScript(file);
var imports;
for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
var node = _a[_i];
- collect(node, /* allowRelativeModuleNames */ true);
+ collect(node, /* allowRelativeModuleNames */ true, /* collectOnlyRequireCalls */ false);
}
file.imports = imports || emptyArray;
- function collect(node, allowRelativeModuleNames) {
- switch (node.kind) {
- case 222 /* ImportDeclaration */:
- case 221 /* ImportEqualsDeclaration */:
- case 228 /* ExportDeclaration */:
- var moduleNameExpr = ts.getExternalModuleName(node);
- if (!moduleNameExpr || moduleNameExpr.kind !== 9 /* StringLiteral */) {
- break;
- }
- if (!moduleNameExpr.text) {
+ return;
+ function collect(node, allowRelativeModuleNames, collectOnlyRequireCalls) {
+ if (!collectOnlyRequireCalls) {
+ switch (node.kind) {
+ case 222 /* ImportDeclaration */:
+ case 221 /* ImportEqualsDeclaration */:
+ case 228 /* ExportDeclaration */:
+ var moduleNameExpr = ts.getExternalModuleName(node);
+ if (!moduleNameExpr || moduleNameExpr.kind !== 9 /* StringLiteral */) {
+ break;
+ }
+ if (!moduleNameExpr.text) {
+ break;
+ }
+ if (allowRelativeModuleNames || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
+ (imports || (imports = [])).push(moduleNameExpr);
+ }
break;
- }
- if (allowRelativeModuleNames || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) {
- (imports || (imports = [])).push(moduleNameExpr);
- }
- break;
- case 218 /* ModuleDeclaration */:
- if (node.name.kind === 9 /* StringLiteral */ && (node.flags & 4 /* Ambient */ || ts.isDeclarationFile(file))) {
- // TypeScript 1.0 spec (April 2014): 12.1.6
- // An AmbientExternalModuleDeclaration declares an external module.
- // This type of declaration is permitted only in the global module.
- // The StringLiteral must specify a top - level external module name.
- // Relative external module names are not permitted
- ts.forEachChild(node.body, function (node) {
+ case 218 /* ModuleDeclaration */:
+ if (node.name.kind === 9 /* StringLiteral */ && (node.flags & 4 /* Ambient */ || ts.isDeclarationFile(file))) {
// TypeScript 1.0 spec (April 2014): 12.1.6
- // An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
- // only through top - level external module names. Relative external module names are not permitted.
- collect(node, /* allowRelativeModuleNames */ false);
- });
- }
- break;
+ // An AmbientExternalModuleDeclaration declares an external module.
+ // This type of declaration is permitted only in the global module.
+ // The StringLiteral must specify a top - level external module name.
+ // Relative external module names are not permitted
+ ts.forEachChild(node.body, function (node) {
+ // TypeScript 1.0 spec (April 2014): 12.1.6
+ // An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
+ // only through top - level external module names. Relative external module names are not permitted.
+ collect(node, /* allowRelativeModuleNames */ false, collectOnlyRequireCalls);
+ });
+ }
+ break;
+ }
+ }
+ if (isJavaScriptFile) {
+ if (ts.isRequireCall(node)) {
+ (imports || (imports = [])).push(node.arguments[0]);
+ }
+ else {
+ ts.forEachChild(node, function (node) { return collect(node, allowRelativeModuleNames, /* collectOnlyRequireCalls */ true); });
+ }
}
}
}
@@ -37526,7 +38017,6 @@ var ts;
// always process imported modules to record module name resolutions
processImportedModules(file, basePath);
if (isDefaultLib) {
- file.isDefaultLib = true;
files.unshift(file);
}
else {
@@ -37604,6 +38094,9 @@ var ts;
commonPathComponents.length = sourcePathComponents.length;
}
});
+ if (!commonPathComponents) {
+ return currentDirectory;
+ }
return ts.getNormalizedPathFromPathComponents(commonPathComponents);
}
function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
@@ -37689,12 +38182,15 @@ var ts;
if (options.module === 5 /* ES6 */ && languageVersion < 2 /* ES6 */) {
programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower));
}
+ // Cannot specify module gen that isn't amd or system with --out
+ if (outFile && options.module && !(options.module === 2 /* AMD */ || options.module === 4 /* System */)) {
+ programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile"));
+ }
// there has to be common source directory if user specified --outdir || --sourceRoot
// if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
if (options.outDir ||
options.sourceRoot ||
- (options.mapRoot &&
- (!outFile || firstExternalModuleSourceFile !== undefined))) {
+ options.mapRoot) {
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
// If a rootDir is specified and is valid use it as the commonSourceDirectory
commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
@@ -38212,20 +38708,20 @@ var ts;
var exclude = json["exclude"] instanceof Array ? ts.map(json["exclude"], ts.normalizeSlashes) : undefined;
var sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
for (var i = 0; i < sysFiles.length; i++) {
- var name_29 = sysFiles[i];
- if (ts.fileExtensionIs(name_29, ".d.ts")) {
- var baseName = name_29.substr(0, name_29.length - ".d.ts".length);
+ var name_31 = sysFiles[i];
+ if (ts.fileExtensionIs(name_31, ".d.ts")) {
+ var baseName = name_31.substr(0, name_31.length - ".d.ts".length);
if (!ts.contains(sysFiles, baseName + ".tsx") && !ts.contains(sysFiles, baseName + ".ts")) {
- fileNames.push(name_29);
+ fileNames.push(name_31);
}
}
- else if (ts.fileExtensionIs(name_29, ".ts")) {
- if (!ts.contains(sysFiles, name_29 + "x")) {
- fileNames.push(name_29);
+ else if (ts.fileExtensionIs(name_31, ".ts")) {
+ if (!ts.contains(sysFiles, name_31 + "x")) {
+ fileNames.push(name_31);
}
}
else {
- fileNames.push(name_29);
+ fileNames.push(name_31);
}
}
}
@@ -38453,12 +38949,12 @@ var ts;
ts.forEach(program.getSourceFiles(), function (sourceFile) {
cancellationToken.throwIfCancellationRequested();
var nameToDeclarations = sourceFile.getNamedDeclarations();
- for (var name_30 in nameToDeclarations) {
- var declarations = ts.getProperty(nameToDeclarations, name_30);
+ for (var name_32 in nameToDeclarations) {
+ var declarations = ts.getProperty(nameToDeclarations, name_32);
if (declarations) {
// First do a quick check to see if the name of the declaration matches the
// last portion of the (possibly) dotted name they're searching for.
- var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_30);
+ var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_32);
if (!matches) {
continue;
}
@@ -38471,14 +38967,14 @@ var ts;
if (!containers) {
return undefined;
}
- matches = patternMatcher.getMatches(containers, name_30);
+ matches = patternMatcher.getMatches(containers, name_32);
if (!matches) {
continue;
}
}
var fileName = sourceFile.fileName;
var matchKind = bestMatchKind(matches);
- rawItems.push({ name: name_30, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration });
+ rawItems.push({ name: name_32, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration });
}
}
}
@@ -38859,9 +39355,9 @@ var ts;
case 211 /* VariableDeclaration */:
case 163 /* BindingElement */:
var variableDeclarationNode;
- var name_31;
+ var name_33;
if (node.kind === 163 /* BindingElement */) {
- name_31 = node.name;
+ name_33 = node.name;
variableDeclarationNode = node;
// binding elements are added only for variable declarations
// bubble up to the containing variable declaration
@@ -38873,16 +39369,16 @@ var ts;
else {
ts.Debug.assert(!ts.isBindingPattern(node.name));
variableDeclarationNode = node;
- name_31 = node.name;
+ name_33 = node.name;
}
if (ts.isConst(variableDeclarationNode)) {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.constElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.constElement);
}
else if (ts.isLet(variableDeclarationNode)) {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.letElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.letElement);
}
else {
- return createItem(node, getTextOfNode(name_31), ts.ScriptElementKind.variableElement);
+ return createItem(node, getTextOfNode(name_33), ts.ScriptElementKind.variableElement);
}
case 144 /* Constructor */:
return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement);
@@ -39802,7 +40298,7 @@ var ts;
if (!candidates.length) {
// We didn't have any sig help items produced by the TS compiler. If this is a JS
// file, then see if we can figure out anything better.
- if (ts.isJavaScript(sourceFile.fileName)) {
+ if (ts.isSourceFileJavaScript(sourceFile)) {
return createJavaScriptSignatureHelpItems(argumentInfo);
}
return undefined;
@@ -41662,9 +42158,9 @@ var ts;
}
Rules.prototype.getRuleName = function (rule) {
var o = this;
- for (var name_32 in o) {
- if (o[name_32] === rule) {
- return name_32;
+ for (var name_34 in o) {
+ if (o[name_34] === rule) {
+ return name_34;
}
}
throw new Error("Unknown rule");
@@ -42096,7 +42592,7 @@ var ts;
function TokenRangeAccess(from, to, except) {
this.tokens = [];
for (var token = from; token <= to; token++) {
- if (except.indexOf(token) < 0) {
+ if (ts.indexOf(except, token) < 0) {
this.tokens.push(token);
}
}
@@ -43709,13 +44205,18 @@ var ts;
];
var jsDocCompletionEntries;
function createNode(kind, pos, end, flags, parent) {
- var node = new (ts.getNodeConstructor(kind))(pos, end);
+ var node = new NodeObject(kind, pos, end);
node.flags = flags;
node.parent = parent;
return node;
}
var NodeObject = (function () {
- function NodeObject() {
+ function NodeObject(kind, pos, end) {
+ this.kind = kind;
+ this.pos = pos;
+ this.end = end;
+ this.flags = 0 /* None */;
+ this.parent = undefined;
}
NodeObject.prototype.getSourceFile = function () {
return ts.getSourceFileOfNode(this);
@@ -44198,8 +44699,8 @@ var ts;
})();
var SourceFileObject = (function (_super) {
__extends(SourceFileObject, _super);
- function SourceFileObject() {
- _super.apply(this, arguments);
+ function SourceFileObject(kind, pos, end) {
+ _super.call(this, kind, pos, end);
}
SourceFileObject.prototype.update = function (newText, textChangeRange) {
return ts.updateSourceFile(this, newText, textChangeRange);
@@ -44521,6 +45022,9 @@ var ts;
ClassificationTypeNames.typeAliasName = "type alias name";
ClassificationTypeNames.parameterName = "parameter name";
ClassificationTypeNames.docCommentTagName = "doc comment tag name";
+ ClassificationTypeNames.jsxOpenTagName = "jsx open tag name";
+ ClassificationTypeNames.jsxCloseTagName = "jsx close tag name";
+ ClassificationTypeNames.jsxSelfClosingTagName = "jsx self closing tag name";
return ClassificationTypeNames;
})();
ts.ClassificationTypeNames = ClassificationTypeNames;
@@ -44543,6 +45047,9 @@ var ts;
ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName";
ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName";
ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName";
+ ClassificationType[ClassificationType["jsxOpenTagName"] = 19] = "jsxOpenTagName";
+ ClassificationType[ClassificationType["jsxCloseTagName"] = 20] = "jsxCloseTagName";
+ ClassificationType[ClassificationType["jsxSelfClosingTagName"] = 21] = "jsxSelfClosingTagName";
})(ts.ClassificationType || (ts.ClassificationType = {}));
var ClassificationType = ts.ClassificationType;
function displayPartsToString(displayParts) {
@@ -44922,8 +45429,9 @@ var ts;
};
}
ts.createDocumentRegistry = createDocumentRegistry;
- function preProcessFile(sourceText, readImportFiles) {
+ function preProcessFile(sourceText, readImportFiles, detectJavaScriptImports) {
if (readImportFiles === void 0) { readImportFiles = true; }
+ if (detectJavaScriptImports === void 0) { detectJavaScriptImports = false; }
var referencedFiles = [];
var importedFiles = [];
var ambientExternalModules;
@@ -44957,116 +45465,66 @@ var ts;
end: pos + importPath.length
});
}
- function processImport() {
- scanner.setText(sourceText);
- var token = scanner.scan();
- // Look for:
- // import "mod";
- // import d from "mod"
- // import {a as A } from "mod";
- // import * as NS from "mod"
- // import d, {a, b as B} from "mod"
- // import i = require("mod");
- //
- // export * from "mod"
- // export {a as b} from "mod"
- // export import i = require("mod")
- while (token !== 1 /* EndOfFileToken */) {
- if (token === 122 /* DeclareKeyword */) {
- // declare module "mod"
- token = scanner.scan();
- if (token === 125 /* ModuleKeyword */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- recordAmbientExternalModule();
- continue;
- }
- }
- }
- else if (token === 89 /* ImportKeyword */) {
+ /**
+ * Returns true if at least one token was consumed from the stream
+ */
+ function tryConsumeDeclare() {
+ var token = scanner.getToken();
+ if (token === 122 /* DeclareKeyword */) {
+ // declare module "mod"
+ token = scanner.scan();
+ if (token === 125 /* ModuleKeyword */) {
token = scanner.scan();
if (token === 9 /* StringLiteral */) {
- // import "mod";
- recordModuleName();
- continue;
+ recordAmbientExternalModule();
}
- else {
- if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
+ }
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Returns true if at least one token was consumed from the stream
+ */
+ function tryConsumeImport() {
+ var token = scanner.getToken();
+ if (token === 89 /* ImportKeyword */) {
+ token = scanner.scan();
+ if (token === 9 /* StringLiteral */) {
+ // import "mod";
+ recordModuleName();
+ return true;
+ }
+ else {
+ if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
+ token = scanner.scan();
+ if (token === 133 /* FromKeyword */) {
token = scanner.scan();
- if (token === 133 /* FromKeyword */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // import d from "mod";
- recordModuleName();
- continue;
- }
- }
- else if (token === 56 /* EqualsToken */) {
- token = scanner.scan();
- if (token === 127 /* RequireKeyword */) {
- token = scanner.scan();
- if (token === 17 /* OpenParenToken */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // import i = require("mod");
- recordModuleName();
- continue;
- }
- }
- }
- }
- else if (token === 24 /* CommaToken */) {
- // consume comma and keep going
- token = scanner.scan();
- }
- else {
- // unknown syntax
- continue;
+ if (token === 9 /* StringLiteral */) {
+ // import d from "mod";
+ recordModuleName();
+ return true;
}
}
- if (token === 15 /* OpenBraceToken */) {
- token = scanner.scan();
- // consume "{ a as B, c, d as D}" clauses
- while (token !== 16 /* CloseBraceToken */) {
- token = scanner.scan();
- }
- if (token === 16 /* CloseBraceToken */) {
- token = scanner.scan();
- if (token === 133 /* FromKeyword */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // import {a as A} from "mod";
- // import d, {a, b as B} from "mod"
- recordModuleName();
- }
- }
+ else if (token === 56 /* EqualsToken */) {
+ if (tryConsumeRequireCall(/* skipCurrentToken */ true)) {
+ return true;
}
}
- else if (token === 37 /* AsteriskToken */) {
+ else if (token === 24 /* CommaToken */) {
+ // consume comma and keep going
token = scanner.scan();
- if (token === 116 /* AsKeyword */) {
- token = scanner.scan();
- if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
- token = scanner.scan();
- if (token === 133 /* FromKeyword */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // import * as NS from "mod"
- // import d, * as NS from "mod"
- recordModuleName();
- }
- }
- }
- }
+ }
+ else {
+ // unknown syntax
+ return true;
}
}
- }
- else if (token === 82 /* ExportKeyword */) {
- token = scanner.scan();
if (token === 15 /* OpenBraceToken */) {
token = scanner.scan();
// consume "{ a as B, c, d as D}" clauses
- while (token !== 16 /* CloseBraceToken */) {
+ // make sure that it stops on EOF
+ while (token !== 16 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
token = scanner.scan();
}
if (token === 16 /* CloseBraceToken */) {
@@ -45074,49 +45532,171 @@ var ts;
if (token === 133 /* FromKeyword */) {
token = scanner.scan();
if (token === 9 /* StringLiteral */) {
- // export {a as A} from "mod";
- // export {a, b as B} from "mod"
+ // import {a as A} from "mod";
+ // import d, {a, b as B} from "mod"
recordModuleName();
}
}
}
}
else if (token === 37 /* AsteriskToken */) {
+ token = scanner.scan();
+ if (token === 116 /* AsKeyword */) {
+ token = scanner.scan();
+ if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
+ token = scanner.scan();
+ if (token === 133 /* FromKeyword */) {
+ token = scanner.scan();
+ if (token === 9 /* StringLiteral */) {
+ // import * as NS from "mod"
+ // import d, * as NS from "mod"
+ recordModuleName();
+ }
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeExport() {
+ var token = scanner.getToken();
+ if (token === 82 /* ExportKeyword */) {
+ token = scanner.scan();
+ if (token === 15 /* OpenBraceToken */) {
+ token = scanner.scan();
+ // consume "{ a as B, c, d as D}" clauses
+ // make sure it stops on EOF
+ while (token !== 16 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
+ token = scanner.scan();
+ }
+ if (token === 16 /* CloseBraceToken */) {
token = scanner.scan();
if (token === 133 /* FromKeyword */) {
token = scanner.scan();
if (token === 9 /* StringLiteral */) {
- // export * from "mod"
+ // export {a as A} from "mod";
+ // export {a, b as B} from "mod"
recordModuleName();
}
}
}
- else if (token === 89 /* ImportKeyword */) {
+ }
+ else if (token === 37 /* AsteriskToken */) {
+ token = scanner.scan();
+ if (token === 133 /* FromKeyword */) {
token = scanner.scan();
- if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
- token = scanner.scan();
- if (token === 56 /* EqualsToken */) {
- token = scanner.scan();
- if (token === 127 /* RequireKeyword */) {
- token = scanner.scan();
- if (token === 17 /* OpenParenToken */) {
- token = scanner.scan();
- if (token === 9 /* StringLiteral */) {
- // export import i = require("mod");
- recordModuleName();
- }
- }
- }
+ if (token === 9 /* StringLiteral */) {
+ // export * from "mod"
+ recordModuleName();
+ }
+ }
+ }
+ else if (token === 89 /* ImportKeyword */) {
+ token = scanner.scan();
+ if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
+ token = scanner.scan();
+ if (token === 56 /* EqualsToken */) {
+ if (tryConsumeRequireCall(/* skipCurrentToken */ true)) {
+ return true;
}
}
}
}
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeRequireCall(skipCurrentToken) {
+ var token = skipCurrentToken ? scanner.scan() : scanner.getToken();
+ if (token === 127 /* RequireKeyword */) {
+ token = scanner.scan();
+ if (token === 17 /* OpenParenToken */) {
+ token = scanner.scan();
+ if (token === 9 /* StringLiteral */) {
+ // require("mod");
+ recordModuleName();
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+ function tryConsumeDefine() {
+ var token = scanner.getToken();
+ if (token === 69 /* Identifier */ && scanner.getTokenValue() === "define") {
+ token = scanner.scan();
+ if (token !== 17 /* OpenParenToken */) {
+ return true;
+ }
token = scanner.scan();
+ if (token === 9 /* StringLiteral */) {
+ // looks like define ("modname", ... - skip string literal and comma
+ token = scanner.scan();
+ if (token === 24 /* CommaToken */) {
+ token = scanner.scan();
+ }
+ else {
+ // unexpected token
+ return true;
+ }
+ }
+ // should be start of dependency list
+ if (token !== 19 /* OpenBracketToken */) {
+ return true;
+ }
+ // skip open bracket
+ token = scanner.scan();
+ var i = 0;
+ // scan until ']' or EOF
+ while (token !== 20 /* CloseBracketToken */ && token !== 1 /* EndOfFileToken */) {
+ // record string literals as module names
+ if (token === 9 /* StringLiteral */) {
+ recordModuleName();
+ i++;
+ }
+ token = scanner.scan();
+ }
+ return true;
+ }
+ return false;
+ }
+ function processImports() {
+ scanner.setText(sourceText);
+ scanner.scan();
+ // Look for:
+ // import "mod";
+ // import d from "mod"
+ // import {a as A } from "mod";
+ // import * as NS from "mod"
+ // import d, {a, b as B} from "mod"
+ // import i = require("mod");
+ //
+ // export * from "mod"
+ // export {a as b} from "mod"
+ // export import i = require("mod")
+ // (for JavaScript files) require("mod")
+ while (true) {
+ if (scanner.getToken() === 1 /* EndOfFileToken */) {
+ break;
+ }
+ // check if at least one of alternative have moved scanner forward
+ if (tryConsumeDeclare() ||
+ tryConsumeImport() ||
+ tryConsumeExport() ||
+ (detectJavaScriptImports && (tryConsumeRequireCall(/* skipCurrentToken */ false) || tryConsumeDefine()))) {
+ continue;
+ }
+ else {
+ scanner.scan();
+ }
}
scanner.setText(undefined);
}
if (readImportFiles) {
- processImport();
+ processImports();
}
processTripleSlashDirectives();
return { referencedFiles: referencedFiles, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientExternalModules };
@@ -45547,7 +46127,7 @@ var ts;
// For JavaScript files, we don't want to report the normal typescript semantic errors.
// Instead, we just report errors for using TypeScript-only constructs from within a
// JavaScript file.
- if (ts.isJavaScript(fileName)) {
+ if (ts.isSourceFileJavaScript(targetSourceFile)) {
return getJavaScriptSemanticDiagnostics(targetSourceFile);
}
// Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
@@ -45759,7 +46339,7 @@ var ts;
var typeChecker = program.getTypeChecker();
var syntacticStart = new Date().getTime();
var sourceFile = getValidSourceFile(fileName);
- var isJavaScriptFile = ts.isJavaScript(fileName);
+ var isJavaScriptFile = ts.isSourceFileJavaScript(sourceFile);
var isJsDocTagName = false;
var start = new Date().getTime();
var currentToken = ts.getTokenAtPosition(sourceFile, position);
@@ -46393,8 +46973,8 @@ var ts;
if (element.getStart() <= position && position <= element.getEnd()) {
continue;
}
- var name_33 = element.propertyName || element.name;
- exisingImportsOrExports[name_33.text] = true;
+ var name_35 = element.propertyName || element.name;
+ exisingImportsOrExports[name_35.text] = true;
}
if (ts.isEmpty(exisingImportsOrExports)) {
return exportsOfModule;
@@ -46426,7 +47006,10 @@ var ts;
}
var existingName = void 0;
if (m.kind === 163 /* BindingElement */ && m.propertyName) {
- existingName = m.propertyName.text;
+ // include only identifiers in completion list
+ if (m.propertyName.kind === 69 /* Identifier */) {
+ existingName = m.propertyName.text;
+ }
}
else {
// TODO(jfreeman): Account for computed property name
@@ -46466,46 +47049,43 @@ var ts;
return undefined;
}
var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName;
- var entries;
if (isJsDocTagName) {
// If the current position is a jsDoc tag name, only tag names should be provided for completion
return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() };
}
- if (isRightOfDot && ts.isJavaScript(fileName)) {
- entries = getCompletionEntriesFromSymbols(symbols);
- ts.addRange(entries, getJavaScriptCompletionEntries());
+ var sourceFile = getValidSourceFile(fileName);
+ var entries = [];
+ if (isRightOfDot && ts.isSourceFileJavaScript(sourceFile)) {
+ var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries);
+ ts.addRange(entries, getJavaScriptCompletionEntries(sourceFile, uniqueNames));
}
else {
if (!symbols || symbols.length === 0) {
return undefined;
}
- entries = getCompletionEntriesFromSymbols(symbols);
+ getCompletionEntriesFromSymbols(symbols, entries);
}
// Add keywords if this is not a member completion list
if (!isMemberCompletion && !isJsDocTagName) {
ts.addRange(entries, keywordCompletions);
}
return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
- function getJavaScriptCompletionEntries() {
+ function getJavaScriptCompletionEntries(sourceFile, uniqueNames) {
var entries = [];
- var allNames = {};
var target = program.getCompilerOptions().target;
- for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
- var sourceFile = _a[_i];
- var nameTable = getNameTable(sourceFile);
- for (var name_34 in nameTable) {
- if (!allNames[name_34]) {
- allNames[name_34] = name_34;
- var displayName = getCompletionEntryDisplayName(name_34, target, /*performCharacterChecks:*/ true);
- if (displayName) {
- var entry = {
- name: displayName,
- kind: ScriptElementKind.warning,
- kindModifiers: "",
- sortText: "1"
- };
- entries.push(entry);
- }
+ var nameTable = getNameTable(sourceFile);
+ for (var name_36 in nameTable) {
+ if (!uniqueNames[name_36]) {
+ uniqueNames[name_36] = name_36;
+ var displayName = getCompletionEntryDisplayName(name_36, target, /*performCharacterChecks:*/ true);
+ if (displayName) {
+ var entry = {
+ name: displayName,
+ kind: ScriptElementKind.warning,
+ kindModifiers: "",
+ sortText: "1"
+ };
+ entries.push(entry);
}
}
}
@@ -46543,25 +47123,24 @@ var ts;
sortText: "0"
};
}
- function getCompletionEntriesFromSymbols(symbols) {
+ function getCompletionEntriesFromSymbols(symbols, entries) {
var start = new Date().getTime();
- var entries = [];
+ var uniqueNames = {};
if (symbols) {
- var nameToSymbol = {};
for (var _i = 0, symbols_3 = symbols; _i < symbols_3.length; _i++) {
var symbol = symbols_3[_i];
var entry = createCompletionEntry(symbol, location);
if (entry) {
var id = ts.escapeIdentifier(entry.name);
- if (!ts.lookUp(nameToSymbol, id)) {
+ if (!ts.lookUp(uniqueNames, id)) {
entries.push(entry);
- nameToSymbol[id] = symbol;
+ uniqueNames[id] = id;
}
}
}
}
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
- return entries;
+ return uniqueNames;
}
}
function getCompletionEntryDetails(fileName, position, entryName) {
@@ -46762,16 +47341,16 @@ var ts;
case ScriptElementKind.parameterElement:
case ScriptElementKind.localVariableElement:
// If it is call or construct signature of lambda's write type name
- displayParts.push(ts.punctuationPart(54 /* ColonToken */));
+ displayParts.push(ts.punctuationPart(ts.SyntaxKind.ColonToken));
displayParts.push(ts.spacePart());
if (useConstructSignatures) {
- displayParts.push(ts.keywordPart(92 /* NewKeyword */));
+ displayParts.push(ts.keywordPart(ts.SyntaxKind.NewKeyword));
displayParts.push(ts.spacePart());
}
- if (!(type.flags & 65536 /* Anonymous */)) {
- ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */));
+ if (!(type.flags & ts.TypeFlags.Anonymous)) {
+ ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, ts.SymbolFormatFlags.WriteTypeParametersOrArguments));
}
- addSignatureDisplayParts(signature, allSignatures, 8 /* WriteArrowStyleSignature */);
+ addSignatureDisplayParts(signature, allSignatures, ts.TypeFormatFlags.WriteArrowStyleSignature);
break;
default:
// Just signature
@@ -48396,19 +48975,19 @@ var ts;
if (isNameOfPropertyAssignment(node)) {
var objectLiteral = node.parent.parent;
var contextualType = typeChecker.getContextualType(objectLiteral);
- var name_35 = node.text;
+ var name_37 = node.text;
if (contextualType) {
if (contextualType.flags & 16384 /* Union */) {
// This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types)
// if not, search the constituent types for the property
- var unionProperty = contextualType.getProperty(name_35);
+ var unionProperty = contextualType.getProperty(name_37);
if (unionProperty) {
return [unionProperty];
}
else {
var result_4 = [];
ts.forEach(contextualType.types, function (t) {
- var symbol = t.getProperty(name_35);
+ var symbol = t.getProperty(name_37);
if (symbol) {
result_4.push(symbol);
}
@@ -48417,7 +48996,7 @@ var ts;
}
}
else {
- var symbol_1 = contextualType.getProperty(name_35);
+ var symbol_1 = contextualType.getProperty(name_37);
if (symbol_1) {
return [symbol_1];
}
@@ -48828,6 +49407,9 @@ var ts;
case 16 /* typeAliasName */: return ClassificationTypeNames.typeAliasName;
case 17 /* parameterName */: return ClassificationTypeNames.parameterName;
case 18 /* docCommentTagName */: return ClassificationTypeNames.docCommentTagName;
+ case 19 /* jsxOpenTagName */: return ClassificationTypeNames.jsxOpenTagName;
+ case 20 /* jsxCloseTagName */: return ClassificationTypeNames.jsxCloseTagName;
+ case 21 /* jsxSelfClosingTagName */: return ClassificationTypeNames.jsxSelfClosingTagName;
}
}
function convertClassifications(classifications) {
@@ -49097,6 +49679,21 @@ var ts;
return 17 /* parameterName */;
}
return;
+ case 235 /* JsxOpeningElement */:
+ if (token.parent.tagName === token) {
+ return 19 /* jsxOpenTagName */;
+ }
+ return;
+ case 237 /* JsxClosingElement */:
+ if (token.parent.tagName === token) {
+ return 20 /* jsxCloseTagName */;
+ }
+ return;
+ case 234 /* JsxSelfClosingElement */:
+ if (token.parent.tagName === token) {
+ return 21 /* jsxSelfClosingTagName */;
+ }
+ return;
}
}
return 2 /* identifier */;
@@ -50021,18 +50618,8 @@ var ts;
ts.getDefaultLibFilePath = getDefaultLibFilePath;
function initializeServices() {
ts.objectAllocator = {
- getNodeConstructor: function (kind) {
- function Node(pos, end) {
- this.pos = pos;
- this.end = end;
- this.flags = 0 /* None */;
- this.parent = undefined;
- }
- var proto = kind === 248 /* SourceFile */ ? new SourceFileObject() : new NodeObject();
- proto.kind = kind;
- Node.prototype = proto;
- return Node;
- },
+ getNodeConstructor: function () { return NodeObject; },
+ getSourceFileConstructor: function () { return SourceFileObject; },
getSymbolConstructor: function () { return SymbolObject; },
getTypeConstructor: function () { return TypeObject; },
getSignatureConstructor: function () { return SignatureObject; }
@@ -51102,7 +51689,8 @@ var ts;
};
CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) {
return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () {
- var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()));
+ // for now treat files as JavaScript
+ var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true);
var convertResult = {
referencedFiles: [],
importedFiles: [],
@@ -51166,7 +51754,7 @@ var ts;
TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) {
try {
if (this.documentRegistry === undefined) {
- this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
+ this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory());
}
var hostAdapter = new LanguageServiceShimHostAdapter(host);
var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry);
@@ -51199,7 +51787,7 @@ var ts;
TypeScriptServicesFactory.prototype.close = function () {
// Forget all the registered shims
this._shims = [];
- this.documentRegistry = ts.createDocumentRegistry();
+ this.documentRegistry = undefined;
};
TypeScriptServicesFactory.prototype.registerShim = function (shim) {
this._shims.push(shim);
diff --git a/package.json b/package.json
index 7b8abfaae43f7..261cdfa64b7d1 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,8 @@
"browserify": "latest",
"istanbul": "latest",
"mocha-fivemat-progress-reporter": "latest",
- "tslint": "latest",
+ "tslint": "next",
+ "typescript": "next",
"tsd": "latest"
},
"scripts": {
diff --git a/scripts/tslint/booleanTriviaRule.ts b/scripts/tslint/booleanTriviaRule.ts
index be32a870ff4b2..93c312ab8708a 100644
--- a/scripts/tslint/booleanTriviaRule.ts
+++ b/scripts/tslint/booleanTriviaRule.ts
@@ -1,6 +1,5 @@
-///
-///
-
+import * as Lint from "tslint/lib/lint";
+import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {
public static FAILURE_STRING_FACTORY = (name: string, currently: string) => `Tag boolean argument as '${name}' (currently '${currently}')`;
@@ -19,7 +18,7 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
visitCallExpression(node: ts.CallExpression) {
super.visitCallExpression(node);
- if (node.arguments) {
+ if (node.arguments) {
const targetCallSignature = this.checker.getResolvedSignature(node);
if (!!targetCallSignature) {
const targetParameters = targetCallSignature.getParameters();
@@ -37,7 +36,7 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
let triviaContent: string;
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
if (ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia) {
- triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); //+/-2 to remove /**/
+ triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); // +/-2 to remove /**/
}
if (triviaContent !== param.getName()) {
this.addFailure(this.createFailure(arg.getStart(source), arg.getWidth(source), Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent)));
@@ -45,6 +44,6 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
}
}
}
- }
+ }
}
}
diff --git a/scripts/tslint/nextLineRule.ts b/scripts/tslint/nextLineRule.ts
index 6d803fc7f8810..d25652f7bce6e 100644
--- a/scripts/tslint/nextLineRule.ts
+++ b/scripts/tslint/nextLineRule.ts
@@ -1,5 +1,5 @@
-///
-///
+import * as Lint from "tslint/lib/lint";
+import * as ts from "typescript";
const OPTION_CATCH = "check-catch";
const OPTION_ELSE = "check-else";
diff --git a/scripts/tslint/noNullRule.ts b/scripts/tslint/noNullRule.ts
index 2a2c5bc371778..8e9deca996b5e 100644
--- a/scripts/tslint/noNullRule.ts
+++ b/scripts/tslint/noNullRule.ts
@@ -1,5 +1,5 @@
-///
-///
+import * as Lint from "tslint/lib/lint";
+import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {
diff --git a/scripts/tslint/preferConstRule.ts b/scripts/tslint/preferConstRule.ts
index 29160a9c634f5..aaa1b0e53d5b8 100644
--- a/scripts/tslint/preferConstRule.ts
+++ b/scripts/tslint/preferConstRule.ts
@@ -1,5 +1,5 @@
-///
-///
+import * as Lint from "tslint/lib/lint";
+import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {
@@ -85,12 +85,12 @@ class PreferConstWalker extends Lint.RuleWalker {
visitBinaryExpression(node: ts.BinaryExpression) {
if (isAssignmentOperator(node.operatorToken.kind)) {
- this.visitLHSExpressions(node.left);
+ this.visitLeftHandSideExpression(node.left);
}
super.visitBinaryExpression(node);
}
- private visitLHSExpressions(node: ts.Expression) {
+ private visitLeftHandSideExpression(node: ts.Expression) {
while (node.kind === ts.SyntaxKind.ParenthesizedExpression) {
node = (node as ts.ParenthesizedExpression).expression;
}
@@ -101,23 +101,25 @@ class PreferConstWalker extends Lint.RuleWalker {
this.visitBindingLiteralExpression(node as (ts.ArrayLiteralExpression | ts.ObjectLiteralExpression));
}
}
-
+
private visitBindingLiteralExpression(node: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression) {
if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) {
const pattern = node as ts.ObjectLiteralExpression;
for (const element of pattern.properties) {
- if (element.name.kind === ts.SyntaxKind.Identifier) {
- this.markAssignment(element.name as ts.Identifier)
+ const kind = element.kind;
+
+ if (kind === ts.SyntaxKind.ShorthandPropertyAssignment) {
+ this.markAssignment((element as ts.ShorthandPropertyAssignment).name);
}
- else if (isBindingPattern(element.name)) {
- this.visitBindingPatternIdentifiers(element.name as ts.BindingPattern);
+ else if (kind === ts.SyntaxKind.PropertyAssignment) {
+ this.visitLeftHandSideExpression((element as ts.PropertyAssignment).initializer);
}
}
}
else if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
const pattern = node as ts.ArrayLiteralExpression;
for (const element of pattern.elements) {
- this.visitLHSExpressions(element);
+ this.visitLeftHandSideExpression(element);
}
}
}
@@ -145,7 +147,7 @@ class PreferConstWalker extends Lint.RuleWalker {
private visitAnyUnaryExpression(node: ts.PrefixUnaryExpression | ts.PostfixUnaryExpression) {
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) {
- this.visitLHSExpressions(node.operand);
+ this.visitLeftHandSideExpression(node.operand);
}
}
@@ -211,12 +213,12 @@ class PreferConstWalker extends Lint.RuleWalker {
}
}
- private collectNameIdentifiers(value: ts.VariableDeclaration, node: ts.Identifier | ts.BindingPattern, table: ts.Map) {
+ private collectNameIdentifiers(declaration: ts.VariableDeclaration, node: ts.Identifier | ts.BindingPattern, table: ts.Map) {
if (node.kind === ts.SyntaxKind.Identifier) {
- table[(node as ts.Identifier).text] = {declaration: value, usages: 0};
+ table[(node as ts.Identifier).text] = { declaration, usages: 0 };
}
else {
- this.collectBindingPatternIdentifiers(value, node as ts.BindingPattern, table);
+ this.collectBindingPatternIdentifiers(declaration, node as ts.BindingPattern, table);
}
}
diff --git a/scripts/tslint/typeOperatorSpacingRule.ts b/scripts/tslint/typeOperatorSpacingRule.ts
index 239254933400a..7ceef2372bf87 100644
--- a/scripts/tslint/typeOperatorSpacingRule.ts
+++ b/scripts/tslint/typeOperatorSpacingRule.ts
@@ -1,5 +1,5 @@
-///
-///
+import * as Lint from "tslint/lib/lint";
+import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {
@@ -13,10 +13,10 @@ export class Rule extends Lint.Rules.AbstractRule {
class TypeOperatorSpacingWalker extends Lint.RuleWalker {
public visitNode(node: ts.Node) {
if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) {
- let types = (node).types;
+ const types = (node).types;
let expectedStart = types[0].end + 2; // space, | or &
for (let i = 1; i < types.length; i++) {
- let currentType = types[i];
+ const currentType = types[i];
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
this.addFailure(failure);
diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 49b259ea695b9..86fcc809d5850 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -139,6 +139,8 @@ namespace ts {
file.classifiableNames = classifiableNames;
}
+ file = undefined;
+ options = undefined;
parent = undefined;
container = undefined;
blockScopeContainer = undefined;
@@ -175,9 +177,14 @@ namespace ts {
symbol.members = {};
}
- if (symbolFlags & SymbolFlags.Value && !symbol.valueDeclaration) {
- symbol.valueDeclaration = node;
- }
+ if (symbolFlags & SymbolFlags.Value) {
+ const valueDeclaration = symbol.valueDeclaration;
+ if (!valueDeclaration ||
+ (valueDeclaration.kind !== node.kind && valueDeclaration.kind === SyntaxKind.ModuleDeclaration)) {
+ // other kinds of value declarations take precedence over modules
+ symbol.valueDeclaration = node;
+ }
+ }
}
// Should not be called on a declaration with a computed property name,
@@ -189,6 +196,11 @@ namespace ts {
}
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
const nameExpression = (node.name).expression;
+ // treat computed property names where expression is string/numeric literal as just string/numeric literal
+ if (isStringOrNumericLiteral(nameExpression.kind)) {
+ return (nameExpression).text;
+ }
+
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
return getPropertyNameForKnownSymbolName((nameExpression).name.text);
}
@@ -210,8 +222,21 @@ namespace ts {
case SyntaxKind.ExportAssignment:
return (node).isExportEquals ? "export=" : "default";
case SyntaxKind.BinaryExpression:
- // Binary expression case is for JS module 'module.exports = expr'
- return "export=";
+ switch (getSpecialPropertyAssignmentKind(node)) {
+ case SpecialPropertyAssignmentKind.ModuleExports:
+ // module.exports = ...
+ return "export=";
+ case SpecialPropertyAssignmentKind.ExportsProperty:
+ case SpecialPropertyAssignmentKind.ThisProperty:
+ // exports.x = ... or this.y = ...
+ return ((node as BinaryExpression).left as PropertyAccessExpression).name.text;
+ case SpecialPropertyAssignmentKind.PrototypeProperty:
+ // className.prototype.methodName = ...
+ return (((node as BinaryExpression).left as PropertyAccessExpression).expression as PropertyAccessExpression).name.text;
+ }
+ Debug.fail("Unknown binary declaration kind");
+ break;
+
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ClassDeclaration:
return node.flags & NodeFlags.Default ? "default" : undefined;
@@ -445,7 +470,7 @@ namespace ts {
/**
* Returns true if node and its subnodes were successfully traversed.
- * Returning false means that node was not examined and caller needs to dive into the node himself.
+ * Returning false means that node was not examined and caller needs to dive into the node himself.
*/
function bindReachableStatement(node: Node): void {
if (checkUnreachable(node)) {
@@ -555,7 +580,7 @@ namespace ts {
}
function bindIfStatement(n: IfStatement): void {
- // denotes reachability state when entering 'thenStatement' part of the if statement:
+ // denotes reachability state when entering 'thenStatement' part of the if statement:
// i.e. if condition is false then thenStatement is unreachable
const ifTrueState = n.expression.kind === SyntaxKind.FalseKeyword ? Reachability.Unreachable : currentReachabilityState;
// denotes reachability state when entering 'elseStatement':
@@ -1154,11 +1179,25 @@ namespace ts {
return checkStrictModeIdentifier(node);
case SyntaxKind.BinaryExpression:
if (isInJavaScriptFile(node)) {
- if (isExportsPropertyAssignment(node)) {
- bindExportsPropertyAssignment(node);
- }
- else if (isModuleExportsAssignment(node)) {
- bindModuleExportsAssignment(node);
+ const specialKind = getSpecialPropertyAssignmentKind(node);
+ switch (specialKind) {
+ case SpecialPropertyAssignmentKind.ExportsProperty:
+ bindExportsPropertyAssignment(node);
+ break;
+ case SpecialPropertyAssignmentKind.ModuleExports:
+ bindModuleExportsAssignment(node);
+ break;
+ case SpecialPropertyAssignmentKind.PrototypeProperty:
+ bindPrototypePropertyAssignment(node);
+ break;
+ case SpecialPropertyAssignmentKind.ThisProperty:
+ bindThisPropertyAssignment(node);
+ break;
+ case SpecialPropertyAssignmentKind.None:
+ // Nothing to do
+ break;
+ default:
+ Debug.fail("Unknown special property assignment kind");
}
}
return checkStrictModeBinaryExpression(node);
@@ -1174,7 +1213,7 @@ namespace ts {
return checkStrictModePrefixUnaryExpression(node);
case SyntaxKind.WithStatement:
return checkStrictModeWithStatement(node);
- case SyntaxKind.ThisKeyword:
+ case SyntaxKind.ThisType:
seenThisKeyword = true;
return;
@@ -1327,6 +1366,45 @@ namespace ts {
bindExportAssignment(node);
}
+ function bindThisPropertyAssignment(node: BinaryExpression) {
+ if (container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) {
+ container.symbol.members = container.symbol.members || {};
+ declareClassMember(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
+ }
+ }
+
+ function bindPrototypePropertyAssignment(node: BinaryExpression) {
+ // We saw a node of the form 'x.prototype.y = z'.
+ // This does two things: turns 'x' into a constructor function, and
+ // adds a member 'y' to the result of that constructor function
+ // Get 'x', the class
+ const classId = ((node.left).expression).expression;
+
+ // Look up the function in the local scope, since prototype assignments should immediately
+ // follow the function declaration
+ const funcSymbol = container.locals[classId.text];
+ if (!funcSymbol) {
+ return;
+ }
+
+ // The function is now a constructor rather than a normal function
+ if (!funcSymbol.inferredConstructor) {
+ // Have the binder set up all the related class symbols for us
+ declareSymbol(container.locals, funcSymbol, funcSymbol.valueDeclaration, SymbolFlags.Class, SymbolFlags.None);
+ // funcSymbol.members = funcSymbol.members || {};
+ funcSymbol.members["__constructor"] = funcSymbol;
+ funcSymbol.inferredConstructor = true;
+ }
+
+ // Get the exports of the class so we can add the method to it
+ const funcExports = declareSymbol(funcSymbol.exports, funcSymbol, (node.left).expression, SymbolFlags.ObjectLiteral | SymbolFlags.Property, SymbolFlags.None);
+
+ // Declare the method
+ declareSymbol(funcExports.members, funcExports, node.left, SymbolFlags.Method, SymbolFlags.None);
+ // and on the members of the function so it appears in 'prototype'
+ declareSymbol(funcSymbol.members, funcSymbol, node.left, SymbolFlags.Method, SymbolFlags.PropertyExcludes);
+ }
+
function bindCallExpression(node: CallExpression) {
// We're only inspecting call expressions to detect CommonJS modules, so we can skip
// this check if we've already seen the module indicator
@@ -1523,7 +1601,7 @@ namespace ts {
// unreachable code is reported if
// - user has explicitly asked about it AND
- // - statement is in not ambient context (statements in ambient context is already an error
+ // - statement is in not ambient context (statements in ambient context is already an error
// so we should not report extras) AND
// - node is not variable statement OR
// - node is block scoped variable statement OR
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index b73543e14de99..94c13fd1f3f77 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -46,6 +46,7 @@ namespace ts {
const compilerOptions = host.getCompilerOptions();
const languageVersion = compilerOptions.target || ScriptTarget.ES3;
const modulekind = compilerOptions.module ? compilerOptions.module : languageVersion === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
+ const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System;
const emitResolver = createResolver();
@@ -109,9 +110,9 @@ namespace ts {
const undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined");
const nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefinedOrNull, "null");
const unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
- const circularType = createIntrinsicType(TypeFlags.Any, "__circular__");
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
+ const emptyUnionType = emptyObjectType;
const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
emptyGenericType.instantiations = {};
@@ -122,8 +123,8 @@ namespace ts {
const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
- const anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false);
- const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, false, false);
+ const anySignature = createSignature(undefined, undefined, emptyArray, undefined, anyType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
+ const unknownSignature = createSignature(undefined, undefined, emptyArray, undefined, unknownType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
const globals: SymbolTable = {};
@@ -200,6 +201,10 @@ namespace ts {
"symbol": {
type: esSymbolType,
flags: TypeFlags.ESSymbol
+ },
+ "undefined": {
+ type: undefinedType,
+ flags: TypeFlags.ContainsUndefinedOrNull
}
};
@@ -295,7 +300,12 @@ namespace ts {
target.constEnumOnlyModule = false;
}
target.flags |= source.flags;
- if (!target.valueDeclaration && source.valueDeclaration) target.valueDeclaration = source.valueDeclaration;
+ if (source.valueDeclaration &&
+ (!target.valueDeclaration ||
+ (target.valueDeclaration.kind === SyntaxKind.ModuleDeclaration && source.valueDeclaration.kind !== SyntaxKind.ModuleDeclaration))) {
+ // other kinds of value declarations take precedence over modules
+ target.valueDeclaration = source.valueDeclaration;
+ }
forEach(source.declarations, node => {
target.declarations.push(node);
});
@@ -467,15 +477,41 @@ namespace ts {
// Locals of a source file are not in scope (because they get merged into the global symbol table)
if (location.locals && !isGlobalSourceFile(location)) {
if (result = getSymbol(location.locals, name, meaning)) {
- // Type parameters of a function are in scope in the entire function declaration, including the parameter
- // list and return type. However, local types are only in scope in the function body.
- if (!(meaning & SymbolFlags.Type) ||
- !(result.flags & (SymbolFlags.Type & ~SymbolFlags.TypeParameter)) ||
- !isFunctionLike(location) ||
- lastLocation === (location).body) {
+ let useResult = true;
+ if (isFunctionLike(location) && lastLocation && lastLocation !== (location).body) {
+ // symbol lookup restrictions for function-like declarations
+ // - Type parameters of a function are in scope in the entire function declaration, including the parameter
+ // list and return type. However, local types are only in scope in the function body.
+ // - parameters are only in the scope of function body
+ if (meaning & result.flags & SymbolFlags.Type) {
+ useResult = result.flags & SymbolFlags.TypeParameter
+ // type parameters are visible in parameter list, return type and type parameter list
+ ? lastLocation === (location).type ||
+ lastLocation.kind === SyntaxKind.Parameter ||
+ lastLocation.kind === SyntaxKind.TypeParameter
+ // local types not visible outside the function body
+ : false;
+ }
+ if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) {
+ // parameters are visible only inside function body, parameter list and return type
+ // technically for parameter list case here we might mix parameters and variables declared in function,
+ // however it is detected separately when checking initializers of parameters
+ // to make sure that they reference no variables declared after them.
+ useResult =
+ lastLocation.kind === SyntaxKind.Parameter ||
+ (
+ lastLocation === (location).type &&
+ result.valueDeclaration.kind === SyntaxKind.Parameter
+ );
+ }
+ }
+
+ if (useResult) {
break loop;
}
- result = undefined;
+ else {
+ result = undefined;
+ }
}
}
switch (location.kind) {
@@ -486,9 +522,19 @@ namespace ts {
if (location.kind === SyntaxKind.SourceFile ||
(location.kind === SyntaxKind.ModuleDeclaration && (location).name.kind === SyntaxKind.StringLiteral)) {
- // It's an external module. Because of module/namespace merging, a module's exports are in scope,
- // yet we never want to treat an export specifier as putting a member in scope. Therefore,
- // if the name we find is purely an export specifier, it is not actually considered in scope.
+ // It's an external module. First see if the module has an export default and if the local
+ // name of that export default matches.
+ if (result = moduleExports["default"]) {
+ const localSymbol = getLocalSymbolForExportDefault(result);
+ if (localSymbol && (result.flags & meaning) && localSymbol.name === name) {
+ break loop;
+ }
+ result = undefined;
+ }
+
+ // Because of module/namespace merging, a module's exports are in scope,
+ // yet we never want to treat an export specifier as putting a member in scope.
+ // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
// Two things to note about this:
// 1. We have to check this without calling getSymbol. The problem with calling getSymbol
// on an export specifier is that it might find the export specifier itself, and try to
@@ -502,13 +548,6 @@ namespace ts {
getDeclarationOfKind(moduleExports[name], SyntaxKind.ExportSpecifier)) {
break;
}
-
- result = moduleExports["default"];
- const localSymbol = getLocalSymbolForExportDefault(result);
- if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
- break loop;
- }
- result = undefined;
}
if (result = getSymbol(moduleExports, name, meaning & SymbolFlags.ModuleMember)) {
@@ -730,9 +769,12 @@ namespace ts {
const moduleSymbol = resolveExternalModuleName(node, (node.parent).moduleSpecifier);
if (moduleSymbol) {
const exportDefaultSymbol = resolveSymbol(moduleSymbol.exports["default"]);
- if (!exportDefaultSymbol) {
+ if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
}
+ else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
+ return resolveSymbol(moduleSymbol.exports["export="]) || resolveSymbol(moduleSymbol);
+ }
return exportDefaultSymbol;
}
}
@@ -990,16 +1032,12 @@ namespace ts {
// Module names are escaped in our symbol table. However, string literal values aren't.
// Escape the name in the "require(...)" clause to ensure we find the right symbol.
- let moduleName = escapeIdentifier(moduleReferenceLiteral.text);
+ const moduleName = escapeIdentifier(moduleReferenceLiteral.text);
if (moduleName === undefined) {
return;
}
- if (moduleName.indexOf("!") >= 0) {
- moduleName = moduleName.substr(0, moduleName.indexOf("!"));
- }
-
const isRelative = isExternalModuleNameRelative(moduleName);
if (!isRelative) {
const symbol = getSymbol(globals, "\"" + moduleName + "\"", SymbolFlags.ValueModule);
@@ -1658,7 +1696,7 @@ namespace ts {
writeAnonymousType(type, flags);
}
else if (type.flags & TypeFlags.StringLiteral) {
- writer.writeStringLiteral((type).text);
+ writer.writeStringLiteral(`"${escapeString((type).text)}"`);
}
else {
// Should never get here
@@ -2264,7 +2302,7 @@ namespace ts {
return false;
}
resolutionTargets.push(target);
- resolutionResults.push(true);
+ resolutionResults.push(/*items*/ true);
resolutionPropertyNames.push(propertyName);
return true;
}
@@ -2342,6 +2380,26 @@ namespace ts {
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
}
+ function getTextOfPropertyName(name: PropertyName): string {
+ switch (name.kind) {
+ case SyntaxKind.Identifier:
+ return (name).text;
+ case SyntaxKind.StringLiteral:
+ case SyntaxKind.NumericLiteral:
+ return (name).text;
+ case SyntaxKind.ComputedPropertyName:
+ if (isStringOrNumericLiteral((name).expression.kind)) {
+ return ((name).expression).text;
+ }
+ }
+
+ return undefined;
+ }
+
+ function isComputedNonLiteralName(name: PropertyName): boolean {
+ return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((name).expression.kind);
+ }
+
// Return the inferred type for a binding element
function getTypeForBindingElement(declaration: BindingElement): Type {
const pattern = declaration.parent;
@@ -2364,10 +2422,17 @@ namespace ts {
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
const name = declaration.propertyName || declaration.name;
+ if (isComputedNonLiteralName(name)) {
+ // computed properties with non-literal names are treated as 'any'
+ return anyType;
+ }
+
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
// or otherwise the type of the string index signature.
- type = getTypeOfPropertyOfType(parentType, name.text) ||
- isNumericLiteralName(name.text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
+ const text = getTextOfPropertyName(name);
+
+ type = getTypeOfPropertyOfType(parentType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
getIndexTypeOfType(parentType, IndexKind.String);
if (!type) {
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name));
@@ -2478,10 +2543,18 @@ namespace ts {
// Return the type implied by an object binding pattern
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type {
const members: SymbolTable = {};
+ let hasComputedProperties = false;
forEach(pattern.elements, e => {
- const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0);
const name = e.propertyName || e.name;
- const symbol = createSymbol(flags, name.text);
+ if (isComputedNonLiteralName(name)) {
+ // do not include computed properties in the implied type
+ hasComputedProperties = true;
+ return;
+ }
+
+ const text = getTextOfPropertyName(name);
+ const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0);
+ const symbol = createSymbol(flags, text);
symbol.type = getTypeFromBindingElement(e, includePatternInType);
symbol.bindingElement = e;
members[symbol.name] = symbol;
@@ -2490,6 +2563,9 @@ namespace ts {
if (includePatternInType) {
result.pattern = pattern;
}
+ if (hasComputedProperties) {
+ result.flags |= TypeFlags.ObjectLiteralPatternWithComputedProperties;
+ }
return result;
}
@@ -2576,9 +2652,18 @@ namespace ts {
if (declaration.kind === SyntaxKind.BinaryExpression) {
return links.type = checkExpression((declaration).right);
}
- // Handle exports.p = expr
if (declaration.kind === SyntaxKind.PropertyAccessExpression) {
- return checkExpressionCached((declaration.parent).right);
+ // Declarations only exist for property access expressions for certain
+ // special assignment kinds
+ if (declaration.parent.kind === SyntaxKind.BinaryExpression) {
+ // Handle exports.p = expr or this.p = expr or className.prototype.method = expr
+ return links.type = checkExpressionCached((declaration.parent).right);
+ }
+ else {
+ // Declaration for className.prototype in inferred JS class
+ const type = createAnonymousType(symbol, symbol.members, emptyArray, emptyArray, undefined, undefined);
+ return links.type = type;
+ }
}
// Handle variable, parameter or property
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
@@ -2883,23 +2968,25 @@ namespace ts {
function resolveBaseTypesOfClass(type: InterfaceType): void {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
- const baseContructorType = getBaseConstructorTypeOfClass(type);
- if (!(baseContructorType.flags & TypeFlags.ObjectType)) {
+ const baseConstructorType = getBaseConstructorTypeOfClass(type);
+ if (!(baseConstructorType.flags & TypeFlags.ObjectType)) {
return;
}
const baseTypeNode = getBaseTypeNodeOfClass(type);
let baseType: Type;
- if (baseContructorType.symbol && baseContructorType.symbol.flags & SymbolFlags.Class) {
- // When base constructor type is a class we know that the constructors all have the same type parameters as the
+ const originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
+ if (baseConstructorType.symbol && baseConstructorType.symbol.flags & SymbolFlags.Class &&
+ areAllOuterTypeParametersApplied(originalBaseType)) {
+ // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
// class and all return the instance type of the class. There is no need for further checks and we can apply the
// type arguments in the same manner as a type reference to get the same error reporting experience.
- baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseContructorType.symbol);
+ baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
}
else {
// The class derives from a "class-like" constructor function, check that we have at least one construct signature
// with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
// we check that all instantiated signatures return the same type.
- const constructors = getInstantiatedConstructorsForTypeArguments(baseContructorType, baseTypeNode.typeArguments);
+ const constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments);
if (!constructors.length) {
error(baseTypeNode.expression, Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
return;
@@ -2926,6 +3013,18 @@ namespace ts {
}
}
+ function areAllOuterTypeParametersApplied(type: Type): boolean {
+ // An unapplied type parameter has its symbol still the same as the matching argument symbol.
+ // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
+ const outerTypeParameters = (type).outerTypeParameters;
+ if (outerTypeParameters) {
+ const last = outerTypeParameters.length - 1;
+ const typeArguments = (type).typeArguments;
+ return outerTypeParameters[last].symbol !== typeArguments[last].symbol;
+ }
+ return true;
+ }
+
function resolveBaseTypesOfInterface(type: InterfaceType): void {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
for (const declaration of type.symbol.declarations) {
@@ -3111,7 +3210,7 @@ namespace ts {
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
- case SyntaxKind.StringLiteral:
+ case SyntaxKind.StringLiteralType:
return true;
case SyntaxKind.ArrayType:
return isIndependentType((node).elementType);
@@ -3263,12 +3362,13 @@ namespace ts {
resolveObjectTypeMembers(type, source, typeParameters, typeArguments);
}
- function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[],
+ function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[], kind: SignatureKind,
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature {
const sig = new Signature(checker);
sig.declaration = declaration;
sig.typeParameters = typeParameters;
sig.parameters = parameters;
+ sig.kind = kind;
sig.resolvedReturnType = resolvedReturnType;
sig.typePredicate = typePredicate;
sig.minArgumentCount = minArgumentCount;
@@ -3278,13 +3378,13 @@ namespace ts {
}
function cloneSignature(sig: Signature): Signature {
- return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, sig.typePredicate,
+ return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.kind, sig.resolvedReturnType, sig.typePredicate,
sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals);
}
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
if (!hasClassBaseType(classType)) {
- return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)];
+ return [createSignature(undefined, classType.localTypeParameters, emptyArray, SignatureKind.Construct, classType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)];
}
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
@@ -3744,7 +3844,7 @@ namespace ts {
if (node.initializer) {
const signatureDeclaration = node.parent;
const signature = getSignatureFromDeclaration(signatureDeclaration);
- const parameterIndex = signatureDeclaration.parameters.indexOf(node);
+ const parameterIndex = ts.indexOf(signatureDeclaration.parameters, node);
Debug.assert(parameterIndex >= 0);
return parameterIndex >= signature.minArgumentCount;
}
@@ -3765,8 +3865,14 @@ namespace ts {
let minArgumentCount = -1;
for (let i = 0, n = declaration.parameters.length; i < n; i++) {
const param = declaration.parameters[i];
- parameters.push(param.symbol);
- if (param.type && param.type.kind === SyntaxKind.StringLiteral) {
+ let paramSymbol = param.symbol;
+ // Include parameter symbol instead of property symbol in the signature
+ if (paramSymbol && !!(paramSymbol.flags & SymbolFlags.Property) && !isBindingPattern(param.name)) {
+ const resolvedSymbol = resolveName(param, paramSymbol.name, SymbolFlags.Value, undefined, undefined);
+ paramSymbol = resolvedSymbol;
+ }
+ parameters.push(paramSymbol);
+ if (param.type && param.type.kind === SyntaxKind.StringLiteralType) {
hasStringLiterals = true;
}
@@ -3814,7 +3920,33 @@ namespace ts {
}
}
- links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, typePredicate,
+ let kind: SignatureKind;
+ switch (declaration.kind) {
+ case SyntaxKind.Constructor:
+ case SyntaxKind.ConstructSignature:
+ case SyntaxKind.ConstructorType:
+ kind = SignatureKind.Construct;
+ break;
+ default:
+ if (declaration.symbol.inferredConstructor) {
+ kind = SignatureKind.Construct;
+ const members = createSymbolTable(emptyArray);
+ // Collect methods declared with className.protoype.methodName = ...
+ const proto = declaration.symbol.exports["prototype"];
+ if (proto) {
+ mergeSymbolTable(members, proto.members);
+ }
+ // Collect properties defined in the constructor by this.propName = ...
+ mergeSymbolTable(members, declaration.symbol.members);
+ returnType = createAnonymousType(declaration.symbol, members, emptyArray, emptyArray, undefined, undefined);
+ }
+ else {
+ kind = SignatureKind.Call;
+ }
+ break;
+ }
+
+ links.resolvedSignature = createSignature(declaration, typeParameters, parameters, kind, returnType, typePredicate,
minArgumentCount, hasRestParameter(declaration), hasStringLiterals);
}
return links.resolvedSignature;
@@ -3822,7 +3954,7 @@ namespace ts {
function getSignaturesOfSymbol(symbol: Symbol): Signature[] {
if (!symbol) return emptyArray;
- const result: Signature[] = [];
+ let result: Signature[] = [];
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const node = symbol.declarations[i];
switch (node.kind) {
@@ -3849,6 +3981,12 @@ namespace ts {
}
}
result.push(getSignatureFromDeclaration(node));
+ break;
+
+ case SyntaxKind.PropertyAccessExpression:
+ // Inferred class method
+ result = getSignaturesOfType(checkExpressionCached((node.parent).right), SignatureKind.Call);
+ break;
}
}
return result;
@@ -3909,7 +4047,7 @@ namespace ts {
}
function getSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature {
- return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), true);
+ return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true);
}
function getErasedSignature(signature: Signature): Signature {
@@ -3919,7 +4057,7 @@ namespace ts {
signature.erasedSignatureCache = instantiateSignature(getErasedSignature(signature.target), signature.mapper);
}
else {
- signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), true);
+ signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
}
}
return signature.erasedSignatureCache;
@@ -3931,7 +4069,7 @@ namespace ts {
// object type literal or interface (using the new keyword). Each way of declaring a constructor
// will result in a different declaration kind.
if (!signature.isolatedSignatureType) {
- const isConstructor = signature.declaration.kind === SyntaxKind.Constructor || signature.declaration.kind === SyntaxKind.ConstructSignature;
+ const isConstructor = signature.kind === SignatureKind.Construct;
const type = createObjectType(TypeFlags.Anonymous | TypeFlags.FromSignature);
type.members = emptySymbols;
type.properties = emptyArray;
@@ -4149,12 +4287,12 @@ namespace ts {
// We only support expressions that are simple qualified names. For other expressions this produces undefined.
const typeNameOrExpression = node.kind === SyntaxKind.TypeReference ? (node).typeName :
isSupportedExpressionWithTypeArguments(node) ? (node).expression :
- undefined;
+ undefined;
const symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
const type = symbol === unknownSymbol ? unknownType :
symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) :
- symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
- getTypeFromNonGenericTypeReference(node, symbol);
+ symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
+ getTypeFromNonGenericTypeReference(node, symbol);
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
// type reference in checkTypeReferenceOrExpressionWithTypeArguments.
links.resolvedSymbol = symbol;
@@ -4358,7 +4496,7 @@ namespace ts {
// a named type that circularly references itself.
function getUnionType(types: Type[], noSubtypeReduction?: boolean): Type {
if (types.length === 0) {
- return emptyObjectType;
+ return emptyUnionType;
}
const typeSet: Type[] = [];
addTypesToSet(typeSet, types, TypeFlags.Union);
@@ -4435,20 +4573,20 @@ namespace ts {
return links.resolvedType;
}
- function getStringLiteralType(node: StringLiteral): StringLiteralType {
- if (hasProperty(stringLiteralTypes, node.text)) {
- return stringLiteralTypes[node.text];
+ function getStringLiteralTypeForText(text: string): StringLiteralType {
+ if (hasProperty(stringLiteralTypes, text)) {
+ return stringLiteralTypes[text];
}
- const type = stringLiteralTypes[node.text] = createType(TypeFlags.StringLiteral);
- type.text = getTextOfNode(node);
+ const type = stringLiteralTypes[text] = createType(TypeFlags.StringLiteral);
+ type.text = text;
return type;
}
- function getTypeFromStringLiteral(node: StringLiteral): Type {
+ function getTypeFromStringLiteralTypeNode(node: StringLiteralTypeNode): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
- links.resolvedType = getStringLiteralType(node);
+ links.resolvedType = getStringLiteralTypeForText(node.text);
}
return links.resolvedType;
}
@@ -4488,10 +4626,10 @@ namespace ts {
return esSymbolType;
case SyntaxKind.VoidKeyword:
return voidType;
- case SyntaxKind.ThisKeyword:
+ case SyntaxKind.ThisType:
return getTypeFromThisTypeNode(node);
- case SyntaxKind.StringLiteral:
- return getTypeFromStringLiteral(node);
+ case SyntaxKind.StringLiteralType:
+ return getTypeFromStringLiteralTypeNode(node);
case SyntaxKind.TypeReference:
return getTypeFromTypeReference(node);
case SyntaxKind.TypePredicate:
@@ -4634,6 +4772,7 @@ namespace ts {
}
const result = createSignature(signature.declaration, freshTypeParameters,
instantiateList(signature.parameters, mapper, instantiateSymbol),
+ signature.kind,
instantiateType(signature.resolvedReturnType, mapper),
freshTypePredicate,
signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
@@ -5012,7 +5151,7 @@ namespace ts {
}
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
- if (someConstituentTypeHasKind(target, TypeFlags.ObjectType)) {
+ if (!(target.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties) && someConstituentTypeHasKind(target, TypeFlags.ObjectType)) {
for (const prop of getPropertiesOfObjectType(source)) {
if (!isKnownProperty(target, prop.name)) {
if (reportErrors) {
@@ -5034,7 +5173,7 @@ namespace ts {
let result = Ternary.True;
const sourceTypes = source.types;
for (const sourceType of sourceTypes) {
- const related = typeRelatedToSomeType(sourceType, target, false);
+ const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
if (!related) {
return Ternary.False;
}
@@ -5131,9 +5270,12 @@ namespace ts {
const id = relation !== identityRelation || apparentSource.id < target.id ? apparentSource.id + "," + target.id : target.id + "," + apparentSource.id;
const related = relation[id];
if (related !== undefined) {
- // If we computed this relation already and it was failed and reported, or if we're not being asked to elaborate
- // errors, we can use the cached value. Otherwise, recompute the relation
- if (!elaborateErrors || (related === RelationComparisonResult.FailedAndReported)) {
+ if (elaborateErrors && related === RelationComparisonResult.Failed) {
+ // We are elaborating errors and the cached result is an unreported failure. Record the result as a reported
+ // failure and continue computing the relation such that errors get reported.
+ relation[id] = RelationComparisonResult.FailedAndReported;
+ }
+ else {
return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
}
}
@@ -5432,7 +5574,7 @@ namespace ts {
const saveErrorInfo = errorInfo;
let related = isRelatedTo(s, t, reportErrors);
if (!related) {
- related = isRelatedTo(t, s, false);
+ related = isRelatedTo(t, s, /*reportErrors*/ false);
if (!related) {
if (reportErrors) {
reportError(Diagnostics.Types_of_parameters_0_and_1_are_incompatible,
@@ -5559,7 +5701,7 @@ namespace ts {
let related: Ternary;
if (sourceStringType && sourceNumberType) {
// If we know for sure we're testing both string and numeric index types then only report errors from the second one
- related = isRelatedTo(sourceStringType, targetType, false) || isRelatedTo(sourceNumberType, targetType, reportErrors);
+ related = isRelatedTo(sourceStringType, targetType, /*reportErrors*/ false) || isRelatedTo(sourceNumberType, targetType, reportErrors);
}
else {
related = isRelatedTo(sourceStringType || sourceNumberType, targetType, reportErrors);
@@ -5769,6 +5911,10 @@ namespace ts {
return !!getPropertyOfType(type, "0");
}
+ function isStringLiteralType(type: Type) {
+ return type.flags & TypeFlags.StringLiteral;
+ }
+
/**
* Check if a Type was written as a tuple type literal.
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
@@ -5985,6 +6131,17 @@ namespace ts {
}
function inferFromTypes(source: Type, target: Type) {
+ if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
+ source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
+ // Source and target are both unions or both intersections. To improve the quality of
+ // inferences we first reduce the types by removing constituents that are identically
+ // matched by a constituent in the other type. For example, when inferring from
+ // 'string | string[]' to 'string | T', we reduce the types to 'string[]' and 'T'.
+ const reducedSource = reduceUnionOrIntersectionType(source, target);
+ const reducedTarget = reduceUnionOrIntersectionType(target, source);
+ source = reducedSource;
+ target = reducedTarget;
+ }
if (target.flags & TypeFlags.TypeParameter) {
// If target is a type parameter, make an inference, unless the source type contains
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
@@ -5995,7 +6152,6 @@ namespace ts {
if (source.flags & TypeFlags.ContainsAnyFunctionType) {
return;
}
-
const typeParameters = context.typeParameters;
for (let i = 0; i < typeParameters.length; i++) {
if (target === typeParameters[i]) {
@@ -6143,6 +6299,41 @@ namespace ts {
}
}
+ function typeIdenticalToSomeType(source: Type, target: UnionOrIntersectionType): boolean {
+ for (const t of target.types) {
+ if (isTypeIdenticalTo(source, t)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the reduced form of the source type. This type is computed by by removing all source
+ * constituents that have an identical match in the target type.
+ */
+ function reduceUnionOrIntersectionType(source: UnionOrIntersectionType, target: UnionOrIntersectionType) {
+ let sourceTypes = source.types;
+ let sourceIndex = 0;
+ let modified = false;
+ while (sourceIndex < sourceTypes.length) {
+ if (typeIdenticalToSomeType(sourceTypes[sourceIndex], target)) {
+ if (!modified) {
+ sourceTypes = sourceTypes.slice(0);
+ modified = true;
+ }
+ sourceTypes.splice(sourceIndex, 1);
+ }
+ else {
+ sourceIndex++;
+ }
+ }
+ if (modified) {
+ return source.flags & TypeFlags.Union ? getUnionType(sourceTypes, /*noSubtypeReduction*/ true) : getIntersectionType(sourceTypes);
+ }
+ return source;
+ }
+
function getInferenceCandidates(context: InferenceContext, index: number): Type[] {
const inferences = context.inferences[index];
return inferences.primary || inferences.secondary || emptyArray;
@@ -6225,27 +6416,6 @@ namespace ts {
Debug.fail("should not get here");
}
- // For a union type, remove all constituent types that are of the given type kind (when isOfTypeKind is true)
- // or not of the given type kind (when isOfTypeKind is false)
- function removeTypesFromUnionType(type: Type, typeKind: TypeFlags, isOfTypeKind: boolean, allowEmptyUnionResult: boolean): Type {
- if (type.flags & TypeFlags.Union) {
- const types = (type).types;
- if (forEach(types, t => !!(t.flags & typeKind) === isOfTypeKind)) {
- // Above we checked if we have anything to remove, now use the opposite test to do the removal
- const narrowedType = getUnionType(filter(types, t => !(t.flags & typeKind) === isOfTypeKind));
- if (allowEmptyUnionResult || narrowedType !== emptyObjectType) {
- return narrowedType;
- }
- }
- }
- else if (allowEmptyUnionResult && !!(type.flags & typeKind) === isOfTypeKind) {
- // Use getUnionType(emptyArray) instead of emptyObjectType in case the way empty union types
- // are represented ever changes.
- return getUnionType(emptyArray);
- }
- return type;
- }
-
function hasInitializer(node: VariableLikeDeclaration): boolean {
return !!(node.initializer || isBindingPattern(node.parent) && hasInitializer(node.parent.parent));
}
@@ -6347,53 +6517,70 @@ namespace ts {
// Only narrow when symbol is variable of type any or an object, union, or type parameter type
if (node && symbol.flags & SymbolFlags.Variable) {
if (isTypeAny(type) || type.flags & (TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter)) {
+ const declaration = getDeclarationOfKind(symbol, SyntaxKind.VariableDeclaration);
+ const top = declaration && getDeclarationContainer(declaration);
+ const originalType = type;
+ const nodeStack: {node: Node, child: Node}[] = [];
loop: while (node.parent) {
const child = node;
node = node.parent;
- let narrowedType = type;
+ switch (node.kind) {
+ case SyntaxKind.IfStatement:
+ case SyntaxKind.ConditionalExpression:
+ case SyntaxKind.BinaryExpression:
+ nodeStack.push({node, child});
+ break;
+ case SyntaxKind.SourceFile:
+ case SyntaxKind.ModuleDeclaration:
+ // Stop at the first containing file or module declaration
+ break loop;
+ }
+ if (node === top) {
+ break;
+ }
+ }
+
+ let nodes: {node: Node, child: Node};
+ while (nodes = nodeStack.pop()) {
+ const {node, child} = nodes;
switch (node.kind) {
case SyntaxKind.IfStatement:
// In a branch of an if statement, narrow based on controlling expression
if (child !== (node).expression) {
- narrowedType = narrowType(type, (node).expression, /*assumeTrue*/ child === (node).thenStatement);
+ type = narrowType(type, (node).expression, /*assumeTrue*/ child === (node).thenStatement);
}
break;
case SyntaxKind.ConditionalExpression:
// In a branch of a conditional expression, narrow based on controlling condition
if (child !== (node).condition) {
- narrowedType = narrowType(type, (node).condition, /*assumeTrue*/ child === (node).whenTrue);
+ type = narrowType(type, (node).condition, /*assumeTrue*/ child === (node).whenTrue);
}
break;
case SyntaxKind.BinaryExpression:
// In the right operand of an && or ||, narrow based on left operand
if (child === (node).right) {
if ((node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
- narrowedType = narrowType(type, (node).left, /*assumeTrue*/ true);
+ type = narrowType(type, (node).left, /*assumeTrue*/ true);
}
else if ((node).operatorToken.kind === SyntaxKind.BarBarToken) {
- narrowedType = narrowType(type, (node).left, /*assumeTrue*/ false);
+ type = narrowType(type, (node).left, /*assumeTrue*/ false);
}
}
break;
- case SyntaxKind.SourceFile:
- case SyntaxKind.ModuleDeclaration:
- case SyntaxKind.FunctionDeclaration:
- case SyntaxKind.MethodDeclaration:
- case SyntaxKind.MethodSignature:
- case SyntaxKind.GetAccessor:
- case SyntaxKind.SetAccessor:
- case SyntaxKind.Constructor:
- // Stop at the first containing function or module declaration
- break loop;
+ default:
+ Debug.fail("Unreachable!");
}
- // Use narrowed type if construct contains no assignments to variable
- if (narrowedType !== type) {
- if (isVariableAssignedWithin(symbol, node)) {
- break;
- }
- type = narrowedType;
+
+ // Use original type if construct contains assignments to variable
+ if (type !== originalType && isVariableAssignedWithin(symbol, node)) {
+ type = originalType;
}
}
+
+ // Preserve old top-level behavior - if the branch is really an empty set, revert to prior type
+ if (type === emptyUnionType) {
+ type = originalType;
+ }
}
}
@@ -6409,31 +6596,35 @@ namespace ts {
if (left.expression.kind !== SyntaxKind.Identifier || getResolvedSymbol(left.expression) !== symbol) {
return type;
}
- const typeInfo = primitiveTypeInfo[right.text];
if (expr.operatorToken.kind === SyntaxKind.ExclamationEqualsEqualsToken) {
assumeTrue = !assumeTrue;
}
- if (assumeTrue) {
- // Assumed result is true. If check was not for a primitive type, remove all primitive types
- if (!typeInfo) {
- return removeTypesFromUnionType(type, /*typeKind*/ TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.Boolean | TypeFlags.ESSymbol,
- /*isOfTypeKind*/ true, /*allowEmptyUnionResult*/ false);
- }
- // Check was for a primitive type, return that primitive type if it is a subtype
- if (isTypeSubtypeOf(typeInfo.type, type)) {
- return typeInfo.type;
- }
- // Otherwise, remove all types that aren't of the primitive type kind. This can happen when the type is
- // union of enum types and other types.
- return removeTypesFromUnionType(type, /*typeKind*/ typeInfo.flags, /*isOfTypeKind*/ false, /*allowEmptyUnionResult*/ false);
+ const typeInfo = primitiveTypeInfo[right.text];
+ // Don't narrow `undefined`
+ if (typeInfo && typeInfo.type === undefinedType) {
+ return type;
+ }
+ // If the type to be narrowed is any and we're checking a primitive with assumeTrue=true, return the primitive
+ if (!!(type.flags & TypeFlags.Any) && typeInfo && assumeTrue) {
+ return typeInfo.type;
+ }
+ let flags: TypeFlags;
+ if (typeInfo) {
+ flags = typeInfo.flags;
}
else {
- // Assumed result is false. If check was for a primitive type, remove that primitive type
- if (typeInfo) {
- return removeTypesFromUnionType(type, /*typeKind*/ typeInfo.flags, /*isOfTypeKind*/ true, /*allowEmptyUnionResult*/ false);
- }
- // Otherwise we don't have enough information to do anything.
- return type;
+ assumeTrue = !assumeTrue;
+ flags = TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol | TypeFlags.Boolean;
+ }
+ // At this point we can bail if it's not a union
+ if (!(type.flags & TypeFlags.Union)) {
+ // If the active non-union type would be removed from a union by this type guard, return an empty union
+ return filterUnion(type) ? type : emptyUnionType;
+ }
+ return getUnionType(filter((type as UnionType).types, filterUnion), /*noSubtypeReduction*/ true);
+
+ function filterUnion(type: Type) {
+ return assumeTrue === !!(type.flags & flags);
}
}
@@ -6447,7 +6638,7 @@ namespace ts {
// and the second operand was false. We narrow with those assumptions and union the two resulting types.
return getUnionType([
narrowType(type, expr.left, /*assumeTrue*/ false),
- narrowType(narrowType(type, expr.left, /*assumeTrue*/ true), expr.right, /*assumeTrue*/ false)
+ narrowType(type, expr.right, /*assumeTrue*/ false)
]);
}
}
@@ -6458,7 +6649,7 @@ namespace ts {
// and the second operand was true. We narrow with those assumptions and union the two resulting types.
return getUnionType([
narrowType(type, expr.left, /*assumeTrue*/ true),
- narrowType(narrowType(type, expr.left, /*assumeTrue*/ false), expr.right, /*assumeTrue*/ true)
+ narrowType(type, expr.right, /*assumeTrue*/ true)
]);
}
else {
@@ -6650,7 +6841,14 @@ namespace ts {
let container: Node;
if (symbol.flags & SymbolFlags.Class) {
// get parent of class declaration
- container = getClassLikeDeclarationOfSymbol(symbol).parent;
+ const classDeclaration = getClassLikeDeclarationOfSymbol(symbol);
+ if (classDeclaration) {
+ container = classDeclaration.parent;
+ }
+ else {
+ // JS-inferred class; do nothing
+ return;
+ }
}
else {
// nesting structure:
@@ -6994,7 +7192,10 @@ namespace ts {
const operator = binaryExpression.operatorToken.kind;
if (operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
- if (node === binaryExpression.right) {
+ // In JS files where a special assignment is taking place, don't contextually type the RHS to avoid
+ // incorrectly assuming a circular 'any' (the type of the LHS is determined by the RHS)
+ if (node === binaryExpression.right &&
+ !(node.parserContextFlags & ParserContextFlags.JavaScriptFile && getSpecialPropertyAssignmentKind(binaryExpression))) {
return checkExpression(binaryExpression.left);
}
}
@@ -7048,6 +7249,10 @@ namespace ts {
return applyToContextualType(type, t => getIndexTypeOfStructuredType(t, kind));
}
+ function contextualTypeIsStringLiteralType(type: Type): boolean {
+ return !!(type.flags & TypeFlags.Union ? forEach((type).types, isStringLiteralType) : isStringLiteralType(type));
+ }
+
// Return true if the given contextual type is a tuple-like type
function contextualTypeIsTupleLikeType(type: Type): boolean {
return !!(type.flags & TypeFlags.Union ? forEach((type).types, isTupleLikeType) : isTupleLikeType(type));
@@ -7073,7 +7278,7 @@ namespace ts {
function getContextualTypeForObjectLiteralElement(element: ObjectLiteralElement) {
const objectLiteral = element.parent;
- const type = getContextualType(objectLiteral);
+ const type = getApparentTypeOfContextualType(objectLiteral);
if (type) {
if (!hasDynamicName(element)) {
// For a (non-symbol) computed property, there is no reason to look up the name
@@ -7099,7 +7304,7 @@ namespace ts {
// type of T.
function getContextualTypeForElementExpression(node: Expression): Type {
const arrayLiteral = node.parent;
- const type = getContextualType(arrayLiteral);
+ const type = getApparentTypeOfContextualType(arrayLiteral);
if (type) {
const index = indexOf(arrayLiteral.elements, node);
return getTypeOfPropertyOfContextualType(type, "" + index)
@@ -7137,12 +7342,29 @@ namespace ts {
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
- function getContextualType(node: Expression): Type {
- const type = getContextualTypeWorker(node);
+ function getApparentTypeOfContextualType(node: Expression): Type {
+ const type = getContextualType(node);
return type && getApparentType(type);
}
- function getContextualTypeWorker(node: Expression): Type {
+ /**
+ * Woah! Do you really want to use this function?
+ *
+ * Unless you're trying to get the *non-apparent* type for a
+ * value-literal type or you're authoring relevant portions of this algorithm,
+ * you probably meant to use 'getApparentTypeOfContextualType'.
+ * Otherwise this may not be very useful.
+ *
+ * In cases where you *are* working on this function, you should understand
+ * when it is appropriate to use 'getContextualType' and 'getApparentTypeOfContetxualType'.
+ *
+ * - Use 'getContextualType' when you are simply going to propagate the result to the expression.
+ * - Use 'getApparentTypeOfContextualType' when you're going to need the members of the type.
+ *
+ * @param node the expression whose contextual type will be returned.
+ * @returns the contextual type of an expression.
+ */
+ function getContextualType(node: Expression): Type {
if (isInsideWithStatementBody(node)) {
// We cannot answer semantic questions within a with block, do not proceed any further
return undefined;
@@ -7221,7 +7443,7 @@ namespace ts {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
const type = isObjectLiteralMethod(node)
? getContextualTypeForObjectLiteralMethod(node)
- : getContextualType(node);
+ : getApparentTypeOfContextualType(node);
if (!type) {
return undefined;
}
@@ -7351,7 +7573,7 @@ namespace ts {
type.pattern = node;
return type;
}
- const contextualType = getContextualType(node);
+ const contextualType = getApparentTypeOfContextualType(node);
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
const pattern = contextualType.pattern;
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
@@ -7443,11 +7665,12 @@ namespace ts {
const propertiesTable: SymbolTable = {};
const propertiesArray: Symbol[] = [];
- const contextualType = getContextualType(node);
+ const contextualType = getApparentTypeOfContextualType(node);
const contextualTypeHasPattern = contextualType && contextualType.pattern &&
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
let typeFlags: TypeFlags = 0;
+ let patternWithComputedProperties = false;
for (const memberDecl of node.properties) {
let member = memberDecl.symbol;
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
@@ -7475,8 +7698,11 @@ namespace ts {
if (isOptional) {
prop.flags |= SymbolFlags.Optional;
}
+ if (hasDynamicName(memberDecl)) {
+ patternWithComputedProperties = true;
+ }
}
- else if (contextualTypeHasPattern) {
+ else if (contextualTypeHasPattern && !(contextualType.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties)) {
// If object literal is contextually typed by the implied type of a binding pattern, and if the
// binding pattern specifies a default value for the property, make the property optional.
const impliedProp = getPropertyOfType(contextualType, member.name);
@@ -7533,7 +7759,7 @@ namespace ts {
const numberIndexType = getIndexType(IndexKind.Number);
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshObjectLiteral;
- result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags);
+ result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags) | (patternWithComputedProperties ? TypeFlags.ObjectLiteralPatternWithComputedProperties : 0);
if (inDestructuringPattern) {
result.pattern = node;
}
@@ -8621,7 +8847,7 @@ namespace ts {
// for the argument. In that case, we should check the argument.
if (argType === undefined) {
argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors
- ? getStringLiteralType(arg)
+ ? getStringLiteralTypeForText((arg).text)
: checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
}
@@ -8816,7 +9042,7 @@ namespace ts {
case SyntaxKind.Identifier:
case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral:
- return getStringLiteralType(element.name);
+ return getStringLiteralTypeForText((element.name).text);
case SyntaxKind.ComputedPropertyName:
const nameType = checkComputedPropertyName(element.name);
@@ -9418,13 +9644,7 @@ namespace ts {
return voidType;
}
if (node.kind === SyntaxKind.NewExpression) {
- const declaration = signature.declaration;
-
- if (declaration &&
- declaration.kind !== SyntaxKind.Constructor &&
- declaration.kind !== SyntaxKind.ConstructSignature &&
- declaration.kind !== SyntaxKind.ConstructorType) {
-
+ if (signature.kind === SignatureKind.Call) {
// When resolved signature is a call signature (and not a construct signature) the result type is any
if (compilerOptions.noImplicitAny) {
error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
@@ -9450,7 +9670,12 @@ namespace ts {
const targetType = getTypeFromTypeNode(node.type);
if (produceDiagnostics && targetType !== unknownType) {
const widenedType = getWidenedType(exprType);
- if (!(isTypeAssignableTo(targetType, widenedType))) {
+
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ const bothAreStringLike =
+ someConstituentTypeHasKind(targetType, TypeFlags.StringLike) &&
+ someConstituentTypeHasKind(widenedType, TypeFlags.StringLike);
+ if (!bothAreStringLike && !(isTypeAssignableTo(targetType, widenedType))) {
checkTypeAssignableTo(exprType, targetType, node, Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
}
}
@@ -9680,35 +9905,52 @@ namespace ts {
return aggregatedTypes;
}
- // TypeScript Specification 1.0 (6.3) - July 2014
- // An explicitly typed function whose return type isn't the Void or the Any type
- // must have at least one return statement somewhere in its body.
- // An exception to this rule is if the function implementation consists of a single 'throw' statement.
+ /*
+ *TypeScript Specification 1.0 (6.3) - July 2014
+ * An explicitly typed function whose return type isn't the Void or the Any type
+ * must have at least one return statement somewhere in its body.
+ * An exception to this rule is if the function implementation consists of a single 'throw' statement.
+ * @param returnType - return type of the function, can be undefined if return type is not explicitly specified
+ */
function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func: FunctionLikeDeclaration, returnType: Type): void {
if (!produceDiagnostics) {
return;
}
- // Functions that return 'void' or 'any' don't need any return expressions.
+ // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
if (returnType === voidType || isTypeAny(returnType)) {
return;
}
// If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check.
- // also if HasImplicitReturnValue flags is not set this means that all codepaths in function body end with return of throw
+ // also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw
if (nodeIsMissing(func.body) || func.body.kind !== SyntaxKind.Block || !(func.flags & NodeFlags.HasImplicitReturn)) {
return;
}
- if (func.flags & NodeFlags.HasExplicitReturn) {
- if (compilerOptions.noImplicitReturns) {
- error(func.type, Diagnostics.Not_all_code_paths_return_a_value);
- }
- }
- else {
- // This function does not conform to the specification.
+ const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
+
+ if (returnType && !hasExplicitReturn) {
+ // minimal check: function has syntactic return type annotation and no explicit return statements in the body
+ // this function does not conform to the specification.
+ // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
}
+ else if (compilerOptions.noImplicitReturns) {
+ if (!returnType) {
+ // If return type annotation is omitted check if function has any explicit return statements.
+ // If it does not have any - its inferred return type is void - don't do any checks.
+ // Otherwise get inferred return type from function body and report error only if it is not void / anytype
+ const inferredReturnType = hasExplicitReturn
+ ? getReturnTypeOfSignature(getSignatureFromDeclaration(func))
+ : voidType;
+
+ if (inferredReturnType === voidType || isTypeAny(inferredReturnType)) {
+ return;
+ }
+ }
+ error(func.type || func, Diagnostics.Not_all_code_paths_return_a_value);
+ }
}
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, contextualMapper?: TypeMapper): Type {
@@ -9773,7 +10015,7 @@ namespace ts {
return type;
}
- function checkFunctionExpressionOrObjectLiteralMethodBody(node: FunctionExpression | MethodDeclaration) {
+ function checkFunctionExpressionOrObjectLiteralMethodBody(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
const isAsync = isAsyncFunctionLike(node);
@@ -9781,14 +10023,10 @@ namespace ts {
emitAwaiter = true;
}
- const returnType = node.type && getTypeFromTypeNode(node.type);
- let promisedType: Type;
- if (returnType && isAsync) {
- promisedType = checkAsyncFunctionReturnType(node);
- }
-
- if (returnType && !node.asteriskToken) {
- checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, isAsync ? promisedType : returnType);
+ const returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
+ if (!node.asteriskToken) {
+ // return is not necessary in the body of generators
+ checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
}
if (node.body) {
@@ -9811,13 +10049,13 @@ namespace ts {
// check assignability of the awaited type of the expression body against the promised type of
// its return type annotation.
const exprType = checkExpression(node.body);
- if (returnType) {
+ if (returnOrPromisedType) {
if (isAsync) {
const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.Expression_body_for_async_arrow_function_does_not_have_a_valid_callable_then_member);
- checkTypeAssignableTo(awaitedType, promisedType, node.body);
+ checkTypeAssignableTo(awaitedType, returnOrPromisedType, node.body);
}
else {
- checkTypeAssignableTo(exprType, returnType, node.body);
+ checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
}
}
@@ -10058,19 +10296,27 @@ namespace ts {
const properties = node.properties;
for (const p of properties) {
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
- // TODO(andersh): Computed property support
- const name = (p).name;
+ const name = (p).name;
+ if (name.kind === SyntaxKind.ComputedPropertyName) {
+ checkComputedPropertyName(name);
+ }
+ if (isComputedNonLiteralName(name)) {
+ continue;
+ }
+
+ const text = getTextOfPropertyName(name);
const type = isTypeAny(sourceType)
? sourceType
- : getTypeOfPropertyOfType(sourceType, name.text) ||
- isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
+ : getTypeOfPropertyOfType(sourceType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
getIndexTypeOfType(sourceType, IndexKind.String);
if (type) {
if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
checkDestructuringAssignment(p, type);
}
else {
- checkDestructuringAssignment((p).initializer || name, type);
+ // non-shorthand property assignments should always have initializers
+ checkDestructuringAssignment((p).initializer, type);
}
}
else {
@@ -10280,6 +10526,10 @@ namespace ts {
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
case SyntaxKind.ExclamationEqualsEqualsToken:
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ if (someConstituentTypeHasKind(leftType, TypeFlags.StringLike) && someConstituentTypeHasKind(rightType, TypeFlags.StringLike)) {
+ return booleanType;
+ }
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
reportOperatorError();
}
@@ -10418,6 +10668,15 @@ namespace ts {
return getUnionType([type1, type2]);
}
+ function checkStringLiteralExpression(node: StringLiteral): Type {
+ const contextualType = getContextualType(node);
+ if (contextualType && contextualTypeIsStringLiteralType(contextualType)) {
+ return getStringLiteralTypeForText(node.text);
+ }
+
+ return stringType;
+ }
+
function checkTemplateExpression(node: TemplateExpression): Type {
// We just want to check each expressions, but we are unconcerned with
// the type of each expression, as any value may be coerced into a string.
@@ -10477,7 +10736,7 @@ namespace ts {
if (isInferentialContext(contextualMapper)) {
const signature = getSingleCallSignature(type);
if (signature && signature.typeParameters) {
- const contextualType = getContextualType(node);
+ const contextualType = getApparentTypeOfContextualType(node);
if (contextualType) {
const contextualSignature = getSingleCallSignature(contextualType);
if (contextualSignature && !contextualSignature.typeParameters) {
@@ -10548,6 +10807,7 @@ namespace ts {
case SyntaxKind.TemplateExpression:
return checkTemplateExpression(node);
case SyntaxKind.StringLiteral:
+ return checkStringLiteralExpression(node);
case SyntaxKind.NoSubstitutionTemplateLiteral:
return stringType;
case SyntaxKind.RegularExpressionLiteral:
@@ -10881,6 +11141,7 @@ namespace ts {
const symbol = getSymbolOfNode(node);
const firstDeclaration = getDeclarationOfKind(symbol, node.kind);
+
// Only type check the symbol once
if (node === firstDeclaration) {
checkFunctionOrConstructorSymbol(symbol);
@@ -11233,16 +11494,24 @@ namespace ts {
seen = c === node;
}
});
- if (subsequentNode) {
+ // We may be here because of some extra junk between overloads that could not be parsed into a valid node.
+ // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here.
+ if (subsequentNode && subsequentNode.pos === node.end) {
if (subsequentNode.kind === node.kind) {
const errorNode: Node = (subsequentNode).name || subsequentNode;
// TODO(jfreeman): These are methods, so handle computed name case
if (node.name && (subsequentNode).name && (node.name).text === ((subsequentNode).name).text) {
- // the only situation when this is possible (same kind\same name but different symbol) - mixed static and instance class members
- Debug.assert(node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature);
- Debug.assert((node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static));
- const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
- error(errorNode, diagnostic);
+ const reportError =
+ (node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) &&
+ (node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static);
+ // we can get here in two cases
+ // 1. mixed static and instance class members
+ // 2. something with the same name was defined before the set of overloads that prevents them from merging
+ // here we'll report error only for the first case since for second we should already report error in binder
+ if (reportError) {
+ const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
+ error(errorNode, diagnostic);
+ }
return;
}
else if (nodeIsPresent((subsequentNode).body)) {
@@ -11337,7 +11606,7 @@ namespace ts {
// Abstract methods can't have an implementation -- in particular, they don't need one.
if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
- !(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract) ) {
+ !(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract)) {
reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
}
@@ -11905,7 +12174,14 @@ namespace ts {
const symbol = getSymbolOfNode(node);
const localSymbol = node.localSymbol || symbol;
- const firstDeclaration = getDeclarationOfKind(localSymbol, node.kind);
+ // Since the javascript won't do semantic analysis like typescript,
+ // if the javascript file comes before the typescript file and both contain same name functions,
+ // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function.
+ const firstDeclaration = forEach(localSymbol.declarations,
+ // Get first non javascript function declaration
+ declaration => declaration.kind === node.kind && !isSourceFileJavaScript(getSourceFile(declaration)) ?
+ declaration : undefined);
+
// Only type check the symbol once
if (node === firstDeclaration) {
checkFunctionOrConstructorSymbol(localSymbol);
@@ -11921,14 +12197,9 @@ namespace ts {
}
checkSourceElement(node.body);
- if (node.type && !isAccessor(node.kind) && !node.asteriskToken) {
- const returnType = getTypeFromTypeNode(node.type);
- let promisedType: Type;
- if (isAsync) {
- promisedType = checkAsyncFunctionReturnType(node);
- }
-
- checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, isAsync ? promisedType : returnType);
+ if (!isAccessor(node.kind) && !node.asteriskToken) {
+ const returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
+ checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
}
if (produceDiagnostics && !node.type) {
@@ -12189,6 +12460,14 @@ namespace ts {
checkExpressionCached(node.initializer);
}
}
+
+ if (node.kind === SyntaxKind.BindingElement) {
+ // check computed properties inside property names of binding elements
+ if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) {
+ checkComputedPropertyName(node.propertyName);
+ }
+ }
+
// For a binding pattern, check contained binding elements
if (isBindingPattern(node.name)) {
forEach((node.name).elements, checkSourceElement);
@@ -12616,9 +12895,14 @@ namespace ts {
// After we remove all types that are StringLike, we will know if there was a string constituent
// based on whether the remaining type is the same as the initial type.
- const arrayType = removeTypesFromUnionType(arrayOrStringType, TypeFlags.StringLike, /*isTypeOfKind*/ true, /*allowEmptyUnionResult*/ true);
+ let arrayType = arrayOrStringType;
+ if (arrayOrStringType.flags & TypeFlags.Union) {
+ arrayType = getUnionType(filter((arrayOrStringType as UnionType).types, t => !(t.flags & TypeFlags.StringLike)));
+ }
+ else if (arrayOrStringType.flags & TypeFlags.StringLike) {
+ arrayType = emptyUnionType;
+ }
const hasStringConstituent = arrayOrStringType !== arrayType;
-
let reportedError = false;
if (hasStringConstituent) {
if (languageVersion < ScriptTarget.ES5) {
@@ -12742,6 +13026,7 @@ namespace ts {
let hasDuplicateDefaultClause = false;
const expressionType = checkExpression(node.expression);
+ const expressionTypeIsStringLike = someConstituentTypeHasKind(expressionType, TypeFlags.StringLike);
forEach(node.caseBlock.clauses, clause => {
// Grammar check for duplicate default clauses, skip if we already report duplicate default clause
if (clause.kind === SyntaxKind.DefaultClause && !hasDuplicateDefaultClause) {
@@ -12762,8 +13047,14 @@ namespace ts {
// TypeScript 1.0 spec (April 2014):5.9
// In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression.
const caseType = checkExpression(caseClause.expression);
- if (!isTypeAssignableTo(expressionType, caseType)) {
- // check 'expressionType isAssignableTo caseType' failed, try the reversed check and report errors if it fails
+
+ const expressionTypeIsAssignableToCaseType =
+ // Permit 'number[] | "foo"' to be asserted to 'string'.
+ (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, TypeFlags.StringLike)) ||
+ isTypeAssignableTo(expressionType, caseType);
+
+ if (!expressionTypeIsAssignableToCaseType) {
+ // 'expressionType is not assignable to caseType', try the reversed check and report errors if it fails
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
}
}
@@ -13293,11 +13584,14 @@ namespace ts {
const enumIsConst = isConst(node);
for (const member of node.members) {
- if (member.name.kind === SyntaxKind.ComputedPropertyName) {
+ if (isComputedNonLiteralName(member.name)) {
error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
- else if (isNumericLiteralName((member.name).text)) {
- error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ else {
+ const text = getTextOfPropertyName(member.name);
+ if (isNumericLiteralName(text)) {
+ error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ }
}
const previousEnumMemberIsNonConstant = autoValue === undefined;
@@ -14117,8 +14411,12 @@ namespace ts {
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
// Check whether the file has declared it is the default lib,
// and whether the user has specifically chosen to avoid checking it.
- if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) {
- return;
+ if (compilerOptions.skipDefaultLibCheck) {
+ // If the user specified '--noLib' and a file has a '/// ',
+ // then we should treat that file as a default lib.
+ if (node.hasNoDefaultLib) {
+ return;
+ }
}
// Grammar checking
@@ -14127,6 +14425,7 @@ namespace ts {
emitExtends = false;
emitDecorate = false;
emitParam = false;
+ emitAwaiter = false;
potentialThisCollisions.length = 0;
forEach(node.statements, checkSourceElement);
@@ -14249,8 +14548,8 @@ namespace ts {
if (className) {
copySymbol(location.symbol, meaning);
}
- // fall through; this fall-through is necessary because we would like to handle
- // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration
+ // fall through; this fall-through is necessary because we would like to handle
+ // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
// If we didn't come from static member of class or interface,
@@ -14406,8 +14705,8 @@ namespace ts {
return resolveEntityName(entityName, meaning);
}
else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) ||
- (entityName.parent.kind === SyntaxKind.JsxSelfClosingElement) ||
- (entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
+ (entityName.parent.kind === SyntaxKind.JsxSelfClosingElement) ||
+ (entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
return getJsxElementTagSymbol(entityName.parent);
}
else if (isExpression(entityName)) {
@@ -14474,8 +14773,8 @@ namespace ts {
: getSymbolOfPartOfRightHandSideOfImportEquals(node);
}
else if (node.parent.kind === SyntaxKind.BindingElement &&
- node.parent.parent.kind === SyntaxKind.ObjectBindingPattern &&
- node === (node.parent).propertyName) {
+ node.parent.parent.kind === SyntaxKind.ObjectBindingPattern &&
+ node === (node.parent).propertyName) {
const typeOfPattern = getTypeOfNode(node.parent.parent);
const propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, (node).text);
@@ -14496,6 +14795,9 @@ namespace ts {
const type = isExpression(node) ? checkExpression(node) : getTypeFromTypeNode(node);
return type.symbol;
+ case SyntaxKind.ThisType:
+ return getTypeFromTypeNode(node).symbol;
+
case SyntaxKind.ConstructorKeyword:
// constructor keyword for an overload, should take us to the definition if it exist
const constructorDeclaration = node.parent;
@@ -14512,7 +14814,7 @@ namespace ts {
(node.parent).moduleSpecifier === node)) {
return resolveExternalModuleName(node, node);
}
- // Fall through
+ // Fall through
case SyntaxKind.NumericLiteral:
// index access
@@ -14708,7 +15010,7 @@ namespace ts {
if (links.isNestedRedeclaration === undefined) {
const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
links.isNestedRedeclaration = isStatementWithLocals(container) &&
- !!resolveName(container.parent, symbol.name, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
+ !!resolveName(container.parent, symbol.name, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
}
return links.isNestedRedeclaration;
}
@@ -15751,7 +16053,7 @@ namespace ts {
}
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
- if (node.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically((node).expression)) {
+ if (isDynamicName(node)) {
return grammarErrorOnNode(node, message);
}
}
@@ -16030,11 +16332,17 @@ namespace ts {
if (checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol)) {
return true;
}
+ if (node.initializer) {
+ return grammarErrorOnNode(node.initializer, Diagnostics.An_interface_property_cannot_have_an_initializer);
+ }
}
else if (node.parent.kind === SyntaxKind.TypeLiteral) {
if (checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol)) {
return true;
}
+ if (node.initializer) {
+ return grammarErrorOnNode(node.initializer, Diagnostics.A_type_literal_property_cannot_have_an_initializer);
+ }
}
if (isInAmbientContext(node) && node.initializer) {
diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts
index 3fca97c045021..034b7022e8232 100644
--- a/src/compiler/commandLineParser.ts
+++ b/src/compiler/commandLineParser.ts
@@ -279,6 +279,16 @@ namespace ts {
name: "forceConsistentCasingInFileNames",
type: "boolean",
description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
+ },
+ {
+ name: "allowSyntheticDefaultImports",
+ type: "boolean",
+ description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
+ },
+ {
+ name: "allowJs",
+ type: "boolean",
+ description: Diagnostics.Allow_javascript_files_to_be_compiled
}
];
@@ -474,9 +484,10 @@ namespace ts {
* @param basePath A root directory to resolve relative path entries in the config
* file to. e.g. outDir
*/
- export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string): ParsedCommandLine {
- const { options, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath);
+ export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}): ParsedCommandLine {
+ const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath);
+ const options = extend(existingOptions, optionsFromJsonConfigFile);
return {
options,
fileNames: getFileNames(),
@@ -494,23 +505,32 @@ namespace ts {
}
}
else {
+ const filesSeen: Map = {};
const exclude = json["exclude"] instanceof Array ? map(json["exclude"], normalizeSlashes) : undefined;
- const sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
- for (let i = 0; i < sysFiles.length; i++) {
- const name = sysFiles[i];
- if (fileExtensionIs(name, ".d.ts")) {
- const baseName = name.substr(0, name.length - ".d.ts".length);
- if (!contains(sysFiles, baseName + ".tsx") && !contains(sysFiles, baseName + ".ts")) {
- fileNames.push(name);
+ const supportedExtensions = getSupportedExtensions(options);
+ Debug.assert(indexOf(supportedExtensions, ".ts") < indexOf(supportedExtensions, ".d.ts"), "Changed priority of extensions to pick");
+
+ // Get files of supported extensions in their order of resolution
+ for (const extension of supportedExtensions) {
+ const filesInDirWithExtension = host.readDirectory(basePath, extension, exclude);
+ for (const fileName of filesInDirWithExtension) {
+ // .ts extension would read the .d.ts extension files too but since .d.ts is lower priority extension,
+ // lets pick them when its turn comes up
+ if (extension === ".ts" && fileExtensionIs(fileName, ".d.ts")) {
+ continue;
}
- }
- else if (fileExtensionIs(name, ".ts")) {
- if (!contains(sysFiles, name + "x")) {
- fileNames.push(name);
+
+ // If this is one of the output extension (which would be .d.ts and .js if we are allowing compilation of js files)
+ // do not include this file if we included .ts or .tsx file with same base name as it could be output of the earlier compilation
+ if (extension === ".d.ts" || (options.allowJs && contains(supportedJavascriptExtensions, extension))) {
+ const baseName = fileName.substr(0, fileName.length - extension.length);
+ if (hasProperty(filesSeen, baseName + ".ts") || hasProperty(filesSeen, baseName + ".tsx")) {
+ continue;
+ }
}
- }
- else {
- fileNames.push(name);
+
+ filesSeen[fileName] = true;
+ fileNames.push(fileName);
}
}
}
diff --git a/src/compiler/core.ts b/src/compiler/core.ts
index c866cf41a928a..cae7bd8210341 100644
--- a/src/compiler/core.ts
+++ b/src/compiler/core.ts
@@ -297,8 +297,8 @@ namespace ts {
return result;
}
- export function extend(first: Map, second: Map): Map {
- const result: Map = {};
+ export function extend, T2 extends Map<{}>>(first: T1 , second: T2): T1 & T2 {
+ const result: T1 & T2 = {};
for (const id in first) {
(result as any)[id] = first[id];
}
@@ -356,6 +356,33 @@ namespace ts {
return result;
}
+ /**
+ * Reduce the properties of a map.
+ *
+ * @param map The map to reduce
+ * @param callback An aggregation function that is called for each entry in the map
+ * @param initial The initial value for the reduction.
+ */
+ export function reduceProperties(map: Map, callback: (aggregate: U, value: T, key: string) => U, initial: U): U {
+ let result = initial;
+ if (map) {
+ for (const key in map) {
+ if (hasProperty(map, key)) {
+ result = callback(result, map[key], String(key));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests whether a value is an array.
+ */
+ export function isArray(value: any): value is any[] {
+ return Array.isArray ? Array.isArray(value) : value instanceof Array;
+ }
+
export function memoize(callback: () => T): () => T {
let value: T;
return () => {
@@ -714,7 +741,7 @@ namespace ts {
}
export function getBaseFileName(path: string) {
- if (!path) {
+ if (path === undefined) {
return undefined;
}
const i = path.lastIndexOf(directorySeparator);
@@ -738,13 +765,18 @@ namespace ts {
/**
* List of supported extensions in order of file resolution precedence.
*/
- export const supportedExtensions = [".ts", ".tsx", ".d.ts"];
- export const supportedJsExtensions = supportedExtensions.concat(".js", ".jsx");
+ export const supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"];
+ export const supportedJavascriptExtensions = [".js", ".jsx"];
+ const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
+
+ export function getSupportedExtensions(options?: CompilerOptions): string[] {
+ return options && options.allowJs ? allSupportedExtensions : supportedTypeScriptExtensions;
+ }
- export function isSupportedSourceFileName(fileName: string) {
+ export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions) {
if (!fileName) { return false; }
- for (const extension of supportedExtensions) {
+ for (const extension of getSupportedExtensions(compilerOptions)) {
if (fileExtensionIs(fileName, extension)) {
return true;
}
@@ -842,7 +874,7 @@ namespace ts {
}
export function fail(message?: string): void {
- Debug.assert(false, message);
+ Debug.assert(/*expression*/ false, message);
}
}
diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts
index 669cbcbcf0cde..0e0b121bf3c20 100644
--- a/src/compiler/declarationEmitter.ts
+++ b/src/compiler/declarationEmitter.ts
@@ -31,13 +31,17 @@ namespace ts {
}
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
- const diagnostics: Diagnostic[] = [];
- const jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
- emitDeclarations(host, resolver, diagnostics, jsFilePath, targetSourceFile);
- return diagnostics;
+ const declarationDiagnostics = createDiagnosticCollection();
+ forEachExpectedEmitFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
+ return declarationDiagnostics.getDiagnostics(targetSourceFile.fileName);
+
+ function getDeclarationDiagnosticsFromFile({ declarationFilePath }, sources: SourceFile[], isBundledEmit: boolean) {
+ emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit);
+ }
}
- function emitDeclarations(host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[], jsFilePath: string, root?: SourceFile): DeclarationEmit {
+ function emitDeclarations(host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, declarationFilePath: string,
+ sourceFiles: SourceFile[], isBundledEmit: boolean): DeclarationEmit {
const newLine = host.getNewLine();
const compilerOptions = host.getCompilerOptions();
@@ -58,7 +62,7 @@ namespace ts {
let errorNameNode: DeclarationName;
const emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
- let noDeclare = !root;
+ let noDeclare: boolean;
let moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
let asynchronousSubModuleDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[];
@@ -68,105 +72,78 @@ namespace ts {
// and we could be collecting these paths from multiple files into single one with --out option
let referencePathsOutput = "";
- if (root) {
- // Emitting just a single file, so emit references in this file only
- if (!compilerOptions.noResolve) {
- let addedGlobalFileReference = false;
- forEach(root.referencedFiles, fileReference => {
- const referencedFile = tryResolveScriptReference(host, root, fileReference);
-
- // All the references that are not going to be part of same file
- if (referencedFile && ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
- shouldEmitToOwnFile(referencedFile, compilerOptions) || // This is referenced file is emitting its own js file
- !addedGlobalFileReference)) { // Or the global out file corresponding to this reference was not added
+ // Emit references corresponding to each file
+ const emittedReferencedFiles: SourceFile[] = [];
+ let addedGlobalFileReference = false;
+ let allSourcesModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
+ forEach(sourceFiles, sourceFile => {
+ // Dont emit for javascript file
+ if (isSourceFileJavaScript(sourceFile)) {
+ return;
+ }
- writeReferencePath(referencedFile);
- if (!isExternalModuleOrDeclarationFile(referencedFile)) {
+ // Check what references need to be added
+ if (!compilerOptions.noResolve) {
+ forEach(sourceFile.referencedFiles, fileReference => {
+ const referencedFile = tryResolveScriptReference(host, sourceFile, fileReference);
+
+ // Emit reference in dts, if the file reference was not already emitted
+ if (referencedFile && !contains(emittedReferencedFiles, referencedFile)) {
+ // Add a reference to generated dts file,
+ // global file reference is added only
+ // - if it is not bundled emit (because otherwise it would be self reference)
+ // - and it is not already added
+ if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference)) {
addedGlobalFileReference = true;
}
+ emittedReferencedFiles.push(referencedFile);
}
});
}
- emitSourceFile(root);
+ if (!isBundledEmit || !isExternalModule(sourceFile)) {
+ noDeclare = false;
+ emitSourceFile(sourceFile);
+ }
+ else if (isExternalModule(sourceFile)) {
+ noDeclare = true;
+ write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`);
+ writeLine();
+ increaseIndent();
+ emitSourceFile(sourceFile);
+ decreaseIndent();
+ write("}");
+ writeLine();
+ }
// create asynchronous output for the importDeclarations
if (moduleElementDeclarationEmitInfo.length) {
const oldWriter = writer;
forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => {
- if (aliasEmitInfo.isVisible) {
+ if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration);
createAndSetNewTextWriterWithSymbolWriter();
- Debug.assert(aliasEmitInfo.indent === 0);
+ Debug.assert(aliasEmitInfo.indent === 0 || (aliasEmitInfo.indent === 1 && isBundledEmit));
+ for (let i = 0; i < aliasEmitInfo.indent; i++) {
+ increaseIndent();
+ }
writeImportDeclaration(aliasEmitInfo.node);
aliasEmitInfo.asynchronousOutput = writer.getText();
+ for (let i = 0; i < aliasEmitInfo.indent; i++) {
+ decreaseIndent();
+ }
}
});
setWriter(oldWriter);
- }
- }
- else {
- // Emit references corresponding to this file
- const emittedReferencedFiles: SourceFile[] = [];
- let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
- forEach(host.getSourceFiles(), sourceFile => {
- if (!isDeclarationFile(sourceFile)) {
- // Check what references need to be added
- if (!compilerOptions.noResolve) {
- forEach(sourceFile.referencedFiles, fileReference => {
- const referencedFile = tryResolveScriptReference(host, sourceFile, fileReference);
-
- // If the reference file is a declaration file, emit that reference
- if (referencedFile && (isDeclarationFile(referencedFile) &&
- !contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted
-
- writeReferencePath(referencedFile);
- emittedReferencedFiles.push(referencedFile);
- }
- });
- }
- }
-
- if (!isExternalModuleOrDeclarationFile(sourceFile)) {
- noDeclare = false;
- emitSourceFile(sourceFile);
- }
- else if (isExternalModule(sourceFile)) {
- noDeclare = true;
- write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`);
- writeLine();
- increaseIndent();
- emitSourceFile(sourceFile);
- decreaseIndent();
- write("}");
- writeLine();
- // create asynchronous output for the importDeclarations
- if (moduleElementDeclarationEmitInfo.length) {
- const oldWriter = writer;
- forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => {
- if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
- Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration);
- createAndSetNewTextWriterWithSymbolWriter();
- Debug.assert(aliasEmitInfo.indent === 1);
- increaseIndent();
- writeImportDeclaration(aliasEmitInfo.node);
- aliasEmitInfo.asynchronousOutput = writer.getText();
- decreaseIndent();
- }
- });
- setWriter(oldWriter);
- }
- prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
- moduleElementDeclarationEmitInfo = [];
- }
- });
- moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo);
- }
+ allSourcesModuleElementDeclarationEmitInfo = allSourcesModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
+ moduleElementDeclarationEmitInfo = [];
+ }
+ });
return {
reportedDeclarationError,
- moduleElementDeclarationEmitInfo,
+ moduleElementDeclarationEmitInfo: allSourcesModuleElementDeclarationEmitInfo,
synchronousDeclarationOutput: writer.getText(),
referencePathsOutput,
};
@@ -278,14 +255,14 @@ namespace ts {
const errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
if (errorInfo) {
if (errorInfo.typeName) {
- diagnostics.push(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
+ emitterDiagnostics.add(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
errorInfo.diagnosticMessage,
getTextOfNodeFromSourceText(currentText, errorInfo.typeName),
symbolAccesibilityResult.errorSymbolName,
symbolAccesibilityResult.errorModuleName));
}
else {
- diagnostics.push(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
+ emitterDiagnostics.add(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
errorInfo.diagnosticMessage,
symbolAccesibilityResult.errorSymbolName,
symbolAccesibilityResult.errorModuleName));
@@ -300,7 +277,8 @@ namespace ts {
function reportInaccessibleThisError() {
if (errorNameNode) {
- diagnostics.push(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary,
+ reportedDeclarationError = true;
+ emitterDiagnostics.add(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary,
declarationNameToString(errorNameNode)));
}
}
@@ -378,8 +356,8 @@ namespace ts {
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
- case SyntaxKind.ThisKeyword:
- case SyntaxKind.StringLiteral:
+ case SyntaxKind.ThisType:
+ case SyntaxKind.StringLiteralType:
return writeTextOfNode(currentText, type);
case SyntaxKind.ExpressionWithTypeArguments:
return emitExpressionWithTypeArguments(type);
@@ -680,7 +658,7 @@ namespace ts {
}
else {
write("require(");
- writeTextOfNode(currentText, getExternalModuleImportEqualsDeclarationExpression(node));
+ emitExternalModuleSpecifier(node);
write(");");
}
writer.writeLine();
@@ -737,14 +715,23 @@ namespace ts {
}
write(" from ");
}
- emitExternalModuleSpecifier(node.moduleSpecifier);
+ emitExternalModuleSpecifier(node);
write(";");
writer.writeLine();
}
- function emitExternalModuleSpecifier(moduleSpecifier: Expression) {
- if (moduleSpecifier.kind === SyntaxKind.StringLiteral && (!root) && (compilerOptions.out || compilerOptions.outFile)) {
- const moduleName = getExternalModuleNameFromDeclaration(host, resolver, moduleSpecifier.parent as (ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration));
+ function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration) {
+ let moduleSpecifier: Node;
+ if (parent.kind === SyntaxKind.ImportEqualsDeclaration) {
+ const node = parent as ImportEqualsDeclaration;
+ moduleSpecifier = getExternalModuleImportEqualsDeclarationExpression(node);
+ }
+ else {
+ const node = parent as (ImportDeclaration | ExportDeclaration);
+ moduleSpecifier = node.moduleSpecifier;
+ }
+ if (moduleSpecifier.kind === SyntaxKind.StringLiteral && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) {
+ const moduleName = getExternalModuleNameFromDeclaration(host, resolver, parent);
if (moduleName) {
write("\"");
write(moduleName);
@@ -787,7 +774,7 @@ namespace ts {
}
if (node.moduleSpecifier) {
write(" from ");
- emitExternalModuleSpecifier(node.moduleSpecifier);
+ emitExternalModuleSpecifier(node);
}
write(";");
writer.writeLine();
@@ -1643,34 +1630,58 @@ namespace ts {
}
}
- function writeReferencePath(referencedFile: SourceFile) {
- let declFileName = referencedFile.flags & NodeFlags.DeclarationFile
- ? referencedFile.fileName // Declaration file, use declaration file name
- : shouldEmitToOwnFile(referencedFile, compilerOptions)
- ? getOwnEmitOutputFilePath(referencedFile, host, ".d.ts") // Own output file so get the .d.ts file
- : removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts"; // Global out file
-
- declFileName = getRelativePathToDirectoryOrUrl(
- getDirectoryPath(normalizeSlashes(jsFilePath)),
- declFileName,
- host.getCurrentDirectory(),
- host.getCanonicalFileName,
- /*isAbsolutePathAnUrl*/ false);
-
- referencePathsOutput += "/// " + newLine;
+ /**
+ * Adds the reference to referenced file, returns true if global file reference was emitted
+ * @param referencedFile
+ * @param addBundledFileReference Determines if global file reference corresponding to bundled file should be emitted or not
+ */
+ function writeReferencePath(referencedFile: SourceFile, addBundledFileReference: boolean): boolean {
+ let declFileName: string;
+ let addedBundledEmitReference = false;
+ if (isDeclarationFile(referencedFile)) {
+ // Declaration file, use declaration file name
+ declFileName = referencedFile.fileName;
+ }
+ else {
+ // Get the declaration file path
+ forEachExpectedEmitFile(host, getDeclFileName, referencedFile);
+ }
+
+ if (declFileName) {
+ declFileName = getRelativePathToDirectoryOrUrl(
+ getDirectoryPath(normalizeSlashes(declarationFilePath)),
+ declFileName,
+ host.getCurrentDirectory(),
+ host.getCanonicalFileName,
+ /*isAbsolutePathAnUrl*/ false);
+
+ referencePathsOutput += "/// " + newLine;
+ }
+ return addedBundledEmitReference;
+
+ function getDeclFileName(emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) {
+ // Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
+ if (isBundledEmit && !addBundledFileReference) {
+ return;
+ }
+
+ Debug.assert(!!emitFileNames.declarationFilePath || isSourceFileJavaScript(referencedFile), "Declaration file is not present only for javascript files");
+ declFileName = emitFileNames.declarationFilePath || emitFileNames.jsFilePath;
+ addedBundledEmitReference = isBundledEmit;
+ }
}
}
/* @internal */
- export function writeDeclarationFile(jsFilePath: string, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[]) {
- const emitDeclarationResult = emitDeclarations(host, resolver, diagnostics, jsFilePath, sourceFile);
- // TODO(shkamat): Should we not write any declaration file if any of them can produce error,
- // or should we just not write this file like we are doing now
- if (!emitDeclarationResult.reportedDeclarationError) {
+ export function writeDeclarationFile(declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection) {
+ const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit);
+ const emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath);
+ if (!emitSkipped) {
const declarationOutput = emitDeclarationResult.referencePathsOutput
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
- writeFile(host, diagnostics, removeFileExtension(jsFilePath) + ".d.ts", declarationOutput, host.getCompilerOptions().emitBOM);
+ writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM);
}
+ return emitSkipped;
function getDeclarationOutput(synchronousDeclarationOutput: string, moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[]) {
let appliedSyncOutputPos = 0;
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index ad71d646b7b6a..0c19f6d8247a0 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -783,6 +783,14 @@
"category": "Error",
"code": 1245
},
+ "An interface property cannot have an initializer.": {
+ "category": "Error",
+ "code": 1246
+ },
+ "A type literal property cannot have an initializer.": {
+ "category": "Error",
+ "code": 1247
+ },
"'with' statements are not allowed in an async function block.": {
"category": "Error",
@@ -1622,7 +1630,7 @@
},
"Cannot assign an abstract constructor type to a non-abstract constructor type.": {
"category": "Error",
- "code":2517
+ "code": 2517
},
"Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": {
"category": "Error",
@@ -2060,6 +2068,22 @@
"category": "Error",
"code": 5054
},
+ "Cannot write file '{0}' because it would overwrite input file.": {
+ "category": "Error",
+ "code": 5055
+ },
+ "Cannot write file '{0}' because it would be overwritten by multiple input files.": {
+ "category": "Error",
+ "code": 5056
+ },
+ "Cannot find a tsconfig.json file at the specified directory: '{0}'": {
+ "category": "Error",
+ "code": 5057
+ },
+ "The specified path does not exist: '{0}'": {
+ "category": "Error",
+ "code": 5058
+ },
"Concatenate and emit output to single file.": {
"category": "Message",
@@ -2101,6 +2125,10 @@
"category": "Message",
"code": 6010
},
+ "Allow default imports from modules with no default export. This does not affect code emit, just typechecking.": {
+ "category": "Message",
+ "code": 6011
+ },
"Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015' (experimental)": {
"category": "Message",
"code": 6015
@@ -2322,6 +2350,11 @@
"category": "Error",
"code": 6082
},
+ "Allow javascript files to be compiled.": {
+ "category": "Message",
+ "code": 6083
+ },
+
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
@@ -2405,7 +2438,7 @@
"Not all code paths return a value.": {
"category": "Error",
"code": 7030
- },
+ },
"You cannot rename this element.": {
"category": "Error",
"code": 8000
diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts
index ce92150f9fd59..88847999a4b55 100644
--- a/src/compiler/emitter.ts
+++ b/src/compiler/emitter.ts
@@ -1,12 +1,9 @@
///
+///
///
/* @internal */
namespace ts {
- export function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) {
- return isExternalModule(sourceFile) || isDeclarationFile(sourceFile);
- }
-
export function getResolvedExternalModuleName(host: EmitHost, file: SourceFile): string {
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName);
}
@@ -337,47 +334,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
};`;
const compilerOptions = host.getCompilerOptions();
- const languageVersion = compilerOptions.target || ScriptTarget.ES3;
- const modulekind = compilerOptions.module ? compilerOptions.module : languageVersion === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
+ const languageVersion = getEmitScriptTarget(compilerOptions);
+ const modulekind = getEmitModuleKind(compilerOptions);
const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
- let diagnostics: Diagnostic[] = [];
+ const emitterDiagnostics = createDiagnosticCollection();
+ let emitSkipped = false;
const newLine = host.getNewLine();
- const jsxDesugaring = host.getCompilerOptions().jsx !== JsxEmit.Preserve;
- const shouldEmitJsx = (s: SourceFile) => (s.languageVariant === LanguageVariant.JSX && !jsxDesugaring);
- const outFile = compilerOptions.outFile || compilerOptions.out;
const emitJavaScript = createFileEmitter();
-
- if (targetSourceFile === undefined) {
- if (outFile) {
- emitFile(outFile);
- }
- else {
- forEach(host.getSourceFiles(), sourceFile => {
- if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
- const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
- emitFile(jsFilePath, sourceFile);
- }
- });
- }
- }
- else {
- // targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service)
- if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
- const jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, shouldEmitJsx(targetSourceFile) ? ".jsx" : ".js");
- emitFile(jsFilePath, targetSourceFile);
- }
- else if (!isDeclarationFile(targetSourceFile) && outFile) {
- emitFile(outFile);
- }
- }
-
- // Sort and make the unique list of diagnostics
- diagnostics = sortAndDeduplicateDiagnostics(diagnostics);
+ forEachExpectedEmitFile(host, emitFile, targetSourceFile);
return {
- emitSkipped: false,
- diagnostics,
+ emitSkipped,
+ diagnostics: emitterDiagnostics.getDiagnostics(),
sourceMaps: sourceMapDataList
};
@@ -428,18 +397,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
* var loop = function(x) { }
* var arguments_1 = arguments
* for (var x;;) loop(x);
- * otherwise semantics of the code will be different since 'arguments' inside converted loop body
+ * otherwise semantics of the code will be different since 'arguments' inside converted loop body
* will refer to function that holds converted loop.
* This value is set on demand.
*/
argumentsName?: string;
+ /*
+ * alias for 'this' from the calling code stack frame in case if this was used inside the converted loop
+ */
+ thisName?: string;
+
/*
* list of non-block scoped variable declarations that appear inside converted loop
- * such variable declarations should be moved outside the loop body
+ * such variable declarations should be moved outside the loop body
* for (let x;;) {
* var y = 1;
- * ...
+ * ...
* }
* should be converted to
* var loop = function(x) {
@@ -486,10 +460,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
}
- function createFileEmitter(): (jsFilePath: string, root?: SourceFile) => void {
- const writer: EmitTextWriter = createTextWriter(newLine);
+ function createFileEmitter(): (jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) => void {
+ const writer = createTextWriter(newLine);
const { write, writeTextOfNode, writeLine, increaseIndent, decreaseIndent } = writer;
+ const sourceMap = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? createSourceMapWriter(host, writer) : getNullSourceMapWriter();
+ const { setSourceFile, emitStart, emitEnd, emitPos } = sourceMap;
+
let currentSourceFile: SourceFile;
let currentText: string;
let currentLineMap: number[];
@@ -516,7 +493,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let decorateEmitted: boolean;
let paramEmitted: boolean;
let awaiterEmitted: boolean;
- let tempFlags: TempFlags;
+ let tempFlags: TempFlags = 0;
let tempVariables: Identifier[];
let tempParameters: Identifier[];
let externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[];
@@ -524,43 +501,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let exportEquals: ExportAssignment;
let hasExportStars: boolean;
- /** Write emitted output to disk */
- let writeEmittedFiles = writeJavaScriptFile;
-
let detachedCommentsInfo: { nodePos: number; detachedCommentEndPos: number }[];
- let writeComment = writeCommentRange;
-
- /** Emit a node */
- let emit = emitNodeWithCommentsAndWithoutSourcemap;
-
- /** Called just before starting emit of a node */
- let emitStart = function (node: Node) { };
-
- /** Called once the emit of the node is done */
- let emitEnd = function (node: Node) { };
-
- /** Emit the text for the given token that comes after startPos
- * This by default writes the text provided with the given tokenKind
- * but if optional emitFn callback is provided the text is emitted using the callback instead of default text
- * @param tokenKind the kind of the token to search and emit
- * @param startPos the position in the source to start searching for the token
- * @param emitFn if given will be invoked to emit the text instead of actual token emit */
- let emitToken = emitTokenText;
-
- /** Called to before starting the lexical scopes as in function/class in the emitted code because of node
- * @param scopeDeclaration node that starts the lexical scope
- * @param scopeName Optional name of this scope instead of deducing one from the declaration node */
- let scopeEmitStart = function(scopeDeclaration: Node, scopeName?: string) { };
-
- /** Called after coming out of the scope */
- let scopeEmitEnd = function() { };
-
/** Sourcemap data that will get encoded */
let sourceMapData: SourceMapData;
- /** The root file passed to the emit function (if present) */
- let root: SourceFile;
+ /** Is the file being emitted into its own file */
+ let isOwnFileEmit: boolean;
/** If removeComments is true, no leading-comments needed to be emitted **/
const emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos: number) { } : emitLeadingCommentsOfPositionWorker;
@@ -583,18 +530,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
return doEmit;
- function doEmit(jsFilePath: string, rootFile?: SourceFile) {
+ function doEmit(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
+ sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
+ generatedNameSet = {};
+ nodeToGeneratedName = [];
+ isOwnFileEmit = !isBundledEmit;
+
+ // Emit helpers from all the files
+ if (isBundledEmit && modulekind) {
+ forEach(sourceFiles, emitEmitHelpers);
+ }
+
+ // Do not call emit directly. It does not set the currentSourceFile.
+ forEach(sourceFiles, emitSourceFile);
+
+ writeLine();
+
+ const sourceMappingURL = sourceMap.getSourceMappingURL();
+ if (sourceMappingURL) {
+ write(`//# sourceMappingURL=${sourceMappingURL}`);
+ }
+
+ writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM);
+
// reset the state
+ sourceMap.reset();
writer.reset();
currentSourceFile = undefined;
currentText = undefined;
currentLineMap = undefined;
exportFunctionForFile = undefined;
- generatedNameSet = {};
- nodeToGeneratedName = [];
+ generatedNameSet = undefined;
+ nodeToGeneratedName = undefined;
computedPropertyNamesToGeneratedNames = undefined;
convertedLoopState = undefined;
-
extendsEmitted = false;
decorateEmitted = false;
paramEmitted = false;
@@ -611,29 +580,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
isEs6Module = false;
renamedDependencies = undefined;
isCurrentFileExternalModule = false;
- root = rootFile;
-
- if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
- initializeEmitterWithSourceMaps(jsFilePath, root);
- }
-
- if (root) {
- // Do not call emit directly. It does not set the currentSourceFile.
- emitSourceFile(root);
- }
- else {
- if (modulekind) {
- forEach(host.getSourceFiles(), emitEmitHelpers);
- }
- forEach(host.getSourceFiles(), sourceFile => {
- if ((!isExternalModuleOrDeclarationFile(sourceFile)) || (modulekind && isExternalModule(sourceFile))) {
- emitSourceFile(sourceFile);
- }
- });
- }
-
- writeLine();
- writeEmittedFiles(writer.getText(), jsFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM);
}
function emitSourceFile(sourceFile: SourceFile): void {
@@ -647,7 +593,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
currentFileIdentifiers = sourceFile.identifiers;
isCurrentFileExternalModule = isExternalModule(sourceFile);
- emit(sourceFile);
+ setSourceFile(sourceFile);
+ emitNodeWithCommentsAndWithoutSourcemap(sourceFile);
}
function isUniqueName(name: string): boolean {
@@ -744,400 +691,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = unescapeIdentifier(generateNameForNode(node)));
}
- function initializeEmitterWithSourceMaps(jsFilePath: string, root?: SourceFile) {
- let sourceMapDir: string; // The directory in which sourcemap will be
-
- // Current source map file and its index in the sources list
- let sourceMapSourceIndex = -1;
-
- // Names and its index map
- const sourceMapNameIndexMap: Map = {};
- const sourceMapNameIndices: number[] = [];
- function getSourceMapNameIndex() {
- return sourceMapNameIndices.length ? lastOrUndefined(sourceMapNameIndices) : -1;
- }
-
- // Last recorded and encoded spans
- let lastRecordedSourceMapSpan: SourceMapSpan;
- let lastEncodedSourceMapSpan: SourceMapSpan = {
- emittedLine: 1,
- emittedColumn: 1,
- sourceLine: 1,
- sourceColumn: 1,
- sourceIndex: 0
- };
- let lastEncodedNameIndex = 0;
-
- // Encoding for sourcemap span
- function encodeLastRecordedSourceMapSpan() {
- if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) {
- return;
- }
-
- let prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn;
- // Line/Comma delimiters
- if (lastEncodedSourceMapSpan.emittedLine === lastRecordedSourceMapSpan.emittedLine) {
- // Emit comma to separate the entry
- if (sourceMapData.sourceMapMappings) {
- sourceMapData.sourceMapMappings += ",";
- }
- }
- else {
- // Emit line delimiters
- for (let encodedLine = lastEncodedSourceMapSpan.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) {
- sourceMapData.sourceMapMappings += ";";
- }
- prevEncodedEmittedColumn = 1;
- }
-
- // 1. Relative Column 0 based
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.emittedColumn - prevEncodedEmittedColumn);
-
- // 2. Relative sourceIndex
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan.sourceIndex);
-
- // 3. Relative sourceLine 0 based
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan.sourceLine);
-
- // 4. Relative sourceColumn 0 based
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan.sourceColumn);
-
- // 5. Relative namePosition 0 based
- if (lastRecordedSourceMapSpan.nameIndex >= 0) {
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex);
- lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex;
- }
-
- lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
- sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
-
- function base64VLQFormatEncode(inValue: number) {
- function base64FormatEncode(inValue: number) {
- if (inValue < 64) {
- return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(inValue);
- }
- throw TypeError(inValue + ": not a 64 based value");
- }
-
- // Add a new least significant bit that has the sign of the value.
- // if negative number the least significant bit that gets added to the number has value 1
- // else least significant bit value that gets added is 0
- // eg. -1 changes to binary : 01 [1] => 3
- // +1 changes to binary : 01 [0] => 2
- if (inValue < 0) {
- inValue = ((-inValue) << 1) + 1;
- }
- else {
- inValue = inValue << 1;
- }
-
- // Encode 5 bits at a time starting from least significant bits
- let encodedStr = "";
- do {
- let currentDigit = inValue & 31; // 11111
- inValue = inValue >> 5;
- if (inValue > 0) {
- // There are still more digits to decode, set the msb (6th bit)
- currentDigit = currentDigit | 32;
- }
- encodedStr = encodedStr + base64FormatEncode(currentDigit);
- } while (inValue > 0);
-
- return encodedStr;
- }
- }
-
- function recordSourceMapSpan(pos: number) {
- const sourceLinePos = computeLineAndCharacterOfPosition(currentLineMap, pos);
-
- // Convert the location to be one-based.
- sourceLinePos.line++;
- sourceLinePos.character++;
-
- const emittedLine = writer.getLine();
- const emittedColumn = writer.getColumn();
-
- // If this location wasn't recorded or the location in source is going backwards, record the span
- if (!lastRecordedSourceMapSpan ||
- lastRecordedSourceMapSpan.emittedLine !== emittedLine ||
- lastRecordedSourceMapSpan.emittedColumn !== emittedColumn ||
- (lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex &&
- (lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line ||
- (lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
- // Encode the last recordedSpan before assigning new
- encodeLastRecordedSourceMapSpan();
-
- // New span
- lastRecordedSourceMapSpan = {
- emittedLine: emittedLine,
- emittedColumn: emittedColumn,
- sourceLine: sourceLinePos.line,
- sourceColumn: sourceLinePos.character,
- nameIndex: getSourceMapNameIndex(),
- sourceIndex: sourceMapSourceIndex
- };
- }
- else {
- // Take the new pos instead since there is no change in emittedLine and column since last location
- lastRecordedSourceMapSpan.sourceLine = sourceLinePos.line;
- lastRecordedSourceMapSpan.sourceColumn = sourceLinePos.character;
- lastRecordedSourceMapSpan.sourceIndex = sourceMapSourceIndex;
- }
- }
-
- function recordEmitNodeStartSpan(node: Node) {
- // Get the token pos after skipping to the token (ignoring the leading trivia)
- recordSourceMapSpan(skipTrivia(currentText, node.pos));
- }
-
- function recordEmitNodeEndSpan(node: Node) {
- recordSourceMapSpan(node.end);
- }
-
- function writeTextWithSpanRecord(tokenKind: SyntaxKind, startPos: number, emitFn?: () => void) {
- const tokenStartPos = ts.skipTrivia(currentText, startPos);
- recordSourceMapSpan(tokenStartPos);
- const tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
- recordSourceMapSpan(tokenEndPos);
- return tokenEndPos;
- }
-
- function recordNewSourceFileStart(node: SourceFile) {
- // Add the file to tsFilePaths
- // If sourceroot option: Use the relative path corresponding to the common directory path
- // otherwise source locations relative to map file location
- const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
-
- sourceMapData.sourceMapSources.push(getRelativePathToDirectoryOrUrl(sourcesDirectoryPath,
- node.fileName,
- host.getCurrentDirectory(),
- host.getCanonicalFileName,
- /*isAbsolutePathAnUrl*/ true));
- sourceMapSourceIndex = sourceMapData.sourceMapSources.length - 1;
-
- // The one that can be used from program to get the actual source file
- sourceMapData.inputSourceFileNames.push(node.fileName);
-
- if (compilerOptions.inlineSources) {
- if (!sourceMapData.sourceMapSourcesContent) {
- sourceMapData.sourceMapSourcesContent = [];
- }
- sourceMapData.sourceMapSourcesContent.push(node.text);
- }
- }
-
- function recordScopeNameOfNode(node: Node, scopeName?: string) {
- function recordScopeNameIndex(scopeNameIndex: number) {
- sourceMapNameIndices.push(scopeNameIndex);
- }
-
- function recordScopeNameStart(scopeName: string) {
- let scopeNameIndex = -1;
- if (scopeName) {
- const parentIndex = getSourceMapNameIndex();
- if (parentIndex !== -1) {
- // Child scopes are always shown with a dot (even if they have no name),
- // unless it is a computed property. Then it is shown with brackets,
- // but the brackets are included in the name.
- const name = (