diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 213661fdd60..a87b1f8cc28 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -124,7 +124,7 @@ module ts { Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: DiagnosticCategory.Error, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." }, Unterminated_template_literal: { code: 1160, category: DiagnosticCategory.Error, key: "Unterminated template literal." }, Unterminated_regular_expression_literal: { code: 1161, category: DiagnosticCategory.Error, key: "Unterminated regular expression literal." }, - A_object_member_cannot_be_declared_optional: { code: 1160, category: DiagnosticCategory.Error, key: "A object member cannot be declared optional." }, + An_object_member_cannot_be_declared_optional: { code: 1160, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cd2e209e3eb..c05770bdd8e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -479,18 +479,17 @@ "category": "Error", "code": 1159 }, - "Unterminated template literal.": { + "An object member cannot be declared optional.": { "category": "Error", - "code": 1160 + "code": 1160 }, - "Unterminated regular expression literal.": { + "Unterminated template literal.": { "category": "Error", "code": 1161 }, - - "A object member cannot be declared optional.": { + "Unterminated regular expression literal.": { "category": "Error", - "code": 1160 + "code": 1162 }, "Duplicate identifier '{0}'.": { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6a25699f0b9..5818929d6e8 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2264,7 +2264,6 @@ module ts { } if (parseOptional(SyntaxKind.OpenBracketToken)) { - var indexedAccess = createNode(SyntaxKind.IndexedAccess, expr.pos); indexedAccess.object = expr; @@ -2441,10 +2440,12 @@ module ts { (node).initializer = makeFunctionExpression(SyntaxKind.FunctionExpression, node.pos, undefined, sig, body); return finishNode(node); } - // Disallow optional property assignment + + var flags: NodeFlags = 0; + + // Disallowing of optional property assignments happens in the grammar checker. if (token === SyntaxKind.QuestionToken) { - var questionStart = scanner.getTokenPos(); - grammarErrorAtPos(questionStart, scanner.getStartPos() - questionStart, Diagnostics.A_object_member_cannot_be_declared_optional); + flags |= NodeFlags.QuestionMark; nextToken(); } @@ -2459,6 +2460,8 @@ module ts { parseExpected(SyntaxKind.ColonToken); (node).initializer = parseAssignmentExpression(false); } + + node.flags = flags; return finishNode(node); } @@ -3740,42 +3743,44 @@ module ts { function dispatch(node: Node) { switch (node.kind) { - case SyntaxKind.ArrowFunction: return visitArrowFunction(node); - case SyntaxKind.BinaryExpression: return visitBinaryExpression(node); - case SyntaxKind.BreakStatement: return visitBreakOrContinueStatement(node); - case SyntaxKind.CallExpression: return visitCallExpression(node); - case SyntaxKind.CallSignature: return visitCallSignature(node); - case SyntaxKind.CatchBlock: return visitCatchBlock(node); - case SyntaxKind.ClassDeclaration: return visitClassDeclaration(node); - case SyntaxKind.Constructor: return visitConstructor(node); - case SyntaxKind.ConstructorType: return visitConstructorType(node); - case SyntaxKind.ConstructSignature: return visitConstructSignature(node); - case SyntaxKind.ContinueStatement: return visitBreakOrContinueStatement(node); - case SyntaxKind.EnumDeclaration: return visitEnumDeclaration(node); - case SyntaxKind.ForInStatement: return visitForInStatement(node); - case SyntaxKind.ForStatement: return visitForStatement(node); - case SyntaxKind.FunctionDeclaration: return visitFunctionDeclaration(node); - case SyntaxKind.FunctionExpression: return visitFunctionExpression(node); - case SyntaxKind.FunctionType: return visitFunctionType(node); - case SyntaxKind.GetAccessor: return visitGetAccessor(node); - case SyntaxKind.IndexSignature: return visitIndexSignature(node); - case SyntaxKind.InterfaceDeclaration: return visitInterfaceDeclaration(node); - case SyntaxKind.LabeledStatement: return visitLabeledStatement(node); - case SyntaxKind.Method: return visitMethod(node); - case SyntaxKind.ModuleDeclaration: return visitModuleDeclaration(node); - case SyntaxKind.NewExpression: return visitNewExpression(node); - case SyntaxKind.ObjectLiteral: return visitObjectLiteral(node); - case SyntaxKind.Parameter: return visitParameter(node); - case SyntaxKind.PostfixOperator: return visitPostfixOperator(node); - case SyntaxKind.PrefixOperator: return visitPrefixOperator(node); - case SyntaxKind.SetAccessor: return visitSetAccessor(node); - case SyntaxKind.SwitchStatement: return visitSwitchStatement(node); - case SyntaxKind.TaggedTemplateExpression: return visitTaggedTemplateExpression(node); - case SyntaxKind.TupleType: return visitTupleType(node); - case SyntaxKind.TypeReference: return visitTypeReference(node); - case SyntaxKind.VariableDeclaration: return visitVariableDeclaration(node); - case SyntaxKind.VariableStatement: return visitVariableStatement(node); - case SyntaxKind.WithStatement: return visitWithStatement(node); + case SyntaxKind.ArrowFunction: return visitArrowFunction(node); + case SyntaxKind.BinaryExpression: return visitBinaryExpression(node); + case SyntaxKind.BreakStatement: return visitBreakOrContinueStatement(node); + case SyntaxKind.CallExpression: return visitCallExpression(node); + case SyntaxKind.CallSignature: return visitCallSignature(node); + case SyntaxKind.CatchBlock: return visitCatchBlock(node); + case SyntaxKind.ClassDeclaration: return visitClassDeclaration(node); + case SyntaxKind.Constructor: return visitConstructor(node); + case SyntaxKind.ConstructorType: return visitConstructorType(node); + case SyntaxKind.ConstructSignature: return visitConstructSignature(node); + case SyntaxKind.ContinueStatement: return visitBreakOrContinueStatement(node); + case SyntaxKind.EnumDeclaration: return visitEnumDeclaration(node); + case SyntaxKind.ForInStatement: return visitForInStatement(node); + case SyntaxKind.ForStatement: return visitForStatement(node); + case SyntaxKind.FunctionDeclaration: return visitFunctionDeclaration(node); + case SyntaxKind.FunctionExpression: return visitFunctionExpression(node); + case SyntaxKind.FunctionType: return visitFunctionType(node); + case SyntaxKind.GetAccessor: return visitGetAccessor(node); + case SyntaxKind.IndexSignature: return visitIndexSignature(node); + case SyntaxKind.InterfaceDeclaration: return visitInterfaceDeclaration(node); + case SyntaxKind.LabeledStatement: return visitLabeledStatement(node); + case SyntaxKind.Method: return visitMethod(node); + case SyntaxKind.ModuleDeclaration: return visitModuleDeclaration(node); + case SyntaxKind.NewExpression: return visitNewExpression(node); + case SyntaxKind.ObjectLiteral: return visitObjectLiteral(node); + case SyntaxKind.Parameter: return visitParameter(node); + case SyntaxKind.PostfixOperator: return visitPostfixOperator(node); + case SyntaxKind.PrefixOperator: return visitPrefixOperator(node); + case SyntaxKind.PropertyAssignment: return visitPropertyAssignment(node); + case SyntaxKind.SetAccessor: return visitSetAccessor(node); + case SyntaxKind.ShorthandPropertyAssignment: return visitShorthandPropertyAssignment(node); + case SyntaxKind.SwitchStatement: return visitSwitchStatement(node); + case SyntaxKind.TaggedTemplateExpression: return visitTaggedTemplateExpression(node); + case SyntaxKind.TupleType: return visitTupleType(node); + case SyntaxKind.TypeReference: return visitTypeReference(node); + case SyntaxKind.VariableDeclaration: return visitVariableDeclaration(node); + case SyntaxKind.VariableStatement: return visitVariableStatement(node); + case SyntaxKind.WithStatement: return visitWithStatement(node); } } @@ -4346,6 +4351,17 @@ module ts { } } + function visitPropertyAssignment(node: PropertyDeclaration) { + checkForInvalidQuestionMark(node, Diagnostics.An_object_member_cannot_be_declared_optional); + } + + function checkForInvalidQuestionMark(node: Declaration, message: DiagnosticMessage) { + if (node.flags & NodeFlags.QuestionMark) { + var pos = skipTrivia(sourceText, node.name.end); + return grammarErrorAtPos(pos, "?".length, message); + } + } + function visitSetAccessor(node: MethodDeclaration) { checkTypeParameterList(node.typeParameters) || checkParameterList(node.parameters) || @@ -4391,6 +4407,10 @@ module ts { } } + function visitShorthandPropertyAssignment(node: ShortHandPropertyDeclaration): void { + checkForInvalidQuestionMark(node, Diagnostics.An_object_member_cannot_be_declared_optional); + } + function visitSwitchStatement(node: SwitchStatement) { var firstDefaultClause: CaseOrDefaultClause; diff --git a/tests/baselines/reference/objectTypeWithOptionalProperty1.errors.txt b/tests/baselines/reference/objectTypeWithOptionalProperty1.errors.txt new file mode 100644 index 00000000000..7e17563873a --- /dev/null +++ b/tests/baselines/reference/objectTypeWithOptionalProperty1.errors.txt @@ -0,0 +1,9 @@ +tests/cases/compiler/objectTypeWithOptionalProperty1.ts(2,10): error TS1160: An object member cannot be declared optional. + + +==== tests/cases/compiler/objectTypeWithOptionalProperty1.ts (1 errors) ==== + var b = { + x?: 1 // error + ~ +!!! error TS1160: An object member cannot be declared optional. + } \ No newline at end of file diff --git a/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt b/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt index e73e8adc930..669fbfb595b 100644 --- a/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt +++ b/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(12,6): error TS1112: A class member cannot be declared optional. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(20,6): error TS1112: A class member cannot be declared optional. -tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(24,6): error TS1160: A object member cannot be declared optional. -==== tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts (3 errors) ==== +==== tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts (2 errors) ==== // Basic uses of optional properties var a: { @@ -32,6 +31,4 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWith var b = { x?: 1 // error - -!!! error TS1160: A object member cannot be declared optional. } \ No newline at end of file diff --git a/tests/cases/compiler/objectTypeWithOptionalProperty1.ts b/tests/cases/compiler/objectTypeWithOptionalProperty1.ts new file mode 100644 index 00000000000..69f6e1f51ec --- /dev/null +++ b/tests/cases/compiler/objectTypeWithOptionalProperty1.ts @@ -0,0 +1,3 @@ + var b = { + x?: 1 // error + } \ No newline at end of file