mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 20:25:48 -06:00
Move 'disallowIn' into being an ambient parser context flag.
This greatly simplifies how we will do incremental parsing.
This commit is contained in:
parent
22e485bee5
commit
f6c1fe710e
@ -850,9 +850,82 @@ module ts {
|
||||
var nodeCount = 0;
|
||||
var lineStarts: number[];
|
||||
|
||||
var strictModeContext = false;
|
||||
var lookAheadMode = LookAheadMode.NotLookingAhead;
|
||||
|
||||
// Flags that dictate what parsing context we're in. For example:
|
||||
// Whether or not we are in strict parsing mode. All that changes in strict parsing mode is
|
||||
// that some tokens that would be considered identifiers may be considered keywords. When
|
||||
// rewinding, we need to store and restore this as the mode may have changed.
|
||||
//
|
||||
// When adding more parser context flags, consider which is the more common case that the
|
||||
// flag will be in. This should be hte 'false' state for that flag. The reason for this is
|
||||
// that we don't store data in our nodes unless the value is in the *non-default* state. So,
|
||||
// for example, more often than code 'allows-in' (or doesn't 'disallow-in'). We opt for
|
||||
// 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost
|
||||
// all nodes would need extra state on them to store this info.
|
||||
//
|
||||
// Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6
|
||||
// grammar specification.
|
||||
//
|
||||
// An important thing about these context concepts. By default they are effectively inherited
|
||||
// while parsing through every grammar production. i.e. if you don't change them, then when
|
||||
// you parse a sub-production, it will have the same context values as hte parent production.
|
||||
// This is great most of the time. After all, consider all the 'expression' grammar productions
|
||||
// and how nearly all of them pass along the 'in' and 'yield' context values:
|
||||
//
|
||||
// EqualityExpression[In, Yield] :
|
||||
// RelationalExpression[?In, ?Yield]
|
||||
// EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield]
|
||||
// EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield]
|
||||
// EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield]
|
||||
// EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield]
|
||||
//
|
||||
// Where you have to be careful is then understanding what the points are in the grammar
|
||||
// where the values are *not* passed along. For example:
|
||||
//
|
||||
// SingleNameBinding[Yield,GeneratorParameter]
|
||||
// [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt
|
||||
// [~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.
|
||||
// production. Conversely, if the GeneratorParameter context flag is not set, then we
|
||||
// should leave the 'yield' context flag alone.
|
||||
//
|
||||
// Getting this all correct is tricky and requires careful reading of the grammar to
|
||||
// understand when these values should be changed versus when they should be inherited.
|
||||
var strictModeContext = false;
|
||||
var disallowInContext = false;
|
||||
|
||||
function allowInAnd<T>(func: () => T): T {
|
||||
if (disallowInContext) {
|
||||
setDisallowInContext(false);
|
||||
var result = func();
|
||||
setDisallowInContext(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
// no need to do anything special if 'in' is already allowed.
|
||||
return func();
|
||||
}
|
||||
|
||||
function disallowInAnd<T>(func: () => T): T {
|
||||
if (disallowInContext) {
|
||||
// no need to do anything special if 'in' is already disallowed.
|
||||
return func();
|
||||
}
|
||||
|
||||
setDisallowInContext(true);
|
||||
var result = func();
|
||||
setDisallowInContext(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
function setDisallowInContext(val: boolean) {
|
||||
disallowInContext = val;
|
||||
}
|
||||
|
||||
function getLineStarts(): number[] {
|
||||
return lineStarts || (lineStarts = computeLineStarts(sourceText));
|
||||
}
|
||||
@ -1036,7 +1109,11 @@ module ts {
|
||||
node.end = scanner.getStartPos();
|
||||
|
||||
if (strictModeContext) {
|
||||
node.flags |= NodeFlags.ParsedInStrictMode;
|
||||
node.flags |= NodeFlags.ParsedInStrictModeContext;
|
||||
}
|
||||
|
||||
if (disallowInContext) {
|
||||
node.flags |= NodeFlags.ParsedInDisallowInContext
|
||||
}
|
||||
|
||||
return node;
|
||||
@ -1361,7 +1438,7 @@ module ts {
|
||||
|
||||
function parseTemplateSpan(): TemplateSpan {
|
||||
var span = <TemplateSpan>createNode(SyntaxKind.TemplateSpan);
|
||||
span.expression = parseExpression(/*noIn*/ false);
|
||||
span.expression = allowInAnd(parseExpression);
|
||||
|
||||
var literal: LiteralExpression;
|
||||
|
||||
@ -1833,15 +1910,19 @@ module ts {
|
||||
return token !== SyntaxKind.OpenBraceToken && token !== SyntaxKind.FunctionKeyword && isStartOfExpression();
|
||||
}
|
||||
|
||||
function parseExpression(noIn?: boolean): Expression {
|
||||
var expr = parseAssignmentExpression(noIn);
|
||||
function parseExpression(): Expression {
|
||||
// Expression[in]:
|
||||
// AssignmentExpression[in]
|
||||
// Expression[in] , AssignmentExpression[in]
|
||||
|
||||
var expr = parseAssignmentExpression();
|
||||
while (parseOptional(SyntaxKind.CommaToken)) {
|
||||
expr = makeBinaryExpression(expr, SyntaxKind.CommaToken, parseAssignmentExpression(noIn));
|
||||
expr = makeBinaryExpression(expr, SyntaxKind.CommaToken, parseAssignmentExpression());
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
function parseInitializer(inParameter: boolean, noIn?: boolean): Expression {
|
||||
function parseInitializer(inParameter: boolean): Expression {
|
||||
if (token !== SyntaxKind.EqualsToken) {
|
||||
// It's not uncommon during typing for the user to miss writing the '=' token. Check if
|
||||
// there is no newline after the last token and if we're on an expression. If so, parse
|
||||
@ -1858,11 +1939,14 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
// Initializer[In, Yield] :
|
||||
// = AssignmentExpression[?In, ?Yield]
|
||||
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
return parseAssignmentExpression(noIn);
|
||||
return parseAssignmentExpression();
|
||||
}
|
||||
|
||||
function parseAssignmentExpression(noIn?: boolean): Expression {
|
||||
function parseAssignmentExpression(): Expression {
|
||||
// Augmented by TypeScript:
|
||||
//
|
||||
// AssignmentExpression[in]:
|
||||
@ -1885,7 +1969,7 @@ module ts {
|
||||
|
||||
// Now try to handle the rest of the cases. First, see if we can parse out up to and
|
||||
// including a conditional expression.
|
||||
var expr = parseConditionalExpression(noIn);
|
||||
var expr = parseConditionalExpression();
|
||||
|
||||
// To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized
|
||||
// parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
|
||||
@ -1900,7 +1984,7 @@ module ts {
|
||||
if (isLeftHandSideExpression(expr) && isAssignmentOperator(token)) {
|
||||
var operator = token;
|
||||
nextToken();
|
||||
return makeBinaryExpression(expr, operator, parseAssignmentExpression(noIn));
|
||||
return makeBinaryExpression(expr, operator, parseAssignmentExpression());
|
||||
}
|
||||
|
||||
// otherwise this was production '1'. Return whatever we parsed so far.
|
||||
@ -1922,7 +2006,7 @@ module ts {
|
||||
|
||||
var signature = <ParsedSignature> { parameters: parameters };
|
||||
|
||||
return parseArrowExpressionTail(identifier.pos, signature, /*noIn:*/ false);
|
||||
return parseArrowExpressionTail(identifier.pos, signature);
|
||||
}
|
||||
|
||||
function tryParseParenthesizedArrowFunctionExpression(): Expression {
|
||||
@ -1941,7 +2025,7 @@ module ts {
|
||||
// If we have an arrow, then try to parse the body.
|
||||
// Even if not, try to parse if we have an opening brace, just in case we're in an error state.
|
||||
if (parseExpected(SyntaxKind.EqualsGreaterThanToken) || token === SyntaxKind.OpenBraceToken) {
|
||||
return parseArrowExpressionTail(pos, sig, /* noIn: */ false);
|
||||
return parseArrowExpressionTail(pos, sig);
|
||||
}
|
||||
else {
|
||||
// If not, we're probably better off bailing out and returning a bogus function expression.
|
||||
@ -1954,7 +2038,7 @@ module ts {
|
||||
var sig = tryParseSignatureIfArrowOrBraceFollows();
|
||||
if (sig) {
|
||||
parseExpected(SyntaxKind.EqualsGreaterThanToken);
|
||||
return parseArrowExpressionTail(pos, sig, /*noIn:*/ false);
|
||||
return parseArrowExpressionTail(pos, sig);
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
@ -2057,7 +2141,7 @@ module ts {
|
||||
});
|
||||
}
|
||||
|
||||
function parseArrowExpressionTail(pos: number, sig: ParsedSignature, noIn: boolean): FunctionExpression {
|
||||
function parseArrowExpressionTail(pos: number, sig: ParsedSignature): FunctionExpression {
|
||||
var body: Node;
|
||||
|
||||
if (token === SyntaxKind.OpenBraceToken) {
|
||||
@ -2081,37 +2165,36 @@ module ts {
|
||||
body = parseFunctionBlock(/* ignoreMissingOpenBrace */ true);
|
||||
}
|
||||
else {
|
||||
body = parseAssignmentExpression(noIn);
|
||||
body = parseAssignmentExpression();
|
||||
}
|
||||
|
||||
return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /* name */ undefined, sig, body);
|
||||
}
|
||||
|
||||
function parseConditionalExpression(noIn?: boolean): Expression {
|
||||
var expr = parseBinaryExpression(noIn);
|
||||
function parseConditionalExpression(): Expression {
|
||||
// Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
|
||||
// we do not that for the 'whenFalse' part.
|
||||
|
||||
var expr = parseBinaryOperators(parseUnaryExpression(), /*minPrecedence:*/ 0);
|
||||
while (parseOptional(SyntaxKind.QuestionToken)) {
|
||||
var node = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression, expr.pos);
|
||||
node.condition = expr;
|
||||
node.whenTrue = parseAssignmentExpression(false);
|
||||
node.whenTrue = allowInAnd(parseAssignmentExpression);
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
node.whenFalse = parseAssignmentExpression(noIn);
|
||||
node.whenFalse = parseAssignmentExpression();
|
||||
expr = finishNode(node);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
function parseBinaryExpression(noIn?: boolean): Expression {
|
||||
return parseBinaryOperators(parseUnaryExpression(), 0, noIn);
|
||||
}
|
||||
|
||||
function parseBinaryOperators(expr: Expression, minPrecedence: number, noIn?: boolean): Expression {
|
||||
function parseBinaryOperators(expr: Expression, minPrecedence: number): Expression {
|
||||
while (true) {
|
||||
reScanGreaterToken();
|
||||
var precedence = getOperatorPrecedence();
|
||||
if (precedence && precedence > minPrecedence && (!noIn || token !== SyntaxKind.InKeyword)) {
|
||||
if (precedence && precedence > minPrecedence && (!disallowInContext || token !== SyntaxKind.InKeyword)) {
|
||||
var operator = token;
|
||||
nextToken();
|
||||
expr = makeBinaryExpression(expr, operator, parseBinaryOperators(parseUnaryExpression(), precedence, noIn));
|
||||
expr = makeBinaryExpression(expr, operator, parseBinaryOperators(parseUnaryExpression(), precedence));
|
||||
continue;
|
||||
}
|
||||
return expr;
|
||||
@ -2277,7 +2360,7 @@ module ts {
|
||||
indexedAccess.index = createMissingNode();
|
||||
}
|
||||
else {
|
||||
indexedAccess.index = parseExpression();
|
||||
indexedAccess.index = allowInAnd(parseExpression);
|
||||
if (indexedAccess.index.kind === SyntaxKind.StringLiteral || indexedAccess.index.kind === SyntaxKind.NumericLiteral) {
|
||||
var literal = <LiteralExpression>indexedAccess.index;
|
||||
literal.text = internIdentifier(literal.text);
|
||||
@ -2391,7 +2474,7 @@ module ts {
|
||||
function parseParenExpression(): ParenExpression {
|
||||
var node = <ParenExpression>createNode(SyntaxKind.ParenExpression);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
@ -2407,7 +2490,7 @@ module ts {
|
||||
}
|
||||
|
||||
function parseArgumentExpression(): Expression {
|
||||
return parseAssignmentExpressionOrOmittedExpression();
|
||||
return allowInAnd(parseAssignmentExpressionOrOmittedExpression);
|
||||
}
|
||||
|
||||
function parseArrayLiteral(): ArrayLiteral {
|
||||
@ -2456,7 +2539,7 @@ module ts {
|
||||
node = <PropertyDeclaration>createNode(SyntaxKind.PropertyAssignment, nodePos);
|
||||
node.name = propertyName;
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
(<PropertyDeclaration>node).initializer = parseAssignmentExpression(false);
|
||||
(<PropertyDeclaration>node).initializer = allowInAnd(parseAssignmentExpression);
|
||||
}
|
||||
|
||||
node.flags = flags;
|
||||
@ -2545,7 +2628,7 @@ module ts {
|
||||
var node = <IfStatement>createNode(SyntaxKind.IfStatement);
|
||||
parseExpected(SyntaxKind.IfKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
node.thenStatement = parseStatement();
|
||||
node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined;
|
||||
@ -2560,7 +2643,7 @@ module ts {
|
||||
|
||||
parseExpected(SyntaxKind.WhileKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
|
||||
// From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
|
||||
@ -2575,7 +2658,7 @@ module ts {
|
||||
var node = <WhileStatement>createNode(SyntaxKind.WhileStatement);
|
||||
parseExpected(SyntaxKind.WhileKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
|
||||
node.statement = parseStatement();
|
||||
@ -2589,16 +2672,16 @@ module ts {
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
if (token !== SyntaxKind.SemicolonToken) {
|
||||
if (parseOptional(SyntaxKind.VarKeyword)) {
|
||||
var declarations = parseVariableDeclarationList(0, /*noIn*/ true);
|
||||
var declarations = disallowInAnd(() => parseVariableDeclarationList(0));
|
||||
}
|
||||
else if (parseOptional(SyntaxKind.LetKeyword)) {
|
||||
var declarations = parseVariableDeclarationList(NodeFlags.Let, /*noIn*/ true);
|
||||
var declarations = disallowInAnd(() => parseVariableDeclarationList(NodeFlags.Let));
|
||||
}
|
||||
else if (parseOptional(SyntaxKind.ConstKeyword)) {
|
||||
var declarations = parseVariableDeclarationList(NodeFlags.Const, /*noIn*/ true);
|
||||
var declarations = disallowInAnd(() => parseVariableDeclarationList(NodeFlags.Const));
|
||||
}
|
||||
else {
|
||||
var varOrInit = parseExpression(true);
|
||||
var varOrInit = disallowInAnd(parseExpression);
|
||||
}
|
||||
}
|
||||
var forOrForInStatement: IterationStatement;
|
||||
@ -2610,7 +2693,7 @@ module ts {
|
||||
else {
|
||||
forInStatement.variable = varOrInit;
|
||||
}
|
||||
forInStatement.expression = parseExpression();
|
||||
forInStatement.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
forOrForInStatement = forInStatement;
|
||||
}
|
||||
@ -2625,11 +2708,11 @@ module ts {
|
||||
|
||||
parseExpected(SyntaxKind.SemicolonToken);
|
||||
if (token !== SyntaxKind.SemicolonToken && token !== SyntaxKind.CloseParenToken) {
|
||||
forStatement.condition = parseExpression();
|
||||
forStatement.condition = allowInAnd(parseExpression);
|
||||
}
|
||||
parseExpected(SyntaxKind.SemicolonToken);
|
||||
if (token !== SyntaxKind.CloseParenToken) {
|
||||
forStatement.iterator = parseExpression();
|
||||
forStatement.iterator = allowInAnd(parseExpression);
|
||||
}
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
forOrForInStatement = forStatement;
|
||||
@ -2657,7 +2740,7 @@ module ts {
|
||||
|
||||
parseExpected(SyntaxKind.ReturnKeyword);
|
||||
if (!canParseSemicolon()) {
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
}
|
||||
|
||||
parseSemicolon();
|
||||
@ -2668,7 +2751,7 @@ module ts {
|
||||
var node = <WithStatement>createNode(SyntaxKind.WithStatement);
|
||||
parseExpected(SyntaxKind.WithKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
node.statement = parseStatement();
|
||||
return finishNode(node);
|
||||
@ -2677,7 +2760,7 @@ module ts {
|
||||
function parseCaseClause(): CaseOrDefaultClause {
|
||||
var node = <CaseOrDefaultClause>createNode(SyntaxKind.CaseClause);
|
||||
parseExpected(SyntaxKind.CaseKeyword);
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement);
|
||||
return finishNode(node);
|
||||
@ -2699,7 +2782,7 @@ module ts {
|
||||
var node = <SwitchStatement>createNode(SyntaxKind.SwitchStatement);
|
||||
parseExpected(SyntaxKind.SwitchKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
|
||||
@ -2715,7 +2798,7 @@ module ts {
|
||||
if (scanner.hasPrecedingLineBreak()) {
|
||||
error(Diagnostics.Line_break_not_permitted_here);
|
||||
}
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
}
|
||||
@ -2782,7 +2865,7 @@ module ts {
|
||||
|
||||
function parseExpressionStatement(): ExpressionStatement {
|
||||
var node = <ExpressionStatement>createNode(SyntaxKind.ExpressionStatement);
|
||||
node.expression = parseExpression();
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
}
|
||||
@ -2911,17 +2994,17 @@ module ts {
|
||||
|
||||
// DECLARATIONS
|
||||
|
||||
function parseVariableDeclaration(flags: NodeFlags, noIn?: boolean): VariableDeclaration {
|
||||
function parseVariableDeclaration(flags: NodeFlags): VariableDeclaration {
|
||||
var node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration);
|
||||
node.flags = flags;
|
||||
node.name = parseIdentifier();
|
||||
node.type = parseTypeAnnotation();
|
||||
node.initializer = parseInitializer(/*inParameter*/ false, noIn);
|
||||
node.initializer = parseInitializer(/*inParameter*/ false);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseVariableDeclarationList(flags: NodeFlags, noIn?: boolean): NodeArray<VariableDeclaration> {
|
||||
return parseDelimitedList(ParsingContext.VariableDeclarations, () => parseVariableDeclaration(flags, noIn));
|
||||
function parseVariableDeclarationList(flags: NodeFlags): NodeArray<VariableDeclaration> {
|
||||
return parseDelimitedList(ParsingContext.VariableDeclarations, () => parseVariableDeclaration(flags));
|
||||
}
|
||||
|
||||
function parseVariableStatement(fullStart: number, modifiers: ModifiersArray): VariableStatement {
|
||||
@ -2939,7 +3022,7 @@ module ts {
|
||||
}
|
||||
|
||||
nextToken();
|
||||
node.declarations = parseVariableDeclarationList(node.flags, /*noIn*/false);
|
||||
node.declarations = allowInAnd(() => parseVariableDeclarationList(node.flags));
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
}
|
||||
@ -2991,7 +3074,7 @@ module ts {
|
||||
}
|
||||
property.name = name;
|
||||
property.type = parseTypeAnnotation();
|
||||
property.initializer = parseInitializer(/*inParameter*/ false);
|
||||
property.initializer = allowInAnd(() => parseInitializer(/*inParameter*/ false));
|
||||
parseSemicolon();
|
||||
return finishNode(property);
|
||||
}
|
||||
@ -3156,7 +3239,7 @@ module ts {
|
||||
function parseEnumMember(): EnumMember {
|
||||
var node = <EnumMember>createNode(SyntaxKind.EnumMember, scanner.getStartPos());
|
||||
node.name = parsePropertyName();
|
||||
node.initializer = parseInitializer(/*inParameter*/ false);
|
||||
node.initializer = allowInAnd(() => parseInitializer(/*inParameter*/ false));
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@ -3658,7 +3741,7 @@ module ts {
|
||||
}
|
||||
|
||||
function checkBinaryExpression(node: BinaryExpression) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictMode) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictModeContext) {
|
||||
if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operator)) {
|
||||
if (isEvalOrArgumentsIdentifier(node.left)) {
|
||||
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
|
||||
@ -3810,7 +3893,7 @@ module ts {
|
||||
var colonStart = skipTrivia(sourceText, node.variable.end);
|
||||
return grammarErrorAtPos(colonStart, ":".length, Diagnostics.Catch_clause_parameter_cannot_have_a_type_annotation);
|
||||
}
|
||||
if (node.flags & NodeFlags.ParsedInStrictMode && isEvalOrArgumentsIdentifier(node.variable)) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictModeContext && isEvalOrArgumentsIdentifier(node.variable)) {
|
||||
// It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
|
||||
// Catch production is eval or arguments
|
||||
return reportInvalidUseInStrictMode(node.variable);
|
||||
@ -3930,7 +4013,7 @@ module ts {
|
||||
}
|
||||
|
||||
function checkFunctionName(name: Node) {
|
||||
if (name && name.flags & NodeFlags.ParsedInStrictMode && isEvalOrArgumentsIdentifier(name)) {
|
||||
if (name && name.flags & NodeFlags.ParsedInStrictModeContext && isEvalOrArgumentsIdentifier(name)) {
|
||||
// It is a SyntaxError to use within strict mode code the identifiers eval or arguments as the
|
||||
// Identifier of a FunctionLikeDeclaration or FunctionExpression or as a formal parameter name(13.1)
|
||||
return reportInvalidUseInStrictMode(<Identifier>name);
|
||||
@ -4051,7 +4134,7 @@ module ts {
|
||||
var GetAccessor = 2;
|
||||
var SetAccesor = 4;
|
||||
var GetOrSetAccessor = GetAccessor | SetAccesor;
|
||||
var inStrictMode = (node.flags & NodeFlags.ParsedInStrictMode) !== 0;
|
||||
var inStrictMode = (node.flags & NodeFlags.ParsedInStrictModeContext) !== 0;
|
||||
|
||||
for (var i = 0, n = node.properties.length; i < n; i++) {
|
||||
var prop = node.properties[i];
|
||||
@ -4115,7 +4198,7 @@ module ts {
|
||||
|
||||
function checkNumericLiteral(node: LiteralExpression): boolean {
|
||||
if (node.flags & NodeFlags.OctalLiteral) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictMode) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictModeContext) {
|
||||
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode);
|
||||
}
|
||||
else if (languageVersion >= ScriptTarget.ES5) {
|
||||
@ -4259,7 +4342,7 @@ module ts {
|
||||
// or if its FunctionBody is strict code(11.1.5).
|
||||
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
|
||||
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
|
||||
if (node.flags & NodeFlags.ParsedInStrictMode && isEvalOrArgumentsIdentifier(node.name)) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictModeContext && isEvalOrArgumentsIdentifier(node.name)) {
|
||||
return reportInvalidUseInStrictMode(node.name);
|
||||
}
|
||||
}
|
||||
@ -4318,13 +4401,13 @@ module ts {
|
||||
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
|
||||
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
|
||||
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
|
||||
if (node.flags & NodeFlags.ParsedInStrictMode && isEvalOrArgumentsIdentifier(node.operand)) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictModeContext && isEvalOrArgumentsIdentifier(node.operand)) {
|
||||
return reportInvalidUseInStrictMode(<Identifier>node.operand);
|
||||
}
|
||||
}
|
||||
|
||||
function checkPrefixOperator(node: UnaryExpression) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictMode) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictModeContext) {
|
||||
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
|
||||
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
|
||||
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator
|
||||
@ -4509,7 +4592,7 @@ module ts {
|
||||
if (!inAmbientContext && !node.initializer && isConst(node)) {
|
||||
return grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized);
|
||||
}
|
||||
if (node.flags & NodeFlags.ParsedInStrictMode && isEvalOrArgumentsIdentifier(node.name)) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictModeContext && isEvalOrArgumentsIdentifier(node.name)) {
|
||||
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
|
||||
// and its Identifier is eval or arguments
|
||||
return reportInvalidUseInStrictMode(node.name);
|
||||
@ -4571,7 +4654,7 @@ module ts {
|
||||
}
|
||||
|
||||
function checkWithStatement(node: WithStatement): boolean {
|
||||
if (node.flags & NodeFlags.ParsedInStrictMode) {
|
||||
if (node.flags & NodeFlags.ParsedInStrictModeContext) {
|
||||
// Strict mode code may not include a WithStatement. The occurrence of a WithStatement in such
|
||||
// a context is an
|
||||
return grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode);
|
||||
|
||||
@ -272,8 +272,10 @@ module ts {
|
||||
|
||||
// Set if this node was parsed in strict mode. Used for grammar error checks, as well as
|
||||
// checking if the node can be reused in incremental settings.
|
||||
ParsedInStrictMode = 0x00002000,
|
||||
OctalLiteral = 0x00004000,
|
||||
ParsedInStrictModeContext = 0x00002000,
|
||||
ParsedInDisallowInContext = 0x00004000,
|
||||
|
||||
OctalLiteral = 0x00008000,
|
||||
|
||||
Modifier = Export | Ambient | Public | Private | Protected | Static,
|
||||
AccessibilityModifier = Public | Private | Protected,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user