Merge branch 'master' into invertedIncremental

Conflicts:
	src/services/syntax/parser.ts
This commit is contained in:
Cyrus Najmabadi 2014-12-06 01:30:38 -08:00
commit b25d0a6fbc
14 changed files with 611 additions and 1032 deletions

View File

@ -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.",

View File

@ -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 },

View File

@ -411,6 +411,10 @@
"category": "Error",
"code": 1120
},
"String literal expected.": {
"category": "Error",
"code": 1121
},
"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2000

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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
};
}

View File

@ -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";
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);
}