mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Merge branch 'master' into invertedIncremental
Conflicts: src/services/syntax/parser.ts
This commit is contained in:
commit
b25d0a6fbc
@ -104,6 +104,7 @@ module TypeScript {
|
||||
A_generator_declaration_cannot_have_the_async_modifier: "A generator declaration cannot have the 'async' modifier.",
|
||||
async_modifier_cannot_appear_here: "'async' modifier cannot appear here.",
|
||||
comma_expression_cannot_appear_in_a_computed_property_name: "'comma' expression cannot appear in a computed property name.",
|
||||
String_literal_expected: "String literal expected.",
|
||||
Duplicate_identifier_0: "Duplicate identifier '{0}'.",
|
||||
The_name_0_does_not_exist_in_the_current_scope: "The name '{0}' does not exist in the current scope.",
|
||||
The_name_0_does_not_refer_to_a_value: "The name '{0}' does not refer to a value.",
|
||||
|
||||
@ -106,6 +106,7 @@ module TypeScript {
|
||||
"A generator declaration cannot have the 'async' modifier.": { "code": 1118, "category": DiagnosticCategory.Error },
|
||||
"'async' modifier cannot appear here.": { "code": 1119, "category": DiagnosticCategory.Error },
|
||||
"'comma' expression cannot appear in a computed property name.": { "code": 1120, "category": DiagnosticCategory.Error },
|
||||
"String literal expected.": { "code": 1121, "category": DiagnosticCategory.Error },
|
||||
"Duplicate identifier '{0}'.": { "code": 2000, "category": DiagnosticCategory.Error },
|
||||
"The name '{0}' does not exist in the current scope.": { "code": 2001, "category": DiagnosticCategory.Error },
|
||||
"The name '{0}' does not refer to a value.": { "code": 2002, "category": DiagnosticCategory.Error },
|
||||
|
||||
@ -411,6 +411,10 @@
|
||||
"category": "Error",
|
||||
"code": 1120
|
||||
},
|
||||
"String literal expected.": {
|
||||
"category": "Error",
|
||||
"code": 1121
|
||||
},
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2000
|
||||
|
||||
@ -1964,17 +1964,23 @@ function generateConstructorFunction(definition) {
|
||||
}
|
||||
result += ") {\r\n";
|
||||
result += " if (data) { this.__data = data; }\r\n";
|
||||
result += " this.parent = undefined";
|
||||
if (definition.children.length) {
|
||||
result += " ";
|
||||
for (var i = 0; i < definition.children.length; i++) {
|
||||
<<<<<<< HEAD
|
||||
if (i) {
|
||||
result += ", ";
|
||||
}
|
||||
=======
|
||||
result += ",\r\n";
|
||||
>>>>>>> 691a8a7... Remove restriction that you cannot reuse nodes/tokens during incremental parsing while doing speculatively operations.
|
||||
var child = definition.children[i];
|
||||
result += "this." + child.name + " = " + getSafeName(child);
|
||||
}
|
||||
result += ";\r\n";
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
if (definition.children.length > 0) {
|
||||
result += " ";
|
||||
for (var i = 0; i < definition.children.length; i++) {
|
||||
@ -1991,6 +1997,9 @@ function generateConstructorFunction(definition) {
|
||||
}
|
||||
result += ";\r\n";
|
||||
}
|
||||
=======
|
||||
result += ";\r\n";
|
||||
>>>>>>> 691a8a7... Remove restriction that you cannot reuse nodes/tokens during incremental parsing while doing speculatively operations.
|
||||
result += " };\r\n";
|
||||
result += " " + definition.name + ".prototype.kind = SyntaxKind." + getNameWithoutSuffix(definition) + ";\r\n";
|
||||
result += " " + definition.name + ".prototype.childCount = " + definition.children.length + ";\r\n";
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -25,17 +25,15 @@ module TypeScript.IncrementalParser {
|
||||
//
|
||||
// This parser source also keeps track of the absolute position in the text that we're in,
|
||||
// and any token diagnostics produced. That way we dont' have to track that ourselves.
|
||||
var _scannerParserSource = Scanner.createParserSource(oldSyntaxTree.fileName(), text, oldSyntaxTree.languageVersion());
|
||||
var scannerParserSource = Scanner.createParserSource(oldSyntaxTree.fileName(), text, oldSyntaxTree.languageVersion());
|
||||
|
||||
// The cursor we use to navigate through and retrieve nodes and tokens from the old tree.
|
||||
var oldSourceUnit = oldSyntaxTree.sourceUnit();
|
||||
|
||||
var _isSpeculativelyParsing = false;
|
||||
|
||||
// Start the cursor pointing at the first element in the source unit (if it exists).
|
||||
var _oldSourceUnitCursor = getSyntaxCursor();
|
||||
var oldSourceUnitCursor = getSyntaxCursor();
|
||||
if (oldSourceUnit.moduleElements.length > 0) {
|
||||
_oldSourceUnitCursor.pushElement(childAt(oldSourceUnit.moduleElements, 0), /*indexInParent:*/ 0);
|
||||
oldSourceUnitCursor.pushElement(childAt(oldSourceUnit.moduleElements, 0), /*indexInParent:*/ 0);
|
||||
}
|
||||
|
||||
// In general supporting multiple individual edits is just not that important. So we
|
||||
@ -43,18 +41,16 @@ module TypeScript.IncrementalParser {
|
||||
// time this could be problematic would be if the user made a ton of discontinuous edits.
|
||||
// For example, doing a column select on a *large* section of a code. If this is a
|
||||
// problem, we can always update this code to handle multiple changes.
|
||||
var _changeRange = extendToAffectedRange(textChangeRange, oldSourceUnit);
|
||||
|
||||
// Cached value of _changeRange.newSpan(). Cached for performance.
|
||||
var _changeRangeNewSpan = _changeRange.newSpan();
|
||||
var changeRange = extendToAffectedRange(textChangeRange, oldSourceUnit);
|
||||
|
||||
// The old tree's length, plus whatever length change was caused by the edit
|
||||
// Had better equal the new text's length!
|
||||
if (Debug.shouldAssert(AssertionLevel.Aggressive)) {
|
||||
Debug.assert((fullWidth(oldSourceUnit) - _changeRange.span().length() + _changeRange.newLength()) === text.length());
|
||||
Debug.assert((fullWidth(oldSourceUnit) - changeRange.span().length() + changeRange.newLength()) === text.length());
|
||||
}
|
||||
|
||||
var delta = _changeRange.newSpan().length() - _changeRange.span().length();
|
||||
var delta = changeRange.newSpan().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 down (if we inserted chars)
|
||||
// or they may move backward (if we deleted chars).
|
||||
@ -70,7 +66,7 @@ module TypeScript.IncrementalParser {
|
||||
// Also, mark any syntax elements that intersect the changed span. We know, up front,
|
||||
// that we cannot reuse these elements.
|
||||
updateTokenPositionsAndMarkElements(<ISyntaxElementInternal><ISyntaxElement>oldSourceUnit,
|
||||
_changeRange.span().start(), _changeRange.span().end(), delta, /*fullStart:*/ 0);
|
||||
changeRange.span().start(), changeRange.span().end(), delta, /*fullStart:*/ 0);
|
||||
|
||||
function extendToAffectedRange(changeRange: TextChangeRange, sourceUnit: SourceUnitSyntax): TextChangeRange {
|
||||
// Consider the following code:
|
||||
@ -104,35 +100,27 @@ module TypeScript.IncrementalParser {
|
||||
}
|
||||
|
||||
function absolutePosition() {
|
||||
return _scannerParserSource.absolutePosition();
|
||||
return scannerParserSource.absolutePosition();
|
||||
}
|
||||
|
||||
function tokenDiagnostics(): Diagnostic[] {
|
||||
return _scannerParserSource.tokenDiagnostics();
|
||||
function diagnostics(): Diagnostic[] {
|
||||
return scannerParserSource.diagnostics();
|
||||
}
|
||||
|
||||
function tryParse<T extends ISyntaxNode>(callback: () => T): T {
|
||||
// Clone our cursor. That way we can restore to that point if the parser needs to rewind.
|
||||
var savedOldSourceUnitCursor = cloneSyntaxCursor(_oldSourceUnitCursor);
|
||||
var savedIsSpeculativelyParsing = _isSpeculativelyParsing;
|
||||
|
||||
// Mark that we're speculative parsing. During speculative parsing we cannot ruse
|
||||
// nodes from the parse tree. See the comment in trySynchronizeCursorToPosition for
|
||||
// the reasons why.
|
||||
_isSpeculativelyParsing = true;
|
||||
var savedOldSourceUnitCursor = cloneSyntaxCursor(oldSourceUnitCursor);
|
||||
|
||||
// Now defer to our underlying scanner source to actually invoke the callback. That
|
||||
// way, if the parser decides to rewind, both the scanner source and this incremental
|
||||
// source will rewind appropriately.
|
||||
var result = _scannerParserSource.tryParse(callback);
|
||||
|
||||
_isSpeculativelyParsing = savedIsSpeculativelyParsing;
|
||||
var result = scannerParserSource.tryParse(callback);
|
||||
|
||||
if (!result) {
|
||||
// We're rewinding. Reset the cursor to what it was when we got the rewind point.
|
||||
// Make sure to return our existing cursor to the pool so it can be reused.
|
||||
returnSyntaxCursor(_oldSourceUnitCursor);
|
||||
_oldSourceUnitCursor = savedOldSourceUnitCursor;
|
||||
returnSyntaxCursor(oldSourceUnitCursor);
|
||||
oldSourceUnitCursor = savedOldSourceUnitCursor;
|
||||
}
|
||||
else {
|
||||
// We're not rewinding. Return the cloned original cursor back to the pool.
|
||||
@ -143,36 +131,15 @@ module TypeScript.IncrementalParser {
|
||||
}
|
||||
|
||||
function trySynchronizeCursorToPosition() {
|
||||
// If we're currently pinned, then do not want to touch the cursor. Here's why. First,
|
||||
// recall that we're 'pinned' when we're speculatively parsing. So say we were to allow
|
||||
// returning old nodes/tokens while speculatively parsing. Then, the parser might start
|
||||
// mutating the nodes and tokens we returned (i.e. by setting their parents). Then,
|
||||
// when we rewound, those nodes and tokens would still have those updated parents.
|
||||
// Parents which we just decided we did *not* want to parse (hence why we rewound). For
|
||||
// Example, say we have something like:
|
||||
//
|
||||
// var v = f<a,b,c>e; // note: this is not generic.
|
||||
//
|
||||
// When incrementally parsing, we will need to speculatively parse to determine if the
|
||||
// above is generic. This will cause us to reuse the "a, b, c" tokens, and set their
|
||||
// parent to a new type argument list. A type argument list we will then throw away once
|
||||
// we decide that it isn't actually generic. We will have now 'broken' the original tree.
|
||||
//
|
||||
// As such, the rule is simple. We only return nodes/tokens from teh original tree if
|
||||
// we know the parser will accept and consume them and never rewind back before them.
|
||||
if (_isSpeculativelyParsing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var absolutePos = absolutePosition();
|
||||
while (true) {
|
||||
if (_oldSourceUnitCursor.isFinished()) {
|
||||
if (oldSourceUnitCursor.isFinished()) {
|
||||
// Can't synchronize the cursor to the current position if the cursor is finished.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start with the current node or token the cursor is pointing at.
|
||||
var currentNodeOrToken = _oldSourceUnitCursor.currentNodeOrToken();
|
||||
var currentNodeOrToken = oldSourceUnitCursor.currentNodeOrToken();
|
||||
|
||||
// Node, move the cursor past any nodes or tokens that intersect the change range
|
||||
// 1) they are never reusable.
|
||||
@ -182,10 +149,10 @@ module TypeScript.IncrementalParser {
|
||||
// of the incremental algorithm.
|
||||
if ((<ISyntaxElementInternal><ISyntaxElement>currentNodeOrToken).intersectsChange) {
|
||||
if (isNode(currentNodeOrToken)) {
|
||||
_oldSourceUnitCursor.moveToFirstChild();
|
||||
oldSourceUnitCursor.moveToFirstChild();
|
||||
}
|
||||
else {
|
||||
_oldSourceUnitCursor.moveToNextSibling();
|
||||
oldSourceUnitCursor.moveToNextSibling();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -213,13 +180,13 @@ module TypeScript.IncrementalParser {
|
||||
// able to break up that token any further and we should just move to the next
|
||||
// token.
|
||||
if (currentNodeOrTokenFullEnd <= absolutePos || isToken(currentNodeOrToken)) {
|
||||
_oldSourceUnitCursor.moveToNextSibling();
|
||||
oldSourceUnitCursor.moveToNextSibling();
|
||||
}
|
||||
else {
|
||||
// We have a node, and it started before our absolute pos, and ended after our
|
||||
// pos. Try to crumble this node to see if we'll be able to skip the first node
|
||||
// or token contained within.
|
||||
_oldSourceUnitCursor.moveToFirstChild();
|
||||
oldSourceUnitCursor.moveToFirstChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -248,12 +215,12 @@ module TypeScript.IncrementalParser {
|
||||
|
||||
// Either we couldn't read from the old source unit, or we weren't able to successfully
|
||||
// get a token from it. In this case we need to read a token from the underlying text.
|
||||
return _scannerParserSource.currentToken();
|
||||
return scannerParserSource.currentToken();
|
||||
}
|
||||
|
||||
function currentContextualToken(): ISyntaxToken {
|
||||
// Just delegate to the underlying source to handle
|
||||
return _scannerParserSource.currentContextualToken();
|
||||
return scannerParserSource.currentContextualToken();
|
||||
}
|
||||
|
||||
function tryGetNodeFromOldSourceUnit(): ISyntaxNode {
|
||||
@ -264,7 +231,7 @@ module TypeScript.IncrementalParser {
|
||||
// c) it does not have a regex token in it.
|
||||
// d) we are still in the same strict or non-strict state that the node was originally parsed in.
|
||||
while (true) {
|
||||
var node = _oldSourceUnitCursor.currentNode();
|
||||
var node = oldSourceUnitCursor.currentNode();
|
||||
if (node === undefined) {
|
||||
// Couldn't even read a node, nothing to return.
|
||||
return undefined;
|
||||
@ -279,7 +246,7 @@ module TypeScript.IncrementalParser {
|
||||
// We couldn't use currentNode. Try to move to its first child (in case that's a
|
||||
// node). If it is we can try using that. Otherwise we'll just bail out in the
|
||||
// next iteration of the loop.
|
||||
_oldSourceUnitCursor.moveToFirstChild();
|
||||
oldSourceUnitCursor.moveToFirstChild();
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,7 +276,7 @@ module TypeScript.IncrementalParser {
|
||||
|
||||
function tryGetTokenFromOldSourceUnit(): ISyntaxToken {
|
||||
// get the current token that the cursor is pointing at.
|
||||
var token = _oldSourceUnitCursor.currentToken();
|
||||
var token = oldSourceUnitCursor.currentToken();
|
||||
|
||||
return canReuseTokenFromOldSourceUnit(token) ? token : undefined;
|
||||
}
|
||||
@ -323,44 +290,44 @@ module TypeScript.IncrementalParser {
|
||||
}
|
||||
|
||||
// Couldn't peek this far in the old tree. Get the token from the new text.
|
||||
return _scannerParserSource.peekToken(n);
|
||||
return scannerParserSource.peekToken(n);
|
||||
}
|
||||
|
||||
function tryPeekTokenFromOldSourceUnit(n: number): ISyntaxToken {
|
||||
// clone the existing cursor so we can move it forward and then restore ourselves back
|
||||
// to where we started from.
|
||||
|
||||
var cursorClone = cloneSyntaxCursor(_oldSourceUnitCursor);
|
||||
var cursorClone = cloneSyntaxCursor(oldSourceUnitCursor);
|
||||
|
||||
var token = tryPeekTokenFromOldSourceUnitWorker(n);
|
||||
|
||||
returnSyntaxCursor(_oldSourceUnitCursor);
|
||||
_oldSourceUnitCursor = cursorClone;
|
||||
returnSyntaxCursor(oldSourceUnitCursor);
|
||||
oldSourceUnitCursor = cursorClone;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
function tryPeekTokenFromOldSourceUnitWorker(n: number): ISyntaxToken {
|
||||
// First, make sure the cursor is pointing at a token.
|
||||
_oldSourceUnitCursor.moveToFirstToken();
|
||||
oldSourceUnitCursor.moveToFirstToken();
|
||||
|
||||
// Now, keep walking forward to successive tokens.
|
||||
for (var i = 0; i < n; i++) {
|
||||
var interimToken = _oldSourceUnitCursor.currentToken();
|
||||
var interimToken = oldSourceUnitCursor.currentToken();
|
||||
|
||||
if (!canReuseTokenFromOldSourceUnit(interimToken)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
_oldSourceUnitCursor.moveToNextSibling();
|
||||
oldSourceUnitCursor.moveToNextSibling();
|
||||
}
|
||||
|
||||
var token = _oldSourceUnitCursor.currentToken();
|
||||
var token = oldSourceUnitCursor.currentToken();
|
||||
return canReuseTokenFromOldSourceUnit(token) ? token : undefined;
|
||||
}
|
||||
|
||||
function consumeNodeOrToken(nodeOrToken: ISyntaxNodeOrToken): void {
|
||||
_scannerParserSource.consumeNodeOrToken(nodeOrToken);
|
||||
scannerParserSource.consumeNodeOrToken(nodeOrToken);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -372,15 +339,15 @@ module TypeScript.IncrementalParser {
|
||||
currentToken: currentToken,
|
||||
currentContextualToken: currentContextualToken,
|
||||
peekToken: peekToken,
|
||||
consumeNodeOrToken: consumeNodeOrToken,
|
||||
consumeNodeOrToken: scannerParserSource.consumeNodeOrToken,
|
||||
tryParse: tryParse,
|
||||
tokenDiagnostics: tokenDiagnostics,
|
||||
diagnostics: diagnostics
|
||||
};
|
||||
}
|
||||
|
||||
function updateTokenPositionsAndMarkElements(element: ISyntaxElement, changeStart: number, changeRangeOldEnd: number, delta: number, fullStart: number): void {
|
||||
// First, try to skip past any elements that we dont' need to move. We don't need to
|
||||
// move any elements that don't start after the end of the change range.
|
||||
// First, try to skip past any elements that we dont' need to move. We don't need to
|
||||
// move any elements that don't start after the end of the change range.
|
||||
if (fullStart > changeRangeOldEnd) {
|
||||
// Note, we only move elements that are truly after the end of the change range.
|
||||
// We consider elements that are touching the end of the change range to be unusable.
|
||||
@ -444,8 +411,7 @@ module TypeScript.IncrementalParser {
|
||||
forceUpdateTokenPosition(<ISyntaxToken>nodeOrToken, delta);
|
||||
}
|
||||
else {
|
||||
var node = <ISyntaxNode>nodeOrToken;
|
||||
var tokens = getTokens(node);
|
||||
var tokens = getTokens(<ISyntaxNode>nodeOrToken);
|
||||
for (var i = 0, n = tokens.length; i < n; i++) {
|
||||
forceUpdateTokenPosition(tokens[i], delta);
|
||||
}
|
||||
|
||||
@ -59,24 +59,34 @@ module TypeScript.Parser {
|
||||
|
||||
// The current token reinterpretted contextually based on where the parser is. If the
|
||||
// source is on a / or /= token, then it can be reinterpretted as a regex token. If the
|
||||
// source is on a > token, it may be reinterpretted to: >> >>> >= >>= >>>=
|
||||
// source is on a > token, it may be reinterpretted to: >> >>> >= >>= >>>=. If the
|
||||
// source is on a }, it will be reinterpretted as a template middle/end token.
|
||||
currentContextualToken(): ISyntaxToken;
|
||||
|
||||
// Called to move the source to the next node or token once the parser has consumed the
|
||||
// current one.
|
||||
consumeNodeOrToken(node: ISyntaxNodeOrToken): void;
|
||||
|
||||
// Peek any number of tokens ahead from the current location in source. peekToken(0) is
|
||||
// equivalent to 'currentToken', peekToken(1) is the next token, peekToken(2) the token
|
||||
// after that, etc. If the caller peeks past the end of the text, then EndOfFile tokens
|
||||
// will be returned.
|
||||
peekToken(n: number): ISyntaxToken;
|
||||
|
||||
// Used by the parser to tell the source that it is currently speculatively parsing. The
|
||||
// source will save its current state and then invoke the passed in callback. If the call
|
||||
// back returned 'undefined', then the source will rollback to the exact state it was in
|
||||
// prior to calling the callback. If the callback returns an actual node then the source
|
||||
// will stay in its current state and then return that node back out of this function.
|
||||
tryParse<T extends ISyntaxNode>(callback: () => T): T;
|
||||
|
||||
// Called to move the source to the next node or token once the parser has consumed the
|
||||
// current one.
|
||||
consumeNodeOrToken(node: ISyntaxNodeOrToken): void;
|
||||
|
||||
tryParse<T extends ISyntaxNode>(callback: () => T): T;
|
||||
|
||||
// Retrieves the diagnostics generated while the source was producing nodes or tokens.
|
||||
// Should generally only be called after the document has been completely parsed.
|
||||
tokenDiagnostics(): Diagnostic[];
|
||||
diagnostics(): Diagnostic[];
|
||||
}
|
||||
|
||||
// Contains the actual logic to parse typescript/javascript. This is the code that generally
|
||||
@ -130,8 +140,8 @@ module TypeScript.Parser {
|
||||
// [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
|
||||
//
|
||||
// Here this is saying that if the GeneratorParameter context flag is set, that we should
|
||||
// explicitly set the 'yield' context flag to false before calling into the BindingIdentifier
|
||||
// and we should explicitly unset the 'yield' context flag before calling into the Initializer.
|
||||
// explicitly set the 'yield' context flag to true before calling into the 'BindingIdentifier'
|
||||
// and we should explicitly unset the 'yield' context flag before calling into the 'Initializer'.
|
||||
// production. Conversely, if the GeneratorParameter context flag is not set, then we
|
||||
// should leave the 'yield' context flag alone.
|
||||
//
|
||||
@ -202,7 +212,7 @@ module TypeScript.Parser {
|
||||
function inAsyncContext() {
|
||||
return (contextFlags & ParserContextFlags.Async) !== 0;
|
||||
}
|
||||
|
||||
|
||||
function allowInAnd<T>(func: () => T): T {
|
||||
if (inDisallowInContext()) {
|
||||
setDisallowInContext(false);
|
||||
@ -292,13 +302,42 @@ module TypeScript.Parser {
|
||||
|
||||
function parseSyntaxTreeWorker(isDeclaration: boolean): SyntaxTree {
|
||||
var sourceUnit = parseSourceUnit();
|
||||
setupParentsForSyntaxNodeOrToken(sourceUnit);
|
||||
|
||||
var allDiagnostics = source.tokenDiagnostics().concat(diagnostics);
|
||||
var allDiagnostics = source.diagnostics().concat(diagnostics);
|
||||
allDiagnostics.sort((a: Diagnostic, b: Diagnostic) => a.start() - b.start());
|
||||
|
||||
return new SyntaxTree(sourceUnit, isDeclaration, allDiagnostics, source.fileName, source.text, source.languageVersion);
|
||||
}
|
||||
|
||||
function setupParentsForElement(element: ISyntaxElement, parent: ISyntaxElement) {
|
||||
if (element) {
|
||||
if (element.parent === parent) {
|
||||
return;
|
||||
}
|
||||
element.parent = parent;
|
||||
|
||||
if (isList(element)) {
|
||||
setupParentsForList(<ISyntaxNodeOrToken[]>element);
|
||||
}
|
||||
else {
|
||||
setupParentsForSyntaxNodeOrToken(<ISyntaxNodeOrToken>element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setupParentsForList(list: ISyntaxNodeOrToken[]) {
|
||||
for (var i = 0, n = list.length; i < n; i++) {
|
||||
setupParentsForElement(list[i], list);
|
||||
}
|
||||
}
|
||||
|
||||
function setupParentsForSyntaxNodeOrToken(nodeOrToken: ISyntaxNodeOrToken) {
|
||||
for (var i = 0, n = nodeOrToken.childCount; i < n; i++) {
|
||||
setupParentsForElement(nodeOrToken.childAt(i), nodeOrToken);
|
||||
}
|
||||
}
|
||||
|
||||
function tryParse<T extends ISyntaxNode>(callback: () => T): T {
|
||||
// See the comments in IParserRewindPoint for the explanation on why we need to store
|
||||
// this data, and what it is used for.
|
||||
@ -618,11 +657,11 @@ module TypeScript.Parser {
|
||||
|
||||
function getBinaryExpressionPrecedence(tokenKind: SyntaxKind): BinaryExpressionPrecedence {
|
||||
switch (tokenKind) {
|
||||
case SyntaxKind.BarBarToken: return BinaryExpressionPrecedence.LogicalOrExpressionPrecedence;
|
||||
case SyntaxKind.AmpersandAmpersandToken: return BinaryExpressionPrecedence.LogicalAndExpressionPrecedence;
|
||||
case SyntaxKind.BarToken: return BinaryExpressionPrecedence.BitwiseOrExpressionPrecedence;
|
||||
case SyntaxKind.CaretToken: return BinaryExpressionPrecedence.BitwiseExclusiveOrExpressionPrecedence;
|
||||
case SyntaxKind.AmpersandToken: return BinaryExpressionPrecedence.BitwiseAndExpressionPrecedence;
|
||||
case SyntaxKind.BarBarToken: return BinaryExpressionPrecedence.LogicalOrExpressionPrecedence;
|
||||
case SyntaxKind.AmpersandAmpersandToken: return BinaryExpressionPrecedence.LogicalAndExpressionPrecedence;
|
||||
case SyntaxKind.BarToken: return BinaryExpressionPrecedence.BitwiseOrExpressionPrecedence;
|
||||
case SyntaxKind.CaretToken: return BinaryExpressionPrecedence.BitwiseExclusiveOrExpressionPrecedence;
|
||||
case SyntaxKind.AmpersandToken: return BinaryExpressionPrecedence.BitwiseAndExpressionPrecedence;
|
||||
case SyntaxKind.EqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsToken:
|
||||
case SyntaxKind.EqualsEqualsEqualsToken:
|
||||
@ -640,7 +679,7 @@ module TypeScript.Parser {
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
|
||||
return BinaryExpressionPrecedence.ShiftExpressionPrecdence;
|
||||
case SyntaxKind.PlusToken:
|
||||
case SyntaxKind.MinusToken:
|
||||
case SyntaxKind.MinusToken:
|
||||
return BinaryExpressionPrecedence.AdditiveExpressionPrecedence;
|
||||
case SyntaxKind.AsteriskToken:
|
||||
case SyntaxKind.SlashToken:
|
||||
@ -660,9 +699,9 @@ module TypeScript.Parser {
|
||||
// Note: any skipped tokens produced after the end of all the module elements will be
|
||||
// added as skipped trivia to the start of the EOF token.
|
||||
var moduleElements = parseSyntaxList<IModuleElementSyntax>(ListParsingState.SourceUnit_ModuleElements, updateStrictModeState);
|
||||
|
||||
|
||||
setStrictModeContext(savedIsInStrictMode);
|
||||
|
||||
|
||||
var sourceUnit = new SourceUnitSyntax(contextFlags, moduleElements, consumeToken(currentToken()));
|
||||
|
||||
if (Debug.shouldAssert(AssertionLevel.Aggressive)) {
|
||||
@ -697,7 +736,7 @@ module TypeScript.Parser {
|
||||
function isModuleElement(inErrorRecovery: boolean): boolean {
|
||||
var _modifierCount = modifierCount();
|
||||
return isInterfaceEnumClassModuleImportExportOrTypeAlias(_modifierCount) ||
|
||||
isStatement(_modifierCount, inErrorRecovery);
|
||||
isStatement(_modifierCount, inErrorRecovery);
|
||||
}
|
||||
|
||||
function tryParseModuleElement(inErrorRecovery: boolean): IModuleElementSyntax {
|
||||
@ -800,12 +839,15 @@ module TypeScript.Parser {
|
||||
|
||||
function isExternalModuleReference(): boolean {
|
||||
return currentToken().kind === SyntaxKind.RequireKeyword &&
|
||||
peekToken(1).kind === SyntaxKind.OpenParenToken;
|
||||
peekToken(1).kind === SyntaxKind.OpenParenToken;
|
||||
}
|
||||
|
||||
function parseExternalModuleReference(): ExternalModuleReferenceSyntax {
|
||||
return new ExternalModuleReferenceSyntax(contextFlags,
|
||||
eatToken(SyntaxKind.RequireKeyword), eatToken(SyntaxKind.OpenParenToken), eatToken(SyntaxKind.StringLiteral), eatToken(SyntaxKind.CloseParenToken));
|
||||
eatToken(SyntaxKind.RequireKeyword),
|
||||
eatToken(SyntaxKind.OpenParenToken),
|
||||
parseExpression(),
|
||||
eatToken(SyntaxKind.CloseParenToken));
|
||||
}
|
||||
|
||||
function parseModuleNameModuleReference(): ModuleNameModuleReferenceSyntax {
|
||||
@ -876,10 +918,10 @@ module TypeScript.Parser {
|
||||
function parseEnumDeclaration(): EnumDeclarationSyntax {
|
||||
var openBraceToken: ISyntaxToken;
|
||||
|
||||
return new EnumDeclarationSyntax(contextFlags,
|
||||
parseModifiers(),
|
||||
eatToken(SyntaxKind.EnumKeyword),
|
||||
eatIdentifierToken(),
|
||||
return new EnumDeclarationSyntax(contextFlags,
|
||||
parseModifiers(),
|
||||
eatToken(SyntaxKind.EnumKeyword),
|
||||
eatIdentifierToken(),
|
||||
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
|
||||
openBraceToken.fullWidth() > 0 ? parseSeparatedSyntaxList<EnumElementSyntax>(ListParsingState.EnumDeclaration_EnumElements) : [],
|
||||
eatToken(SyntaxKind.CloseBraceToken));
|
||||
@ -888,7 +930,7 @@ module TypeScript.Parser {
|
||||
function isEnumElement(inErrorRecovery: boolean): boolean {
|
||||
return isPropertyName(/*peekToken:*/ 0, inErrorRecovery);
|
||||
}
|
||||
|
||||
|
||||
function tryParseEnumElementEqualsValueClause(): EqualsValueClauseSyntax {
|
||||
return isEqualsValueClause(/*inParameter*/ false) ? allowInAnd(parseEqualsValueClause) : undefined;
|
||||
}
|
||||
@ -1025,12 +1067,12 @@ module TypeScript.Parser {
|
||||
function parseClassDeclaration(): ClassDeclarationSyntax {
|
||||
var openBraceToken: ISyntaxToken;
|
||||
return new ClassDeclarationSyntax(contextFlags,
|
||||
parseModifiers(),
|
||||
eatToken(SyntaxKind.ClassKeyword),
|
||||
eatIdentifierToken(),
|
||||
tryParseTypeParameterList(/*requireCompleteTypeParameterList:*/ false),
|
||||
parseHeritageClauses(/*isClassHeritageClauses:*/ true),
|
||||
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
|
||||
parseModifiers(),
|
||||
eatToken(SyntaxKind.ClassKeyword),
|
||||
eatIdentifierToken(),
|
||||
tryParseTypeParameterList(/*requireCompleteTypeParameterList:*/ false),
|
||||
parseHeritageClauses(/*isClassHeritageClauses:*/ true),
|
||||
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
|
||||
openBraceToken.fullWidth() > 0 ? parseSyntaxList<IClassElementSyntax>(ListParsingState.ClassDeclaration_ClassElements) : [],
|
||||
eatToken(SyntaxKind.CloseBraceToken));
|
||||
}
|
||||
@ -1094,10 +1136,10 @@ module TypeScript.Parser {
|
||||
|
||||
function isClassElement(inErrorRecovery: boolean): boolean {
|
||||
return isAtModifier() ||
|
||||
isConstructorDeclaration() ||
|
||||
isAccessor(inErrorRecovery) ||
|
||||
isIndexMemberDeclaration() ||
|
||||
isMemberVariableOrFunctionDeclaration(inErrorRecovery);
|
||||
isConstructorDeclaration() ||
|
||||
isAccessor(inErrorRecovery) ||
|
||||
isIndexMemberDeclaration() ||
|
||||
isMemberVariableOrFunctionDeclaration(inErrorRecovery);
|
||||
}
|
||||
|
||||
function isMemberVariableOrFunctionDeclaration(inErrorRecovery: boolean) {
|
||||
@ -1200,9 +1242,9 @@ module TypeScript.Parser {
|
||||
// Note: if we see an arrow after the close paren, then try to parse out a function
|
||||
// block anyways. It's likely the user just though '=> expr' was legal anywhere a
|
||||
// block was legal.
|
||||
return new ConstructorDeclarationSyntax(contextFlags,
|
||||
modifiers,
|
||||
eatToken(SyntaxKind.ConstructorKeyword),
|
||||
return new ConstructorDeclarationSyntax(contextFlags,
|
||||
modifiers,
|
||||
eatToken(SyntaxKind.ConstructorKeyword),
|
||||
parseCallSignatureWithoutSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false),
|
||||
parseFunctionBody(/*isGenerator:*/ false, /*asyncContext:*/ false));
|
||||
}
|
||||
@ -1230,12 +1272,12 @@ module TypeScript.Parser {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function parsePropertyDeclaration(modifiers: ISyntaxToken[], propertyName: IPropertyNameSyntax): PropertyDeclarationSyntax {
|
||||
return new PropertyDeclarationSyntax(contextFlags,
|
||||
modifiers,
|
||||
new VariableDeclaratorSyntax(contextFlags, propertyName,
|
||||
parseOptionalTypeAnnotation(/*allowStringLiteral:*/ false),
|
||||
parseOptionalTypeAnnotation(/*allowStringLiteral:*/ false),
|
||||
isEqualsValueClause(/*inParameter*/ false) ? allowInAnd(parseEqualsValueClause) : undefined),
|
||||
eatExplicitOrAutomaticSemicolon());
|
||||
}
|
||||
@ -1287,8 +1329,8 @@ module TypeScript.Parser {
|
||||
return new ModuleDeclarationSyntax(contextFlags,
|
||||
parseModifiers(),
|
||||
eatToken(SyntaxKind.ModuleKeyword),
|
||||
parseModuleName(),
|
||||
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
|
||||
parseModuleName(),
|
||||
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
|
||||
openBraceToken.fullWidth() > 0 ? parseSyntaxList<IModuleElementSyntax>(ListParsingState.ModuleDeclaration_ModuleElements) : [],
|
||||
eatToken(SyntaxKind.CloseBraceToken));
|
||||
}
|
||||
@ -1315,7 +1357,7 @@ module TypeScript.Parser {
|
||||
|
||||
function parseObjectType(): ObjectTypeSyntax {
|
||||
var openBraceToken: ISyntaxToken;
|
||||
|
||||
|
||||
return new ObjectTypeSyntax(contextFlags,
|
||||
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
|
||||
openBraceToken.fullWidth() > 0 ? parseSyntaxList<ITypeMemberSyntax>(ListParsingState.ObjectType_TypeMembers) : [],
|
||||
@ -1331,9 +1373,9 @@ module TypeScript.Parser {
|
||||
|
||||
function isTypeMember(inErrorRecovery: boolean): boolean {
|
||||
return isCallSignature(/*tokenIndex:*/ 0) ||
|
||||
isConstructSignature() ||
|
||||
isIndexSignature(/*tokenIndex:*/ 0) ||
|
||||
isMethodOrPropertySignature(inErrorRecovery);
|
||||
isConstructSignature() ||
|
||||
isIndexSignature(/*tokenIndex:*/ 0) ||
|
||||
isMethodOrPropertySignature(inErrorRecovery);
|
||||
}
|
||||
|
||||
function isMethodOrPropertySignature(inErrorRecovery: boolean): boolean {
|
||||
@ -1378,7 +1420,7 @@ module TypeScript.Parser {
|
||||
return parseConstructSignature();
|
||||
}
|
||||
else if (isIndexSignature(/*tokenIndex:*/ 0)) {
|
||||
return parseIndexSignature(/*modifiers:*/ []);
|
||||
return parseIndexSignature(/*modifiers:*/[]);
|
||||
}
|
||||
else if (isMethodOrPropertySignature(inErrorRecovery)) {
|
||||
var propertyName = parsePropertyName();
|
||||
@ -1496,7 +1538,7 @@ module TypeScript.Parser {
|
||||
// "implements foo" is not considered a type name.
|
||||
return !isNotHeritageClauseTypeName();
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1516,11 +1558,11 @@ module TypeScript.Parser {
|
||||
if (modifierCount) {
|
||||
// Any of these keywords following a modifier is definitely a TS construct.
|
||||
switch (peekToken(modifierCount).kind) {
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
return true;
|
||||
@ -1566,24 +1608,24 @@ module TypeScript.Parser {
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
|
||||
//if (isModifierKind(currentTokenKind)) {
|
||||
// ERROR RECOVERY
|
||||
// None of the modifiers are actually keywords. And they might show up in a real
|
||||
// statement (i.e. "public();"). However, if we see 'public <identifier>' then
|
||||
// that can't possibly be a statement (and instead will be a class element),
|
||||
// and we should not parse it out here. Note: if there is a newline between the
|
||||
// elements, then we should not do this. That's because asi might take effect. i.e.:
|
||||
//
|
||||
// public
|
||||
// foo
|
||||
//
|
||||
// Are two legal statements in JS.
|
||||
//
|
||||
// Also: 'async a' can start an statement, so we want to check for that as well.
|
||||
var token1 = peekToken(1);
|
||||
if (!token1.hasLeadingNewLine() && SyntaxFacts.isIdentifierNameOrAnyKeyword(token1)) {
|
||||
return true;
|
||||
}
|
||||
//if (isModifierKind(currentTokenKind)) {
|
||||
// ERROR RECOVERY
|
||||
// None of the modifiers are actually keywords. And they might show up in a real
|
||||
// statement (i.e. "public();"). However, if we see 'public <identifier>' then
|
||||
// that can't possibly be a statement (and instead will be a class element),
|
||||
// and we should not parse it out here. Note: if there is a newline between the
|
||||
// elements, then we should not do this. That's because asi might take effect. i.e.:
|
||||
//
|
||||
// public
|
||||
// foo
|
||||
//
|
||||
// Are two legal statements in JS.
|
||||
//
|
||||
// Also: 'async a' can start an statement, so we want to check for that as well.
|
||||
var token1 = peekToken(1);
|
||||
if (!token1.hasLeadingNewLine() && SyntaxFacts.isIdentifierNameOrAnyKeyword(token1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for common things that might appear where we expect a statement, but which we
|
||||
@ -1662,7 +1704,7 @@ module TypeScript.Parser {
|
||||
case SyntaxKind.TryKeyword: return parseTryStatement(_currentToken);
|
||||
case SyntaxKind.DebuggerKeyword: return parseDebuggerStatement(_currentToken);
|
||||
}
|
||||
|
||||
|
||||
if (isVariableStatement(modifierCount)) {
|
||||
return parseVariableStatement();
|
||||
}
|
||||
@ -1825,8 +1867,8 @@ module TypeScript.Parser {
|
||||
var initializer = tokenKind === SyntaxKind.SemicolonToken
|
||||
? undefined
|
||||
: isVariableDeclaration(tokenKind)
|
||||
? disallowInAnd(parseVariableDeclaration)
|
||||
: disallowInAnd(parseExpression)
|
||||
? disallowInAnd(parseVariableDeclaration)
|
||||
: disallowInAnd(parseExpression)
|
||||
|
||||
// In order to be a 'for-in' statement, we had to have an initializer of some sort, and
|
||||
// we had to actually get an 'in' keyword.
|
||||
@ -1920,10 +1962,10 @@ module TypeScript.Parser {
|
||||
var openBraceToken: ISyntaxToken;
|
||||
|
||||
return new SwitchStatementSyntax(contextFlags,
|
||||
consumeToken(switchKeyword),
|
||||
consumeToken(switchKeyword),
|
||||
openParenToken = eatToken(SyntaxKind.OpenParenToken),
|
||||
parseSwitchExpression(openParenToken),
|
||||
eatToken(SyntaxKind.CloseParenToken),
|
||||
eatToken(SyntaxKind.CloseParenToken),
|
||||
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
|
||||
openBraceToken.fullWidth() > 0 ? parseSyntaxList<ISwitchClauseSyntax>(ListParsingState.SwitchStatement_SwitchClauses) : [],
|
||||
eatToken(SyntaxKind.CloseBraceToken));
|
||||
@ -1954,15 +1996,15 @@ module TypeScript.Parser {
|
||||
return new CaseSwitchClauseSyntax(contextFlags,
|
||||
consumeToken(caseKeyword),
|
||||
allowInAnd(parseExpression),
|
||||
eatToken(SyntaxKind.ColonToken),
|
||||
eatToken(SyntaxKind.ColonToken),
|
||||
parseSyntaxList<IStatementSyntax>(ListParsingState.SwitchClause_Statements));
|
||||
}
|
||||
|
||||
function parseDefaultSwitchClause(defaultKeyword: ISyntaxToken): DefaultSwitchClauseSyntax {
|
||||
// Debug.assert(isDefaultSwitchClause());
|
||||
|
||||
return new DefaultSwitchClauseSyntax(contextFlags,
|
||||
consumeToken(defaultKeyword),
|
||||
return new DefaultSwitchClauseSyntax(contextFlags,
|
||||
consumeToken(defaultKeyword),
|
||||
eatToken(SyntaxKind.ColonToken),
|
||||
parseSyntaxList<IStatementSyntax>(ListParsingState.SwitchClause_Statements));
|
||||
}
|
||||
@ -2035,7 +2077,7 @@ module TypeScript.Parser {
|
||||
case SyntaxKind.NoSubstitutionTemplateToken:
|
||||
case SyntaxKind.TemplateStartToken:
|
||||
|
||||
// For array literals.
|
||||
// For array literals.
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
|
||||
// For parenthesized expressions
|
||||
@ -2063,9 +2105,9 @@ module TypeScript.Parser {
|
||||
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.SlashEqualsToken:
|
||||
// Note: if we see a / or /= token then we always consider this an expression.
|
||||
// The / or /= will actually be the start of a regex that we will contextually
|
||||
// rescan.
|
||||
// Note: if we see a / or /= token then we always consider this an expression.
|
||||
// The / or /= will actually be the start of a regex that we will contextually
|
||||
// rescan.
|
||||
|
||||
// Simple epxressions.
|
||||
case SyntaxKind.SuperKeyword:
|
||||
@ -2263,7 +2305,7 @@ module TypeScript.Parser {
|
||||
|
||||
leftOperand = new BinaryExpressionSyntax(contextFlags,
|
||||
leftOperand,
|
||||
consumeToken(_currentToken),
|
||||
consumeToken(_currentToken),
|
||||
parseAssignmentExpressionOrHigher());
|
||||
}
|
||||
|
||||
@ -2318,7 +2360,7 @@ module TypeScript.Parser {
|
||||
if (SyntaxFacts.isAssignmentOperatorToken(operatorToken.kind)) {
|
||||
return new BinaryExpressionSyntax(contextFlags,
|
||||
leftOperand,
|
||||
consumeToken(operatorToken),
|
||||
consumeToken(operatorToken),
|
||||
parseAssignmentExpressionOrHigher());
|
||||
}
|
||||
}
|
||||
@ -2333,20 +2375,6 @@ module TypeScript.Parser {
|
||||
return parseAwaitExpression(awaitKeyword);
|
||||
}
|
||||
|
||||
// We're in a context where 'await expr' is not allowed. However, if we can
|
||||
// definitely tell that the user was trying to parse a 'await expr' and not
|
||||
// just a normal expr that start with a 'await' identifier, then parse out
|
||||
// an 'await expr'. We can then report an error later that they are only
|
||||
// allowed in async contexts.
|
||||
//
|
||||
// for example, if we see 'await(foo)', then we'll have to treat that as an
|
||||
// invocation expression of something called 'await'. However, if we have
|
||||
// 'await foo' then that is not legal as a normal expression, so we can
|
||||
// definitely recognize this as a await expression.
|
||||
//
|
||||
// for now we just check if the next token is an identifier. More heuristics
|
||||
// can be added here later as necessary. We just need to make sure that we
|
||||
// don't accidently consume something legal.
|
||||
if (isUnambiguouslyYieldOrAwaitExpression()) {
|
||||
return parseAwaitExpression(awaitKeyword);
|
||||
}
|
||||
@ -2562,7 +2590,7 @@ module TypeScript.Parser {
|
||||
// Precedence is okay, so we'll "take" this operator.
|
||||
// Now skip the operator token we're on.
|
||||
|
||||
leftOperand = new BinaryExpressionSyntax(contextFlags, leftOperand, consumeToken(operatorToken),
|
||||
leftOperand = new BinaryExpressionSyntax(contextFlags, leftOperand, consumeToken(operatorToken),
|
||||
parseBinaryExpressionOrHigher(currentToken(), newPrecedence));
|
||||
}
|
||||
|
||||
@ -2634,7 +2662,7 @@ module TypeScript.Parser {
|
||||
// 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(_currentToken);
|
||||
return <IMemberExpressionSyntax>parseMemberExpressionRest(expression);
|
||||
return <IMemberExpressionSyntax>parseMemberExpressionRest(expression);
|
||||
}
|
||||
|
||||
function parseMemberExpressionRest(expression: ILeftHandSideExpressionSyntax): ILeftHandSideExpressionSyntax {
|
||||
@ -2870,7 +2898,7 @@ module TypeScript.Parser {
|
||||
Debug.assert(openParenToken.kind === SyntaxKind.OpenParenToken && openParenToken.fullWidth() > 0);
|
||||
|
||||
return new ArgumentListSyntax(contextFlags,
|
||||
typeArgumentList,
|
||||
typeArgumentList,
|
||||
consumeToken(openParenToken),
|
||||
parseSeparatedSyntaxList<IExpressionSyntax>(ListParsingState.ArgumentList_AssignmentExpressions),
|
||||
eatToken(SyntaxKind.CloseParenToken));
|
||||
@ -2888,7 +2916,7 @@ module TypeScript.Parser {
|
||||
// cause a missing identiifer to be created), so that we will then consume the
|
||||
// comma and the following list items).
|
||||
var force = currentToken().kind === SyntaxKind.CommaToken;
|
||||
return (force || isExpression(currentToken())) ? allowInAnd(parseAssignmentExpressionOrHigher) : undefined;
|
||||
return (force || isExpression(currentToken())) ? allowInAnd(parseAssignmentExpressionOrHigher) : undefined;
|
||||
}
|
||||
|
||||
function parseElementAccessArgumentExpression(openBracketToken: ISyntaxToken) {
|
||||
@ -3035,7 +3063,7 @@ module TypeScript.Parser {
|
||||
if (startToken.kind === SyntaxKind.NoSubstitutionTemplateToken) {
|
||||
return startToken;
|
||||
}
|
||||
|
||||
|
||||
var templateClauses: TemplateClauseSyntax[] = [];
|
||||
|
||||
do {
|
||||
@ -3044,7 +3072,7 @@ module TypeScript.Parser {
|
||||
templateClauses.push(parseTemplateClause());
|
||||
}
|
||||
while (templateClauses[templateClauses.length - 1].templateMiddleOrEndToken.kind === SyntaxKind.TemplateMiddleToken);
|
||||
|
||||
|
||||
return new TemplateExpressionSyntax(contextFlags, startToken, Syntax.list(templateClauses));
|
||||
}
|
||||
|
||||
@ -3196,14 +3224,14 @@ module TypeScript.Parser {
|
||||
}
|
||||
|
||||
return isIdentifier(_currentToken) &&
|
||||
peekToken(1).kind === SyntaxKind.EqualsGreaterThanToken;
|
||||
peekToken(1).kind === SyntaxKind.EqualsGreaterThanToken;
|
||||
}
|
||||
|
||||
function parseSimpleArrowFunctionExpression(): SimpleArrowFunctionExpressionSyntax {
|
||||
var asyncKeyword: ISyntaxToken;
|
||||
return new SimpleArrowFunctionExpressionSyntax(contextFlags,
|
||||
asyncKeyword = tryEatToken(SyntaxKind.AsyncKeyword),
|
||||
asyncKeyword ? doInsideAsyncContext(eatSimpleParameter) : doOutsideAsyncContext(eatSimpleParameter),
|
||||
asyncKeyword ? doInsideAsyncContext(eatSimpleParameter) : doOutsideAsyncContext(eatSimpleParameter),
|
||||
eatToken(SyntaxKind.EqualsGreaterThanToken),
|
||||
parseArrowFunctionBody(/*asyncContext:*/ !!asyncKeyword));
|
||||
}
|
||||
@ -3252,8 +3280,8 @@ module TypeScript.Parser {
|
||||
token2 = peekToken(peekIndex + 2);
|
||||
var token2Kind = token2.kind;
|
||||
return token2Kind === SyntaxKind.ColonToken ||
|
||||
token2Kind === SyntaxKind.EqualsGreaterThanToken ||
|
||||
token2Kind === SyntaxKind.OpenBraceToken;
|
||||
token2Kind === SyntaxKind.EqualsGreaterThanToken ||
|
||||
token2Kind === SyntaxKind.OpenBraceToken;
|
||||
}
|
||||
|
||||
if (token1Kind === SyntaxKind.DotDotDotToken) {
|
||||
@ -3262,7 +3290,7 @@ module TypeScript.Parser {
|
||||
return true;
|
||||
}
|
||||
|
||||
token2 = peekToken(peekIndex + 2);
|
||||
token2 = peekToken(peekIndex + 2);
|
||||
token2Kind = token2.kind;
|
||||
|
||||
if (SyntaxFacts.isAccessibilityModifier(token1Kind)) {
|
||||
@ -3399,7 +3427,7 @@ module TypeScript.Parser {
|
||||
function parseObjectLiteralExpression(openBraceToken: ISyntaxToken): ObjectLiteralExpressionSyntax {
|
||||
// Debug.assert(currentToken().kind === SyntaxKind.OpenBraceToken);
|
||||
return new ObjectLiteralExpressionSyntax(contextFlags,
|
||||
consumeToken(openBraceToken),
|
||||
consumeToken(openBraceToken),
|
||||
parseSeparatedSyntaxList<IPropertyAssignmentSyntax>(ListParsingState.ObjectLiteralExpression_PropertyAssignments),
|
||||
eatToken(SyntaxKind.CloseBraceToken));
|
||||
}
|
||||
@ -3475,9 +3503,9 @@ module TypeScript.Parser {
|
||||
|
||||
function isPropertyAssignment(inErrorRecovery: boolean): boolean {
|
||||
return isAtModifier() ||
|
||||
isAccessor(inErrorRecovery) ||
|
||||
currentToken().kind === SyntaxKind.AsteriskToken ||
|
||||
isPropertyName(/*peekIndex:*/ 0, inErrorRecovery);
|
||||
isAccessor(inErrorRecovery) ||
|
||||
currentToken().kind === SyntaxKind.AsteriskToken ||
|
||||
isPropertyName(/*peekIndex:*/ 0, inErrorRecovery);
|
||||
}
|
||||
|
||||
function isPropertyName(peekIndex: number, inErrorRecovery: boolean): boolean {
|
||||
@ -3560,7 +3588,7 @@ module TypeScript.Parser {
|
||||
function parseArrayLiteralExpression(openBracketToken: ISyntaxToken): ArrayLiteralExpressionSyntax {
|
||||
// Debug.assert(currentToken().kind === SyntaxKind.OpenBracketToken);
|
||||
return new ArrayLiteralExpressionSyntax(contextFlags,
|
||||
consumeToken(openBracketToken),
|
||||
consumeToken(openBracketToken),
|
||||
parseSeparatedSyntaxList<IExpressionSyntax>(ListParsingState.ArrayLiteralExpression_AssignmentExpressions),
|
||||
eatToken(SyntaxKind.CloseBracketToken));
|
||||
}
|
||||
@ -3834,7 +3862,7 @@ module TypeScript.Parser {
|
||||
var barToken: ISyntaxToken;
|
||||
while ((barToken = currentToken()).kind === SyntaxKind.BarToken) {
|
||||
type = new UnionTypeSyntax(contextFlags, type, consumeToken(barToken), parsePrimaryType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
@ -3843,7 +3871,7 @@ module TypeScript.Parser {
|
||||
function parsePrimaryType(): ITypeSyntax {
|
||||
return tryParsePrimaryType() || eatIdentifierToken(DiagnosticCode.Type_expected);
|
||||
}
|
||||
|
||||
|
||||
function tryParsePrimaryType(): ITypeSyntax {
|
||||
// First consume any underlying element type.
|
||||
var type = tryParseNonArrayType();
|
||||
@ -3885,10 +3913,10 @@ module TypeScript.Parser {
|
||||
}
|
||||
|
||||
return consumeToken(_currentToken);
|
||||
case SyntaxKind.VoidKeyword: return consumeToken(_currentToken);
|
||||
case SyntaxKind.OpenParenToken: return parseParenthesizedType(_currentToken);
|
||||
case SyntaxKind.OpenBraceToken: return parseObjectType();
|
||||
case SyntaxKind.TypeOfKeyword: return parseTypeQuery(_currentToken);
|
||||
case SyntaxKind.VoidKeyword: return consumeToken(_currentToken);
|
||||
case SyntaxKind.OpenParenToken: return parseParenthesizedType(_currentToken);
|
||||
case SyntaxKind.OpenBraceToken: return parseObjectType();
|
||||
case SyntaxKind.TypeOfKeyword: return parseTypeQuery(_currentToken);
|
||||
case SyntaxKind.OpenBracketToken: return parseTupleType(_currentToken);
|
||||
}
|
||||
|
||||
@ -3992,7 +4020,7 @@ module TypeScript.Parser {
|
||||
// Function types only exist in the type space and not the expression space. So they
|
||||
// aren't in the [Yield] or [GeneratorParameter] context.
|
||||
return new FunctionTypeSyntax(contextFlags,
|
||||
tryParseTypeParameterList(/*requireCompleteTypeParameterList:*/ false),
|
||||
tryParseTypeParameterList(/*requireCompleteTypeParameterList:*/ false),
|
||||
parseParameterList(/*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false),
|
||||
eatToken(SyntaxKind.EqualsGreaterThanToken), parseType());
|
||||
}
|
||||
@ -4014,13 +4042,13 @@ module TypeScript.Parser {
|
||||
function isParameterHelper(token: ISyntaxToken): boolean {
|
||||
var tokenKind = token.kind;
|
||||
return tokenKind === SyntaxKind.DotDotDotToken ||
|
||||
isModifierKind(tokenKind) ||
|
||||
isIdentifier(token);
|
||||
isModifierKind(tokenKind) ||
|
||||
isIdentifier(token);
|
||||
}
|
||||
|
||||
function eatSimpleParameter() {
|
||||
return new ParameterSyntax(contextFlags,
|
||||
/*dotDotDotToken:*/ undefined, /*modifiers:*/ [], eatIdentifierToken(),
|
||||
/*dotDotDotToken:*/ undefined, /*modifiers:*/[], eatIdentifierToken(),
|
||||
/*questionToken:*/ undefined, /*typeAnnotation:*/ undefined, /*equalsValueClause:*/ undefined);
|
||||
}
|
||||
|
||||
@ -4058,8 +4086,8 @@ module TypeScript.Parser {
|
||||
var equalsValueClause: EqualsValueClauseSyntax = undefined;
|
||||
if (isEqualsValueClause(/*inParameter*/ true)) {
|
||||
equalsValueClause = inGeneratorParameterContext()
|
||||
? doOutsideYieldContext(parseEqualsValueClause)
|
||||
: parseEqualsValueClause();
|
||||
? doOutsideYieldContext(parseEqualsValueClause)
|
||||
: parseEqualsValueClause();
|
||||
}
|
||||
|
||||
return new ParameterSyntax(contextFlags, dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause);
|
||||
@ -4115,10 +4143,10 @@ module TypeScript.Parser {
|
||||
}
|
||||
|
||||
function tryParseExpectedListItem<T extends ISyntaxNodeOrToken>(
|
||||
currentListType: ListParsingState,
|
||||
inErrorRecovery: boolean,
|
||||
items: T[],
|
||||
processItems: (items: ISyntaxNodeOrToken[]) => void): void {
|
||||
currentListType: ListParsingState,
|
||||
inErrorRecovery: boolean,
|
||||
items: T[],
|
||||
processItems: (items: ISyntaxNodeOrToken[]) => void): void {
|
||||
var item = <T>tryParseExpectedListItemWorker(currentListType, inErrorRecovery);
|
||||
|
||||
if (item !== undefined) {
|
||||
@ -4134,10 +4162,10 @@ module TypeScript.Parser {
|
||||
|
||||
function listIsTerminated(currentListType: ListParsingState): boolean {
|
||||
return isExpectedListTerminator(currentListType) ||
|
||||
currentToken().kind === SyntaxKind.EndOfFileToken;
|
||||
currentToken().kind === SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
|
||||
function parseSyntaxListWorker<T extends ISyntaxNodeOrToken>(currentListType: ListParsingState, processItems: (items: ISyntaxNodeOrToken[]) => void ): T[] {
|
||||
function parseSyntaxListWorker<T extends ISyntaxNodeOrToken>(currentListType: ListParsingState, processItems: (items: ISyntaxNodeOrToken[]) => void): T[] {
|
||||
var items: T[] = [];
|
||||
|
||||
while (true) {
|
||||
@ -4272,27 +4300,27 @@ module TypeScript.Parser {
|
||||
|
||||
function isExpectedListTerminator(currentListType: ListParsingState): boolean {
|
||||
switch (currentListType) {
|
||||
case ListParsingState.SourceUnit_ModuleElements: return isExpectedSourceUnit_ModuleElementsTerminator();
|
||||
case ListParsingState.ClassDeclaration_ClassElements: return isExpectedClassDeclaration_ClassElementsTerminator();
|
||||
case ListParsingState.ModuleDeclaration_ModuleElements: return isExpectedModuleDeclaration_ModuleElementsTerminator();
|
||||
case ListParsingState.SwitchStatement_SwitchClauses: return isExpectedSwitchStatement_SwitchClausesTerminator();
|
||||
case ListParsingState.SwitchClause_Statements: return isExpectedSwitchClause_StatementsTerminator();
|
||||
case ListParsingState.Block_Statements: return isExpectedBlock_StatementsTerminator();
|
||||
case ListParsingState.TryBlock_Statements: return isExpectedTryBlock_StatementsTerminator();
|
||||
case ListParsingState.CatchBlock_Statements: return isExpectedCatchBlock_StatementsTerminator();
|
||||
case ListParsingState.EnumDeclaration_EnumElements: return isExpectedEnumDeclaration_EnumElementsTerminator();
|
||||
case ListParsingState.ObjectType_TypeMembers: return isExpectedObjectType_TypeMembersTerminator();
|
||||
case ListParsingState.ClassOrInterfaceDeclaration_HeritageClauses: return isExpectedClassOrInterfaceDeclaration_HeritageClausesTerminator();
|
||||
case ListParsingState.HeritageClause_TypeNameList: return isExpectedHeritageClause_TypeNameListTerminator();
|
||||
case ListParsingState.VariableDeclaration_VariableDeclarators: return isExpectedVariableDeclaration_VariableDeclaratorsTerminator();
|
||||
case ListParsingState.ArgumentList_AssignmentExpressions: return isExpectedArgumentList_AssignmentExpressionsTerminator();
|
||||
case ListParsingState.ObjectLiteralExpression_PropertyAssignments: return isExpectedObjectLiteralExpression_PropertyAssignmentsTerminator();
|
||||
case ListParsingState.ArrayLiteralExpression_AssignmentExpressions: return isExpectedLiteralExpression_AssignmentExpressionsTerminator();
|
||||
case ListParsingState.ParameterList_Parameters: return isExpectedParameterList_ParametersTerminator();
|
||||
case ListParsingState.IndexSignature_Parameters: return isExpectedIndexSignature_ParametersTerminator();
|
||||
case ListParsingState.TypeArgumentList_Types: return isExpectedTypeArgumentList_TypesTerminator();
|
||||
case ListParsingState.TypeParameterList_TypeParameters: return isExpectedTypeParameterList_TypeParametersTerminator();
|
||||
case ListParsingState.TupleType_Types: return isExpectedTupleType_TypesTerminator();
|
||||
case ListParsingState.SourceUnit_ModuleElements: return isExpectedSourceUnit_ModuleElementsTerminator();
|
||||
case ListParsingState.ClassDeclaration_ClassElements: return isExpectedClassDeclaration_ClassElementsTerminator();
|
||||
case ListParsingState.ModuleDeclaration_ModuleElements: return isExpectedModuleDeclaration_ModuleElementsTerminator();
|
||||
case ListParsingState.SwitchStatement_SwitchClauses: return isExpectedSwitchStatement_SwitchClausesTerminator();
|
||||
case ListParsingState.SwitchClause_Statements: return isExpectedSwitchClause_StatementsTerminator();
|
||||
case ListParsingState.Block_Statements: return isExpectedBlock_StatementsTerminator();
|
||||
case ListParsingState.TryBlock_Statements: return isExpectedTryBlock_StatementsTerminator();
|
||||
case ListParsingState.CatchBlock_Statements: return isExpectedCatchBlock_StatementsTerminator();
|
||||
case ListParsingState.EnumDeclaration_EnumElements: return isExpectedEnumDeclaration_EnumElementsTerminator();
|
||||
case ListParsingState.ObjectType_TypeMembers: return isExpectedObjectType_TypeMembersTerminator();
|
||||
case ListParsingState.ClassOrInterfaceDeclaration_HeritageClauses: return isExpectedClassOrInterfaceDeclaration_HeritageClausesTerminator();
|
||||
case ListParsingState.HeritageClause_TypeNameList: return isExpectedHeritageClause_TypeNameListTerminator();
|
||||
case ListParsingState.VariableDeclaration_VariableDeclarators: return isExpectedVariableDeclaration_VariableDeclaratorsTerminator();
|
||||
case ListParsingState.ArgumentList_AssignmentExpressions: return isExpectedArgumentList_AssignmentExpressionsTerminator();
|
||||
case ListParsingState.ObjectLiteralExpression_PropertyAssignments: return isExpectedObjectLiteralExpression_PropertyAssignmentsTerminator();
|
||||
case ListParsingState.ArrayLiteralExpression_AssignmentExpressions: return isExpectedLiteralExpression_AssignmentExpressionsTerminator();
|
||||
case ListParsingState.ParameterList_Parameters: return isExpectedParameterList_ParametersTerminator();
|
||||
case ListParsingState.IndexSignature_Parameters: return isExpectedIndexSignature_ParametersTerminator();
|
||||
case ListParsingState.TypeArgumentList_Types: return isExpectedTypeArgumentList_TypesTerminator();
|
||||
case ListParsingState.TypeParameterList_TypeParameters: return isExpectedTypeParameterList_TypeParametersTerminator();
|
||||
case ListParsingState.TupleType_Types: return isExpectedTupleType_TypesTerminator();
|
||||
default:
|
||||
throw Errors.invalidOperation();
|
||||
}
|
||||
@ -4462,7 +4490,7 @@ module TypeScript.Parser {
|
||||
var token0 = currentToken();
|
||||
var tokenKind = token0.kind;
|
||||
return tokenKind === SyntaxKind.CloseParenToken ||
|
||||
tokenKind === SyntaxKind.SemicolonToken;
|
||||
tokenKind === SyntaxKind.SemicolonToken;
|
||||
}
|
||||
|
||||
function isExpectedClassDeclaration_ClassElementsTerminator(): boolean {
|
||||
@ -4475,7 +4503,7 @@ module TypeScript.Parser {
|
||||
|
||||
function isExpectedSwitchClause_StatementsTerminator(): boolean {
|
||||
return currentToken().kind === SyntaxKind.CloseBraceToken ||
|
||||
isSwitchClause();
|
||||
isSwitchClause();
|
||||
}
|
||||
|
||||
function isExpectedBlock_StatementsTerminator(): boolean {
|
||||
@ -4485,7 +4513,7 @@ module TypeScript.Parser {
|
||||
function isExpectedTryBlock_StatementsTerminator(): boolean {
|
||||
var tokenKind = currentToken().kind;
|
||||
return tokenKind === SyntaxKind.CatchKeyword ||
|
||||
tokenKind === SyntaxKind.FinallyKeyword;
|
||||
tokenKind === SyntaxKind.FinallyKeyword;
|
||||
}
|
||||
|
||||
function isExpectedCatchBlock_StatementsTerminator(): boolean {
|
||||
@ -4553,27 +4581,27 @@ module TypeScript.Parser {
|
||||
}
|
||||
|
||||
switch (currentListType) {
|
||||
case ListParsingState.SourceUnit_ModuleElements: return tryParseModuleElement(inErrorRecovery);
|
||||
case ListParsingState.ClassDeclaration_ClassElements: return tryParseClassElement(inErrorRecovery);
|
||||
case ListParsingState.ModuleDeclaration_ModuleElements: return tryParseModuleElement(inErrorRecovery);
|
||||
case ListParsingState.SwitchStatement_SwitchClauses: return tryParseSwitchClause();
|
||||
case ListParsingState.SwitchClause_Statements: return tryParseStatement(inErrorRecovery);
|
||||
case ListParsingState.Block_Statements: return tryParseStatement(inErrorRecovery);
|
||||
case ListParsingState.TryBlock_Statements: return tryParseStatement(inErrorRecovery);
|
||||
case ListParsingState.CatchBlock_Statements: return tryParseStatement(inErrorRecovery);
|
||||
case ListParsingState.EnumDeclaration_EnumElements: return tryParseEnumElement(inErrorRecovery);
|
||||
case ListParsingState.ObjectType_TypeMembers: return tryParseTypeMember(inErrorRecovery);
|
||||
case ListParsingState.ClassOrInterfaceDeclaration_HeritageClauses: return tryParseHeritageClause();
|
||||
case ListParsingState.HeritageClause_TypeNameList: return tryParseHeritageClauseTypeName();
|
||||
case ListParsingState.VariableDeclaration_VariableDeclarators: return tryParseVariableDeclarator();
|
||||
case ListParsingState.ArgumentList_AssignmentExpressions: return tryParseArgumentListExpression();
|
||||
case ListParsingState.ObjectLiteralExpression_PropertyAssignments: return tryParsePropertyAssignment(inErrorRecovery);
|
||||
case ListParsingState.SourceUnit_ModuleElements: return tryParseModuleElement(inErrorRecovery);
|
||||
case ListParsingState.ClassDeclaration_ClassElements: return tryParseClassElement(inErrorRecovery);
|
||||
case ListParsingState.ModuleDeclaration_ModuleElements: return tryParseModuleElement(inErrorRecovery);
|
||||
case ListParsingState.SwitchStatement_SwitchClauses: return tryParseSwitchClause();
|
||||
case ListParsingState.SwitchClause_Statements: return tryParseStatement(inErrorRecovery);
|
||||
case ListParsingState.Block_Statements: return tryParseStatement(inErrorRecovery);
|
||||
case ListParsingState.TryBlock_Statements: return tryParseStatement(inErrorRecovery);
|
||||
case ListParsingState.CatchBlock_Statements: return tryParseStatement(inErrorRecovery);
|
||||
case ListParsingState.EnumDeclaration_EnumElements: return tryParseEnumElement(inErrorRecovery);
|
||||
case ListParsingState.ObjectType_TypeMembers: return tryParseTypeMember(inErrorRecovery);
|
||||
case ListParsingState.ClassOrInterfaceDeclaration_HeritageClauses: return tryParseHeritageClause();
|
||||
case ListParsingState.HeritageClause_TypeNameList: return tryParseHeritageClauseTypeName();
|
||||
case ListParsingState.VariableDeclaration_VariableDeclarators: return tryParseVariableDeclarator();
|
||||
case ListParsingState.ArgumentList_AssignmentExpressions: return tryParseArgumentListExpression();
|
||||
case ListParsingState.ObjectLiteralExpression_PropertyAssignments: return tryParsePropertyAssignment(inErrorRecovery);
|
||||
case ListParsingState.ArrayLiteralExpression_AssignmentExpressions: return tryParseAssignmentOrOmittedExpression();
|
||||
case ListParsingState.ParameterList_Parameters: return tryParseParameter();
|
||||
case ListParsingState.IndexSignature_Parameters: return tryParseParameter();
|
||||
case ListParsingState.TypeArgumentList_Types: return tryParseType();
|
||||
case ListParsingState.TypeParameterList_TypeParameters: return tryParseTypeParameter();
|
||||
case ListParsingState.TupleType_Types: return tryParseType();
|
||||
case ListParsingState.ParameterList_Parameters: return tryParseParameter();
|
||||
case ListParsingState.IndexSignature_Parameters: return tryParseParameter();
|
||||
case ListParsingState.TypeArgumentList_Types: return tryParseType();
|
||||
case ListParsingState.TypeParameterList_TypeParameters: return tryParseTypeParameter();
|
||||
case ListParsingState.TupleType_Types: return tryParseType();
|
||||
default: throw Errors.invalidOperation();
|
||||
}
|
||||
}
|
||||
@ -4725,26 +4753,26 @@ module TypeScript.Parser {
|
||||
|
||||
function getExpectedListElementType(currentListType: ListParsingState): string {
|
||||
switch (currentListType) {
|
||||
case ListParsingState.SourceUnit_ModuleElements: return getLocalizedText(DiagnosticCode.module_class_interface_enum_import_or_statement, undefined);
|
||||
case ListParsingState.ClassOrInterfaceDeclaration_HeritageClauses: return '{';
|
||||
case ListParsingState.ClassDeclaration_ClassElements: return getLocalizedText(DiagnosticCode.constructor_function_accessor_or_variable, undefined);
|
||||
case ListParsingState.ModuleDeclaration_ModuleElements: return getLocalizedText(DiagnosticCode.module_class_interface_enum_import_or_statement, undefined);
|
||||
case ListParsingState.SwitchStatement_SwitchClauses: return getLocalizedText(DiagnosticCode.case_or_default_clause, undefined);
|
||||
case ListParsingState.SwitchClause_Statements: return getLocalizedText(DiagnosticCode.statement, undefined);
|
||||
case ListParsingState.Block_Statements: return getLocalizedText(DiagnosticCode.statement, undefined);
|
||||
case ListParsingState.VariableDeclaration_VariableDeclarators: return getLocalizedText(DiagnosticCode.identifier, undefined);
|
||||
case ListParsingState.EnumDeclaration_EnumElements: return getLocalizedText(DiagnosticCode.identifier, undefined);
|
||||
case ListParsingState.ObjectType_TypeMembers: return getLocalizedText(DiagnosticCode.call_construct_index_property_or_function_signature, undefined);
|
||||
case ListParsingState.ArgumentList_AssignmentExpressions: return getLocalizedText(DiagnosticCode.expression, undefined);
|
||||
case ListParsingState.HeritageClause_TypeNameList: return getLocalizedText(DiagnosticCode.type_name, undefined);
|
||||
case ListParsingState.ObjectLiteralExpression_PropertyAssignments: return getLocalizedText(DiagnosticCode.property_or_accessor, undefined);
|
||||
case ListParsingState.ParameterList_Parameters: return getLocalizedText(DiagnosticCode.parameter, undefined);
|
||||
case ListParsingState.IndexSignature_Parameters: return getLocalizedText(DiagnosticCode.parameter, undefined);
|
||||
case ListParsingState.TypeArgumentList_Types: return getLocalizedText(DiagnosticCode.type, undefined);
|
||||
case ListParsingState.TypeParameterList_TypeParameters: return getLocalizedText(DiagnosticCode.type_parameter, undefined);
|
||||
case ListParsingState.TupleType_Types: return getLocalizedText(DiagnosticCode.type, undefined);
|
||||
case ListParsingState.SourceUnit_ModuleElements: return getLocalizedText(DiagnosticCode.module_class_interface_enum_import_or_statement, undefined);
|
||||
case ListParsingState.ClassOrInterfaceDeclaration_HeritageClauses: return '{';
|
||||
case ListParsingState.ClassDeclaration_ClassElements: return getLocalizedText(DiagnosticCode.constructor_function_accessor_or_variable, undefined);
|
||||
case ListParsingState.ModuleDeclaration_ModuleElements: return getLocalizedText(DiagnosticCode.module_class_interface_enum_import_or_statement, undefined);
|
||||
case ListParsingState.SwitchStatement_SwitchClauses: return getLocalizedText(DiagnosticCode.case_or_default_clause, undefined);
|
||||
case ListParsingState.SwitchClause_Statements: return getLocalizedText(DiagnosticCode.statement, undefined);
|
||||
case ListParsingState.Block_Statements: return getLocalizedText(DiagnosticCode.statement, undefined);
|
||||
case ListParsingState.VariableDeclaration_VariableDeclarators: return getLocalizedText(DiagnosticCode.identifier, undefined);
|
||||
case ListParsingState.EnumDeclaration_EnumElements: return getLocalizedText(DiagnosticCode.identifier, undefined);
|
||||
case ListParsingState.ObjectType_TypeMembers: return getLocalizedText(DiagnosticCode.call_construct_index_property_or_function_signature, undefined);
|
||||
case ListParsingState.ArgumentList_AssignmentExpressions: return getLocalizedText(DiagnosticCode.expression, undefined);
|
||||
case ListParsingState.HeritageClause_TypeNameList: return getLocalizedText(DiagnosticCode.type_name, undefined);
|
||||
case ListParsingState.ObjectLiteralExpression_PropertyAssignments: return getLocalizedText(DiagnosticCode.property_or_accessor, undefined);
|
||||
case ListParsingState.ParameterList_Parameters: return getLocalizedText(DiagnosticCode.parameter, undefined);
|
||||
case ListParsingState.IndexSignature_Parameters: return getLocalizedText(DiagnosticCode.parameter, undefined);
|
||||
case ListParsingState.TypeArgumentList_Types: return getLocalizedText(DiagnosticCode.type, undefined);
|
||||
case ListParsingState.TypeParameterList_TypeParameters: return getLocalizedText(DiagnosticCode.type_parameter, undefined);
|
||||
case ListParsingState.TupleType_Types: return getLocalizedText(DiagnosticCode.type, undefined);
|
||||
case ListParsingState.ArrayLiteralExpression_AssignmentExpressions: return getLocalizedText(DiagnosticCode.expression, undefined);
|
||||
default: throw Errors.invalidOperation();
|
||||
default: throw Errors.invalidOperation();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4792,7 +4820,7 @@ module TypeScript.Parser {
|
||||
//
|
||||
// The code to do this uses the above logic. It will see an operator with the same precedence,
|
||||
// and so it won't consume it.
|
||||
enum BinaryExpressionPrecedence {
|
||||
const enum BinaryExpressionPrecedence {
|
||||
Lowest = 1,
|
||||
|
||||
// Intuitively, logical || have the lowest precedence. "a || b && c" is "a || (b && c)", not
|
||||
|
||||
@ -60,15 +60,15 @@ module TypeScript.Scanner {
|
||||
// This gives us 23bit for width (or 8MB of width which should be enough for any codebase).
|
||||
|
||||
enum ScannerConstants {
|
||||
LargeTokenFullWidthShift = 3,
|
||||
LargeTokenFullWidthShift = 3,
|
||||
|
||||
WhitespaceTrivia = 0x01, // 00000001
|
||||
NewlineTrivia = 0x02, // 00000010
|
||||
CommentTrivia = 0x04, // 00000100
|
||||
TriviaMask = 0x07, // 00000111
|
||||
WhitespaceTrivia = 0x01, // 00000001
|
||||
NewlineTrivia = 0x02, // 00000010
|
||||
CommentTrivia = 0x04, // 00000100
|
||||
TriviaMask = 0x07, // 00000111
|
||||
|
||||
KindMask = 0x7F, // 01111111
|
||||
IsVariableWidthMask = 0x80, // 10000000
|
||||
KindMask = 0x7F, // 01111111
|
||||
IsVariableWidthMask = 0x80, // 10000000
|
||||
}
|
||||
|
||||
function largeTokenPackData(fullWidth: number, leadingTriviaInfo: number) {
|
||||
@ -154,7 +154,7 @@ module TypeScript.Scanner {
|
||||
var lastTokenInfo = { leadingTriviaWidth: -1 };
|
||||
var lastTokenInfoTokenID: number = -1;
|
||||
|
||||
var triviaScanner = createScannerInternal(ts.ScriptTarget.Latest, SimpleText.fromString(""), () => { });
|
||||
var triviaScanner = createScannerInternal(ts.ScriptTarget.Latest, SimpleText.fromString(""),() => { });
|
||||
|
||||
interface IScannerToken extends ISyntaxToken {
|
||||
}
|
||||
@ -208,7 +208,7 @@ module TypeScript.Scanner {
|
||||
public setFullStart(fullStart: number): void {
|
||||
this._fullStart = fullStart;
|
||||
}
|
||||
|
||||
|
||||
public childAt(index: number): ISyntaxElement { throw Errors.invalidOperation() }
|
||||
|
||||
public isIncrementallyUnusable(): boolean { return false; }
|
||||
@ -1425,7 +1425,7 @@ module TypeScript.Scanner {
|
||||
|
||||
export function isValidIdentifier(text: ISimpleText, languageVersion: ts.ScriptTarget): boolean {
|
||||
var hadError = false;
|
||||
var scanner = createScanner(languageVersion, text, () => hadError = true);
|
||||
var scanner = createScanner(languageVersion, text,() => hadError = true);
|
||||
|
||||
var token = scanner.scan(/*allowContextualToken:*/ false);
|
||||
|
||||
@ -1467,7 +1467,7 @@ module TypeScript.Scanner {
|
||||
return _absolutePosition;
|
||||
}
|
||||
|
||||
function tokenDiagnostics(): Diagnostic[] {
|
||||
function diagnostics(): Diagnostic[] {
|
||||
return _tokenDiagnostics;
|
||||
}
|
||||
|
||||
@ -1598,8 +1598,8 @@ module TypeScript.Scanner {
|
||||
peekToken: peekToken,
|
||||
consumeNodeOrToken: consumeNodeOrToken,
|
||||
tryParse: tryParse,
|
||||
tokenDiagnostics: tokenDiagnostics,
|
||||
absolutePosition: absolutePosition,
|
||||
diagnostics: diagnostics,
|
||||
absolutePosition: absolutePosition
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ var interfaces: any = {
|
||||
IPrimaryExpressionSyntax: 'IMemberExpressionSyntax',
|
||||
};
|
||||
|
||||
var definitions:ITypeDefinition[] = [
|
||||
var definitions: ITypeDefinition[] = [
|
||||
<any>{
|
||||
name: 'SourceUnitSyntax',
|
||||
baseType: 'ISyntaxNode',
|
||||
@ -55,10 +55,10 @@ var definitions:ITypeDefinition[] = [
|
||||
baseType: 'ISyntaxNode',
|
||||
interfaces: ['IModuleReferenceSyntax'],
|
||||
children: [
|
||||
<any>{ name: 'requireKeyword', isToken: true, excludeFromAST: true },
|
||||
<any>{ name: 'openParenToken', isToken: true, excludeFromAST: true },
|
||||
<any>{ name: 'stringLiteral', isToken: true },
|
||||
<any>{ name: 'closeParenToken', isToken: true, excludeFromAST: true }
|
||||
<any>{ name: 'requireKeyword', isToken: true },
|
||||
<any>{ name: 'openParenToken', isToken: true },
|
||||
<any>{ name: 'expression', type: 'IExpressionSyntax' },
|
||||
<any>{ name: 'closeParenToken', isToken: true }
|
||||
],
|
||||
isTypeScriptSpecific: true
|
||||
},
|
||||
@ -665,7 +665,7 @@ var definitions:ITypeDefinition[] = [
|
||||
<any>{ name: 'modifiers', isList: true, elementType: 'ISyntaxToken' },
|
||||
<any>{ name: 'constructorKeyword', isToken: true },
|
||||
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
|
||||
],
|
||||
isTypeScriptSpecific: true
|
||||
},
|
||||
@ -678,20 +678,20 @@ var definitions:ITypeDefinition[] = [
|
||||
<any>{ name: 'asterixToken', isToken: true, isOptional: true },
|
||||
<any>{ name: 'propertyName', type: 'IPropertyNameSyntax' },
|
||||
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
|
||||
],
|
||||
isTypeScriptSpecific: true
|
||||
},
|
||||
<any>{
|
||||
name: 'GetAccessorSyntax',
|
||||
baseType: 'ISyntaxNode',
|
||||
interfaces: ['IAccessorSyntax' ],
|
||||
interfaces: ['IAccessorSyntax'],
|
||||
children: [
|
||||
<any>{ name: 'modifiers', isList: true, elementType: 'ISyntaxToken', isTypeScriptSpecific: true },
|
||||
<any>{ name: 'getKeyword', isToken: true, excludeFromAST: true },
|
||||
<any>{ name: 'propertyName', type: 'IPropertyNameSyntax' },
|
||||
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
|
||||
]
|
||||
},
|
||||
<any>{
|
||||
@ -703,7 +703,7 @@ var definitions:ITypeDefinition[] = [
|
||||
<any>{ name: 'setKeyword', isToken: true, excludeFromAST: true },
|
||||
<any>{ name: 'propertyName', type: 'IPropertyNameSyntax' },
|
||||
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
|
||||
],
|
||||
isTypeScriptSpecific: true
|
||||
},
|
||||
@ -769,7 +769,7 @@ var definitions:ITypeDefinition[] = [
|
||||
children: [
|
||||
<any>{ name: 'caseKeyword', isToken: true, excludeFromAST: true },
|
||||
<any>{ name: 'expression', type: 'IExpressionSyntax' },
|
||||
<any>{ name: 'colonToken', isToken: true, excludeFromAST: true},
|
||||
<any>{ name: 'colonToken', isToken: true, excludeFromAST: true },
|
||||
<any>{ name: 'statements', isList: true, elementType: 'IStatementSyntax' }
|
||||
]
|
||||
},
|
||||
@ -931,7 +931,7 @@ var definitions:ITypeDefinition[] = [
|
||||
<any>{ name: 'asterixToken', isToken: true, isOptional: true },
|
||||
<any>{ name: 'identifier', isToken: true, isOptional: true },
|
||||
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }]
|
||||
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }]
|
||||
},
|
||||
<any>{
|
||||
name: 'EmptyStatementSyntax',
|
||||
@ -1104,41 +1104,19 @@ function generateConstructorFunction(definition: ITypeDefinition) {
|
||||
result += ") {\r\n";
|
||||
|
||||
result += " if (data) { this.__data = data; }\r\n";
|
||||
|
||||
result += " this.parent = undefined";
|
||||
if (definition.children.length) {
|
||||
result += " ";
|
||||
|
||||
for (var i = 0; i < definition.children.length; i++) {
|
||||
if (i) {
|
||||
result += ", ";
|
||||
}
|
||||
//if (i) {
|
||||
result += ",\r\n";
|
||||
//}
|
||||
|
||||
var child = definition.children[i];
|
||||
result += "this." + child.name + " = " + getSafeName(child);
|
||||
result += " this." + child.name + " = " + getSafeName(child);
|
||||
}
|
||||
|
||||
result += ";\r\n";
|
||||
}
|
||||
|
||||
if (definition.children.length > 0) {
|
||||
result += " ";
|
||||
|
||||
for (var i = 0; i < definition.children.length; i++) {
|
||||
if (i) {
|
||||
result += ", ";
|
||||
}
|
||||
|
||||
var child = definition.children[i];
|
||||
|
||||
if (child.isOptional) {
|
||||
result += getSafeName(child) + " && (" + getSafeName(child) + ".parent = this)";
|
||||
}
|
||||
else {
|
||||
result += getSafeName(child) + ".parent = this";
|
||||
}
|
||||
}
|
||||
result += ";\r\n";
|
||||
}
|
||||
result += ";\r\n";
|
||||
|
||||
result += " };\r\n";
|
||||
result += " " + definition.name + ".prototype.kind = SyntaxKind." + getNameWithoutSuffix(definition) + ";\r\n";
|
||||
@ -1202,7 +1180,7 @@ function generateSyntaxInterface(definition: ITypeDefinition): string {
|
||||
result += " }\r\n";
|
||||
result += " export interface " + getNameWithoutSuffix(definition) + "Constructor {";
|
||||
result += " new (data: number";
|
||||
|
||||
|
||||
for (var i = 0; i < definition.children.length; i++) {
|
||||
var child = definition.children[i];
|
||||
result += ", ";
|
||||
@ -1338,7 +1316,7 @@ function generateKeywordCondition(keywords: { text: string; kind: TypeScript.Syn
|
||||
|
||||
if (keywords.length === 1) {
|
||||
var keyword = keywords[0];
|
||||
|
||||
|
||||
if (currentCharacter === length) {
|
||||
return " return SyntaxKind." + firstEnumName(getSyntaxKindEnum(), keyword.kind) + ";\r\n";
|
||||
}
|
||||
|
||||
@ -702,10 +702,10 @@ module TypeScript {
|
||||
export interface ExternalModuleReferenceSyntax extends ISyntaxNode, IModuleReferenceSyntax {
|
||||
requireKeyword: ISyntaxToken;
|
||||
openParenToken: ISyntaxToken;
|
||||
stringLiteral: ISyntaxToken;
|
||||
expression: IExpressionSyntax;
|
||||
closeParenToken: ISyntaxToken;
|
||||
}
|
||||
export interface ExternalModuleReferenceConstructor { new (data: number, requireKeyword: ISyntaxToken, openParenToken: ISyntaxToken, stringLiteral: ISyntaxToken, closeParenToken: ISyntaxToken): ExternalModuleReferenceSyntax }
|
||||
export interface ExternalModuleReferenceConstructor { new (data: number, requireKeyword: ISyntaxToken, openParenToken: ISyntaxToken, expression: IExpressionSyntax, closeParenToken: ISyntaxToken): ExternalModuleReferenceSyntax }
|
||||
|
||||
export interface ModuleNameModuleReferenceSyntax extends ISyntaxNode, IModuleReferenceSyntax {
|
||||
moduleName: INameSyntax;
|
||||
|
||||
@ -48,22 +48,10 @@ module TypeScript.Syntax {
|
||||
addArrayPrototypeValue("kind", SyntaxKind.List);
|
||||
|
||||
export function list<T extends ISyntaxNodeOrToken>(nodes: T[]): T[] {
|
||||
if (nodes !== undefined) {
|
||||
for (var i = 0, n = nodes.length; i < n; i++) {
|
||||
nodes[i].parent = nodes;
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
export function separatedList<T extends ISyntaxNodeOrToken>(nodesAndTokens: ISyntaxNodeOrToken[]): ISeparatedSyntaxList<T> {
|
||||
if (nodesAndTokens !== undefined) {
|
||||
for (var i = 0, n = nodesAndTokens.length; i < n; i++) {
|
||||
nodesAndTokens[i].parent = nodesAndTokens;
|
||||
}
|
||||
}
|
||||
|
||||
return <ISeparatedSyntaxList<T>>nodesAndTokens;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -74,55 +74,11 @@ module TypeScript {
|
||||
return this._languageVersion;
|
||||
}
|
||||
|
||||
private cacheSyntaxTreeInfo(): void {
|
||||
// If we're not keeping around the syntax tree, store the diagnostics and line
|
||||
// map so they don't have to be recomputed.
|
||||
var firstToken = firstSyntaxTreeToken(this);
|
||||
var leadingTrivia = firstToken.leadingTrivia(this.text);
|
||||
|
||||
this._isExternalModule = !!externalModuleIndicatorSpanWorker(this, firstToken);
|
||||
|
||||
var amdDependencies: string[] = [];
|
||||
for (var i = 0, n = leadingTrivia.count(); i < n; i++) {
|
||||
var trivia = leadingTrivia.syntaxTriviaAt(i);
|
||||
if (trivia.isComment()) {
|
||||
var amdDependency = this.getAmdDependency(trivia.fullText());
|
||||
if (amdDependency) {
|
||||
amdDependencies.push(amdDependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._amdDependencies = amdDependencies;
|
||||
}
|
||||
|
||||
private getAmdDependency(comment: string): string {
|
||||
var amdDependencyRegEx = /^\/\/\/\s*<amd-dependency\s+path=('|")(.+?)\1/gim;
|
||||
var match = amdDependencyRegEx.exec(comment);
|
||||
return match ? match[2] : undefined;
|
||||
}
|
||||
|
||||
public isExternalModule(): boolean {
|
||||
// October 11, 2013
|
||||
// External modules are written as separate source files that contain at least one
|
||||
// external import declaration, export assignment, or top-level exported declaration.
|
||||
if (this._isExternalModule === undefined) {
|
||||
// force the info about isExternalModule to get created.
|
||||
this.cacheSyntaxTreeInfo();
|
||||
Debug.assert(this._isExternalModule !== undefined);
|
||||
}
|
||||
|
||||
return this._isExternalModule;
|
||||
}
|
||||
|
||||
public amdDependencies(): string[] {
|
||||
if (this._amdDependencies === undefined) {
|
||||
this.cacheSyntaxTreeInfo();
|
||||
Debug.assert(this._amdDependencies !== undefined);
|
||||
}
|
||||
|
||||
return this._amdDependencies;
|
||||
}
|
||||
}
|
||||
|
||||
class GrammarCheckerWalker extends SyntaxWalker {
|
||||
@ -1033,6 +989,15 @@ module TypeScript {
|
||||
super.visitExportAssignment(node);
|
||||
}
|
||||
|
||||
public visitExternalModuleReference(node: ExternalModuleReferenceSyntax): void {
|
||||
if (node.expression.kind !== SyntaxKind.StringLiteral) {
|
||||
this.pushDiagnostic(node.expression, DiagnosticCode.String_literal_expected);
|
||||
return;
|
||||
}
|
||||
|
||||
super.visitExternalModuleReference(node);
|
||||
}
|
||||
|
||||
public visitExpressionBody(node: ExpressionBody): void {
|
||||
// These are always errors. So no need to ever recurse on them.
|
||||
this.pushDiagnostic(node.equalsGreaterThanToken, DiagnosticCode._0_expected, ["{"]);
|
||||
@ -1741,16 +1706,6 @@ module TypeScript {
|
||||
return scanner.scan(/*allowContextualToken:*/ false);
|
||||
}
|
||||
|
||||
export function externalModuleIndicatorSpan(syntaxTree: SyntaxTree): TextSpan {
|
||||
var firstToken = firstSyntaxTreeToken(syntaxTree);
|
||||
return externalModuleIndicatorSpanWorker(syntaxTree, firstToken);
|
||||
}
|
||||
|
||||
export function externalModuleIndicatorSpanWorker(syntaxTree: SyntaxTree, firstToken: ISyntaxToken) {
|
||||
var leadingTrivia = firstToken.leadingTrivia(syntaxTree.text);
|
||||
return implicitImportSpan(leadingTrivia) || topLevelImportOrExportSpan(syntaxTree.sourceUnit());
|
||||
}
|
||||
|
||||
function implicitImportSpan(sourceUnitLeadingTrivia: ISyntaxTriviaList): TextSpan {
|
||||
for (var i = 0, n = sourceUnitLeadingTrivia.count(); i < n; i++) {
|
||||
var trivia = sourceUnitLeadingTrivia.syntaxTriviaAt(i);
|
||||
@ -1776,25 +1731,4 @@ module TypeScript {
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function topLevelImportOrExportSpan(node: SourceUnitSyntax): TextSpan {
|
||||
for (var i = 0, n = node.moduleElements.length; i < n; i++) {
|
||||
var moduleElement = node.moduleElements[i];
|
||||
|
||||
var _firstToken = firstToken(moduleElement);
|
||||
if (_firstToken && _firstToken.kind === SyntaxKind.ExportKeyword) {
|
||||
return new TextSpan(start(_firstToken), width(_firstToken));
|
||||
}
|
||||
|
||||
if (moduleElement.kind === SyntaxKind.ImportDeclaration) {
|
||||
var importDecl = <ImportDeclarationSyntax>moduleElement;
|
||||
if (importDecl.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
var literal = (<TypeScript.ExternalModuleReferenceSyntax>importDecl.moduleReference).stringLiteral;
|
||||
return new TextSpan(start(literal), width(literal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@ -627,7 +627,7 @@ module TypeScript {
|
||||
public visitExternalModuleReference(node: ExternalModuleReferenceSyntax): void {
|
||||
this.visitToken(node.requireKeyword);
|
||||
this.visitToken(node.openParenToken);
|
||||
this.visitToken(node.stringLiteral);
|
||||
visitNodeOrToken(this, node.expression);
|
||||
this.visitToken(node.closeParenToken);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user