diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a0fd0b243d6..469a794d13d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -135,6 +135,7 @@ module ts { if (node.name) { node.name.parent = node; } + // Report errors every position with duplicate declaration // Report errors on previous encountered declarations var message = symbol.flags & SymbolFlags.BlockScopedVariable diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 040b95f3532..cefbc3105ec 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -338,7 +338,6 @@ module ts { // the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with // the given name can be found. function resolveName(location: Node, name: string, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage, nameArg: string | Identifier): Symbol { - var result: Symbol; var lastLocation: Node; var propertyWithInvalidInitializer: Node; @@ -467,9 +466,9 @@ module ts { if (!links.target) { links.target = resolvingSymbol; var node = getDeclarationOfKind(symbol, SyntaxKind.ImportDeclaration); - var target = node.externalModuleName ? - resolveExternalModuleName(node, node.externalModuleName) : - getSymbolOfPartOfRightHandSideOfImport(node.entityName, node); + var target = node.moduleReference.kind === SyntaxKind.ExternalModuleReference + ? resolveExternalModuleName(node, getExternalModuleImportDeclarationExpression(node)) + : getSymbolOfPartOfRightHandSideOfImport(node.moduleReference, node); if (links.target === resolvingSymbol) { links.target = target || unknownSymbol; } @@ -516,26 +515,27 @@ module ts { // Resolves a qualified name and any involved import aliases function resolveEntityName(location: Node, name: EntityName, meaning: SymbolFlags): Symbol { + if (getFullWidth(name) === 0) { + return undefined; + } + if (name.kind === SyntaxKind.Identifier) { - var symbol = resolveName(location, (name).text, meaning, Diagnostics.Cannot_find_name_0, name); + var symbol = resolveName(location,(name).text, meaning, Diagnostics.Cannot_find_name_0, name); if (!symbol) { return; } } else if (name.kind === SyntaxKind.QualifiedName) { - var namespace = resolveEntityName(location, (name).left, SymbolFlags.Namespace); - if (!namespace || namespace === unknownSymbol || (name).right.kind === SyntaxKind.Missing) return; - var symbol = getSymbol(namespace.exports, (name).right.text, meaning); + var namespace = resolveEntityName(location,(name).left, SymbolFlags.Namespace); + if (!namespace || namespace === unknownSymbol || getFullWidth((name).right) === 0) return; + var symbol = getSymbol(namespace.exports,(name).right.text, meaning); if (!symbol) { error(location, Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(namespace), declarationNameToString((name).right)); return; } } - else { - // Missing identifier - return; - } + Debug.assert((symbol.flags & SymbolFlags.Instantiated) === 0, "Should never get an instantiated symbol here."); return symbol.flags & meaning ? symbol : resolveImport(symbol); } @@ -546,7 +546,12 @@ module ts { return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\"; } - function resolveExternalModuleName(location: Node, moduleLiteral: LiteralExpression): Symbol { + function resolveExternalModuleName(location: Node, moduleExpression: Expression): Symbol { + if (moduleExpression.kind !== SyntaxKind.StringLiteral) { + return; + } + + var moduleLiteral = moduleExpression; var searchPath = getDirectoryPath(getSourceFile(location).filename); var moduleName = moduleLiteral.text; if (!moduleName) return; @@ -824,8 +829,8 @@ module ts { if (symbolFromSymbolTable.flags & SymbolFlags.Import) { if (!useOnlyExternalAliasing || // We can use any type of alias to get the name // Is this external alias, then use it to name - ts.forEach(symbolFromSymbolTable.declarations, declaration => - declaration.kind === SyntaxKind.ImportDeclaration && (declaration).externalModuleName)) { + ts.forEach(symbolFromSymbolTable.declarations, isExternalModuleImportDeclaration)) { + var resolvedImportedSymbol = resolveImport(symbolFromSymbolTable); if (isAccessible(symbolFromSymbolTable, resolveImport(symbolFromSymbolTable))) { return [symbolFromSymbolTable]; @@ -4261,7 +4266,7 @@ module ts { function getResolvedSymbol(node: Identifier): Symbol { var links = getNodeLinks(node); if (!links.resolvedSymbol) { - links.resolvedSymbol = resolveName(node, node.text, SymbolFlags.Value | SymbolFlags.ExportValue, Diagnostics.Cannot_find_name_0, node) || unknownSymbol; + links.resolvedSymbol = (getFullWidth(node) > 0 && resolveName(node, node.text, SymbolFlags.Value | SymbolFlags.ExportValue, Diagnostics.Cannot_find_name_0, node)) || unknownSymbol; } return links.resolvedSymbol; } @@ -5251,11 +5256,13 @@ module ts { function checkIndexedAccess(node: ElementAccessExpression): Type { // Obtain base constraint such that we can bail out if the constraint is an unknown type var objectType = getApparentType(checkExpression(node.expression)); - var indexType = checkExpression(node.argumentExpression); + var indexType = node.argumentExpression ? checkExpression(node.argumentExpression) : unknownType; - if (objectType === unknownType) return unknownType; + if (objectType === unknownType) { + return unknownType; + } - if (isConstEnumObjectType(objectType) && node.argumentExpression.kind !== SyntaxKind.StringLiteral) { + if (isConstEnumObjectType(objectType) && node.argumentExpression && node.argumentExpression.kind !== SyntaxKind.StringLiteral) { error(node.argumentExpression, Diagnostics.Index_expression_arguments_in_const_enums_must_be_of_type_string); } @@ -5269,12 +5276,14 @@ module ts { // - Otherwise, if IndexExpr is of type Any, the String or Number primitive type, or an enum type, the property access is of type Any. // See if we can index as a property. - if (node.argumentExpression.kind === SyntaxKind.StringLiteral || node.argumentExpression.kind === SyntaxKind.NumericLiteral) { - var name = (node.argumentExpression).text; - var prop = getPropertyOfType(objectType, name); - if (prop) { - getNodeLinks(node).resolvedSymbol = prop; - return getTypeOfSymbol(prop); + if (node.argumentExpression) { + if (node.argumentExpression.kind === SyntaxKind.StringLiteral || node.argumentExpression.kind === SyntaxKind.NumericLiteral) { + var name = (node.argumentExpression).text; + var prop = getPropertyOfType(objectType, name); + if (prop) { + getNodeLinks(node).resolvedSymbol = prop; + return getTypeOfSymbol(prop); + } } } @@ -5345,7 +5354,7 @@ module ts { var templateExpression = tagExpression.template; var lastSpan = lastOrUndefined(templateExpression.templateSpans); Debug.assert(lastSpan !== undefined); // we should always have at least one span. - callIsIncomplete = lastSpan.literal.kind === SyntaxKind.Missing || !!lastSpan.literal.isUnterminated; + callIsIncomplete = getFullWidth(lastSpan.literal) === 0 || !!lastSpan.literal.isUnterminated; } else { // If the template didn't end in a backtick, or its beginning occurred right prior to EOF, @@ -6230,7 +6239,8 @@ module ts { case SyntaxKind.ElementAccessExpression: var index = (n).argumentExpression; var symbol = findSymbol((n).expression); - if (symbol && index.kind === SyntaxKind.StringLiteral) { + + if (symbol && index && index.kind === SyntaxKind.StringLiteral) { var name = (index).text; var prop = getPropertyOfType(getTypeOfSymbol(symbol), name); return prop && (prop.flags & SymbolFlags.Variable) !== 0 && (getDeclarationFlagsFromSymbol(prop) & NodeFlags.Const) !== 0; @@ -7051,7 +7061,7 @@ module ts { var isConstructor = (symbol.flags & SymbolFlags.Constructor) !== 0; function reportImplementationExpectedError(node: FunctionLikeDeclaration): void { - if (node.name && node.name.kind === SyntaxKind.Missing) { + if (node.name && getFullWidth(node.name) === 0) { return; } @@ -8201,7 +8211,8 @@ module ts { } else { if (e.kind === SyntaxKind.ElementAccessExpression) { - if ((e).argumentExpression.kind !== SyntaxKind.StringLiteral) { + if ((e).argumentExpression === undefined || + (e).argumentExpression.kind !== SyntaxKind.StringLiteral) { return undefined; } var enumType = getTypeOfNode((e).expression); @@ -8348,16 +8359,16 @@ module ts { var symbol = getSymbolOfNode(node); var target: Symbol; - if (node.entityName) { + if (isInternalModuleImportDeclaration(node)) { target = resolveImport(symbol); // Import declaration for an internal module if (target !== unknownSymbol) { if (target.flags & SymbolFlags.Value) { // Target is a value symbol, check that it is not hidden by a local declaration with the same name and // ensure it can be evaluated as an expression - var moduleName = getFirstIdentifier(node.entityName); + var moduleName = getFirstIdentifier(node.moduleReference); if (resolveEntityName(node, moduleName, SymbolFlags.Value | SymbolFlags.Namespace).flags & SymbolFlags.Namespace) { - checkExpression(node.entityName); + checkExpression(node.moduleReference); } else { error(moduleName, Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, declarationNameToString(moduleName)); @@ -8378,12 +8389,17 @@ module ts { // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference // other external modules only through top - level external module names. // Relative external module names are not permitted. - if (isExternalModuleNameRelative(node.externalModuleName.text)) { - error(node, Diagnostics.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name); - target = unknownSymbol; + if (getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) { + if (isExternalModuleNameRelative((getExternalModuleImportDeclarationExpression(node)).text)) { + error(node, Diagnostics.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name); + target = unknownSymbol; + } + else { + target = resolveImport(symbol); + } } else { - target = resolveImport(symbol); + target = unknownSymbol; } } else { @@ -8847,7 +8863,7 @@ module ts { } if (node.parent.kind === SyntaxKind.ImportDeclaration) { - return (node.parent).entityName === node; + return (node.parent).moduleReference === node; } if (node.parent.kind === SyntaxKind.ExportAssignment) { return (node.parent).exportName === node; @@ -8883,6 +8899,11 @@ module ts { } if (isExpression(entityName)) { + if (getFullWidth(entityName) === 0) { + // Missing entity name. + return undefined; + } + if (entityName.kind === SyntaxKind.Identifier) { // Include Import in the meaning, this ensures that we do not follow aliases to where they point and instead // return the alias symbol. @@ -8903,10 +8924,6 @@ module ts { } return getNodeLinks(entityName).resolvedSymbol; } - else { - // Missing identifier - return; - } } else if (isTypeReferenceIdentifier(entityName)) { var meaning = entityName.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; @@ -8958,8 +8975,9 @@ module ts { case SyntaxKind.StringLiteral: // External module name in an import declaration - if (node.parent.kind === SyntaxKind.ImportDeclaration && (node.parent).externalModuleName === node) { - var importSymbol = getSymbolOfNode(node.parent); + if (isExternalModuleImportDeclaration(node.parent.parent) && + getExternalModuleImportDeclarationExpression(node.parent.parent) === node) { + var importSymbol = getSymbolOfNode(node.parent.parent); var moduleType = getTypeOfSymbol(importSymbol); return moduleType ? moduleType.symbol : undefined; } @@ -9145,7 +9163,7 @@ module ts { } function isTopLevelValueImportWithEntityName(node: ImportDeclaration): boolean { - if (node.parent.kind !== SyntaxKind.SourceFile || !node.entityName) { + if (node.parent.kind !== SyntaxKind.SourceFile || !isInternalModuleImportDeclaration(node)) { // parent is not source file or it is not reference to internal module return false; } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index c72054af9c7..7377c42b238 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -106,8 +106,7 @@ module ts { Type_argument_expected: { code: 1140, category: DiagnosticCategory.Error, key: "Type argument expected." }, String_literal_expected: { code: 1141, category: DiagnosticCategory.Error, key: "String literal expected." }, Line_break_not_permitted_here: { code: 1142, category: DiagnosticCategory.Error, key: "Line break not permitted here." }, - catch_or_finally_expected: { code: 1143, category: DiagnosticCategory.Error, key: "'catch' or 'finally' expected." }, - Block_or_expected: { code: 1144, category: DiagnosticCategory.Error, key: "Block or ';' expected." }, + or_expected: { code: 1144, category: DiagnosticCategory.Error, key: "'{' or ';' expected." }, Modifiers_not_permitted_on_index_signature_members: { code: 1145, category: DiagnosticCategory.Error, key: "Modifiers not permitted on index signature members." }, Declaration_expected: { code: 1146, category: DiagnosticCategory.Error, key: "Declaration expected." }, Import_declarations_in_an_internal_module_cannot_reference_an_external_module: { code: 1147, category: DiagnosticCategory.Error, key: "Import declarations in an internal module cannot reference an external module." }, @@ -120,7 +119,6 @@ module ts { const_declarations_must_be_initialized: { code: 1155, category: DiagnosticCategory.Error, key: "'const' declarations must be initialized" }, const_declarations_can_only_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "'const' declarations can only be declared inside a block." }, let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations can only be declared inside a block." }, - Invalid_template_literal_expected: { code: 1158, category: DiagnosticCategory.Error, key: "Invalid template literal; expected '}'" }, 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." }, @@ -141,6 +139,7 @@ module ts { Interface_declaration_cannot_have_implements_clause: { code: 1176, category: DiagnosticCategory.Error, key: "Interface declaration cannot have 'implements' clause." }, Binary_digit_expected: { code: 1177, category: DiagnosticCategory.Error, key: "Binary digit expected." }, Octal_digit_expected: { code: 1178, category: DiagnosticCategory.Error, key: "Octal digit expected." }, + Unexpected_token_expected: { code: 1179, category: DiagnosticCategory.Error, key: "Unexpected token. '{' expected." }, 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 21fe84be2c1..f0dba54e1a1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -415,11 +415,7 @@ "category": "Error", "code": 1142 }, - "'catch' or 'finally' expected.": { - "category": "Error", - "code": 1143 - }, - "Block or ';' expected.": { + "'{' or ';' expected.": { "category": "Error", "code": 1144 }, @@ -471,10 +467,6 @@ "category": "Error", "code": 1157 }, - "Invalid template literal; expected '}'": { - "category": "Error", - "code": 1158 - }, "Tagged templates are only available when targeting ECMAScript 6 and higher.": { "category": "Error", "code": 1159 @@ -556,6 +548,11 @@ "category": "Error", "code": 1178 }, + "Unexpected token. '{' expected.": { + "category": "Error", + "code": 1179 + }, + "Duplicate identifier '{0}'.": { "category": "Error", "code": 2300 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index ed2d1a7d6f6..95508687cd4 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -665,13 +665,13 @@ module ts { write("import "); writeTextOfNode(currentSourceFile, node.name); write(" = "); - if (node.entityName) { - emitTypeWithNewGetSymbolAccessibilityDiangostic(node.entityName, getImportEntityNameVisibilityError); + if (isInternalModuleImportDeclaration(node)) { + emitTypeWithNewGetSymbolAccessibilityDiangostic(node.moduleReference, getImportEntityNameVisibilityError); write(";"); } else { write("require("); - writeTextOfNode(currentSourceFile, node.externalModuleName); + writeTextOfNode(currentSourceFile, getExternalModuleImportDeclarationExpression(node)); write(");"); } writer.writeLine(); @@ -3304,7 +3304,7 @@ module ts { } if (emitImportDeclaration) { - if (node.externalModuleName && node.parent.kind === SyntaxKind.SourceFile && compilerOptions.module === ModuleKind.AMD) { + if (isExternalModuleImportDeclaration(node) && node.parent.kind === SyntaxKind.SourceFile && compilerOptions.module === ModuleKind.AMD) { if (node.flags & NodeFlags.Export) { writeLine(); emitLeadingComments(node); @@ -3324,15 +3324,16 @@ module ts { if (!(node.flags & NodeFlags.Export)) write("var "); emitModuleMemberName(node); write(" = "); - if (node.entityName) { - emit(node.entityName); + if (isInternalModuleImportDeclaration(node)) { + emit(node.moduleReference); } else { + var literal = getExternalModuleImportDeclarationExpression(node); write("require("); - emitStart(node.externalModuleName); - emitLiteral(node.externalModuleName); - emitEnd(node.externalModuleName); - emitToken(SyntaxKind.CloseParenToken, node.externalModuleName.end); + emitStart(literal); + emitLiteral(literal); + emitEnd(literal); + emitToken(SyntaxKind.CloseParenToken, literal.end); } write(";"); emitEnd(node); @@ -3343,12 +3344,9 @@ module ts { function getExternalImportDeclarations(node: SourceFile): ImportDeclaration[] { var result: ImportDeclaration[] = []; - forEach(node.statements, stat => { - if (stat.kind === SyntaxKind.ImportDeclaration - && (stat).externalModuleName - && resolver.isReferencedImportDeclaration(stat)) { - - result.push(stat); + forEach(node.statements, statement => { + if (isExternalModuleImportDeclaration(statement) && resolver.isReferencedImportDeclaration(statement)) { + result.push(statement); } }); return result; @@ -3372,7 +3370,7 @@ module ts { write("[\"require\", \"exports\""); forEach(imports, imp => { write(", "); - emitLiteral(imp.externalModuleName); + emitLiteral(getExternalModuleImportDeclarationExpression(imp)); }); forEach(node.amdDependencies, amdDependency => { var text = "\"" + amdDependency + "\""; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index cea57352ae3..33973f4ac3d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5,6 +5,10 @@ module ts { var nodeConstructors = new Array Node>(SyntaxKind.Count); + export function getFullWidth(node: Node) { + return node.end - node.pos; + } + export function getNodeConstructor(kind: SyntaxKind): new () => Node { return nodeConstructors[kind] || (nodeConstructors[kind] = objectAllocator.getNodeConstructor(kind)); } @@ -75,13 +79,14 @@ module ts { // Computed property names will just be emitted as "[]", where is the source // text of the expression in the computed property. export function declarationNameToString(name: DeclarationName) { - return name.kind === SyntaxKind.Missing ? "(Missing)" : getTextOfNode(name); + return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name); } export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic { node = getErrorSpanForNode(node); var file = getSourceFileOfNode(node); - var start = node.kind === SyntaxKind.Missing ? node.pos : skipTrivia(file.text, node.pos); + + var start = getFullWidth(node) === 0 ? node.pos : skipTrivia(file.text, node.pos); var length = node.end - start; return createFileDiagnostic(file, start, length, message, arg0, arg1, arg2); @@ -382,8 +387,7 @@ module ts { child((node).body); case SyntaxKind.ImportDeclaration: return child((node).name) || - child((node).entityName) || - child((node).externalModuleName); + child((node).moduleReference); case SyntaxKind.ExportAssignment: return child((node).exportName); case SyntaxKind.TemplateExpression: @@ -394,6 +398,8 @@ module ts { return child((node).expression); case SyntaxKind.HeritageClause: return children((node).types); + case SyntaxKind.ExternalModuleReference: + return child((node).expression); } } @@ -589,6 +595,19 @@ module ts { return false; } + export function isExternalModuleImportDeclaration(node: Node) { + return node.kind === SyntaxKind.ImportDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference; + } + + export function getExternalModuleImportDeclarationExpression(node: Node) { + Debug.assert(isExternalModuleImportDeclaration(node)); + return ((node).moduleReference).expression; + } + + export function isInternalModuleImportDeclaration(node: Node) { + return node.kind === SyntaxKind.ImportDeclaration && (node).moduleReference.kind !== SyntaxKind.ExternalModuleReference; + } + export function hasRestParameters(s: SignatureDeclaration): boolean { return s.parameters.length > 0 && (s.parameters[s.parameters.length - 1].flags & NodeFlags.Rest) !== 0; } @@ -760,7 +779,7 @@ module ts { TypeMembers, // Members in interface or type literal ClassMembers, // Members in class declaration EnumMembers, // Members in enum declaration - BaseTypeReferences, // Type references in extends or implements clause + TypeReferences, // Type references in extends or implements clause VariableDeclarations, // Variable declarations in variable statement ArgumentExpressions, // Expressions in argument list ObjectLiteralMembers, // Members in object literal @@ -789,7 +808,7 @@ module ts { case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected; case ParsingContext.ClassMembers: return Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected; case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected; - case ParsingContext.BaseTypeReferences: return Diagnostics.Type_reference_expected; + case ParsingContext.TypeReferences: return Diagnostics.Type_reference_expected; case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected; case ParsingContext.ArgumentExpressions: return Diagnostics.Argument_expression_expected; case ParsingContext.ObjectLiteralMembers: return Diagnostics.Property_assignment_expected; @@ -798,6 +817,7 @@ module ts { case ParsingContext.TypeParameters: return Diagnostics.Type_parameter_declaration_expected; case ParsingContext.TypeArguments: return Diagnostics.Type_argument_expected; case ParsingContext.TupleElementTypes: return Diagnostics.Type_expected; + case ParsingContext.HeritageClauses: return Diagnostics.Unexpected_token_expected; } }; @@ -809,7 +829,7 @@ module ts { export interface ReferencePathMatchResult { fileReference?: FileReference - diagnostic?: DiagnosticMessage + diagnosticMessage?: DiagnosticMessage isNoDefaultLib?: boolean } @@ -838,7 +858,7 @@ module ts { } else { return { - diagnostic: Diagnostics.Invalid_reference_directive_syntax, + diagnosticMessage: Diagnostics.Invalid_reference_directive_syntax, isNoDefaultLib: false }; } @@ -863,6 +883,7 @@ module ts { case SyntaxKind.StaticKeyword: case SyntaxKind.ExportKeyword: case SyntaxKind.DeclareKeyword: + case SyntaxKind.ConstKeyword: return true; } return false; @@ -876,6 +897,7 @@ module ts { case SyntaxKind.PrivateKeyword: return NodeFlags.Private; case SyntaxKind.ExportKeyword: return NodeFlags.Export; case SyntaxKind.DeclareKeyword: return NodeFlags.Ambient; + case SyntaxKind.ConstKeyword: return NodeFlags.Const; } return 0; } @@ -1043,16 +1065,17 @@ module ts { var start = scanner.getTokenPos(); var length = scanner.getTextPos() - start; - errorAtPos(start, length, message, arg0, arg1, arg2); + errorAtPosition(start, length, message, arg0, arg1, arg2); } - function errorAtPos(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { - var lastErrorPos = file.parseDiagnostics.length + function errorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { + var lastErrorPosition = file.parseDiagnostics.length ? file.parseDiagnostics[file.parseDiagnostics.length - 1].start : -1; - if (start !== lastErrorPos) { + + // Don't report another error if it would just be at the same position as the last error. + if (start !== lastErrorPosition) { var diagnostic = createFileDiagnostic(file, start, length, message, arg0, arg1, arg2); - diagnostic.isParseError = true; file.parseDiagnostics.push(diagnostic); } @@ -1063,7 +1086,7 @@ module ts { function scanError(message: DiagnosticMessage) { var pos = scanner.getTextPos(); - errorAtPos(pos, 0, message); + errorAtPosition(pos, 0, message); } function onComment(pos: number, end: number) { @@ -1165,17 +1188,18 @@ module ts { return inStrictModeContext() ? token > SyntaxKind.LastFutureReservedWord : token > SyntaxKind.LastReservedWord; } - function parseExpected(t: SyntaxKind, diagnosticMessage?: DiagnosticMessage): boolean { - if (token === t) { + function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): boolean { + if (token === kind) { nextToken(); return true; } + // Report specific message if provided with one. Otherwise, report generic fallback message. if (diagnosticMessage) { - error(diagnosticMessage); + error(diagnosticMessage, arg0); } else { - error(Diagnostics._0_expected, tokenToString(t)); + error(Diagnostics._0_expected, tokenToString(kind)); } return false; } @@ -1207,7 +1231,7 @@ module ts { return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.EndOfFileToken || scanner.hasPrecedingLineBreak(); } - function parseSemicolon(): void { + function parseSemicolon(diagnosticMessage?: DiagnosticMessage): void { if (canParseSemicolon()) { if (token === SyntaxKind.SemicolonToken) { // consume the semicolon if it was explicitly provided. @@ -1215,7 +1239,7 @@ module ts { } } else { - error(Diagnostics._0_expected, ";"); + parseExpected(SyntaxKind.SemicolonToken, diagnosticMessage); } } @@ -1241,8 +1265,21 @@ module ts { return node; } - function createMissingNode(pos?: number): Node { - return createNode(SyntaxKind.Missing, pos); + function createMissingNode(kind: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node { + if (reportAtCurrentPosition) { + errorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); + } + else { + error(diagnosticMessage, arg0); + } + + return createMissingNodeWithoutError(kind); + } + + function createMissingNodeWithoutError(kind: SyntaxKind) { + var result = createNode(kind, scanner.getStartPos()); + (result).text = ""; + return finishNode(result); } function internIdentifier(text: string): string { @@ -1253,7 +1290,7 @@ module ts { // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for // each identifier in order to reduce memory consumption. - function createIdentifier(isIdentifier: boolean): Identifier { + function createIdentifier(isIdentifier: boolean, diagnosticMessage?: DiagnosticMessage): Identifier { identifierCount++; if (isIdentifier) { var node = createNode(SyntaxKind.Identifier); @@ -1261,14 +1298,12 @@ module ts { nextToken(); return finishNode(node); } - error(Diagnostics.Identifier_expected); - var node = createMissingNode(); - node.text = ""; - return node; + + return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition:*/ false, diagnosticMessage || Diagnostics.Identifier_expected); } - function parseIdentifier(): Identifier { - return createIdentifier(isIdentifier()); + function parseIdentifier(diagnosticMessage?: DiagnosticMessage): Identifier { + return createIdentifier(isIdentifier(), diagnosticMessage); } function parseIdentifierName(): Identifier { @@ -1328,6 +1363,11 @@ module ts { function parseAnyContextualModifier(): boolean { return isModifier(token) && tryParse(() => { + if (token === SyntaxKind.ConstKeyword) { + // 'const' is only a modifier if followed by 'enum'. + return nextToken() === SyntaxKind.EnumKeyword; + } + nextToken(); return canFollowModifier(); }); @@ -1358,7 +1398,7 @@ module ts { return token === SyntaxKind.OpenBracketToken || isLiteralPropertyName(); case ParsingContext.ObjectLiteralMembers: return token === SyntaxKind.OpenBracketToken || token === SyntaxKind.AsteriskToken || isLiteralPropertyName(); - case ParsingContext.BaseTypeReferences: + case ParsingContext.TypeReferences: return isIdentifier() && ((token !== SyntaxKind.ExtendsKeyword && token !== SyntaxKind.ImplementsKeyword) || !lookAhead(() => (nextToken(), isIdentifier()))); case ParsingContext.VariableDeclarations: case ParsingContext.TypeParameters: @@ -1397,7 +1437,7 @@ module ts { return token === SyntaxKind.CloseBraceToken; case ParsingContext.SwitchClauseStatements: return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword; - case ParsingContext.BaseTypeReferences: + case ParsingContext.TypeReferences: return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.ExtendsKeyword || token === SyntaxKind.ImplementsKeyword; case ParsingContext.VariableDeclarations: return isVariableDeclaratorListTerminator(); @@ -1467,12 +1507,14 @@ module ts { var result = >[]; result.pos = getNodePos(); var savedStrictModeContext = inStrictModeContext(); + while (!isListTerminator(kind)) { if (isListElement(kind, /* inErrorRecovery */ false)) { var element = parseElement(); result.push(element); + // test elements only if we are not already in strict mode - if (!inStrictModeContext() && checkForStrictMode) { + if (checkForStrictMode && !inStrictModeContext()) { if (isPrologueDirective(element)) { if (isUseStrictPrologueDirective(element)) { setStrictModeContext(true); @@ -1483,21 +1525,32 @@ module ts { checkForStrictMode = false; } } + + continue; } - else { - error(parsingContextErrors(kind)); - if (isInSomeParsingContext()) { - break; - } - nextToken(); + + if (abortParsingListOrMoveToNextToken(kind)) { + break; } } + setStrictModeContext(savedStrictModeContext); result.end = getNodeEnd(); parsingContext = saveParsingContext; return result; } + // Returns true if we should abort parsing. + function abortParsingListOrMoveToNextToken(kind: ParsingContext) { + error(parsingContextErrors(kind)); + if (isInSomeParsingContext()) { + return true; + } + + nextToken(); + return false; + } + // Parses a comma-delimited list of elements function parseDelimitedList(kind: ParsingContext, parseElement: () => T): NodeArray { var saveParsingContext = parsingContext; @@ -1517,17 +1570,16 @@ module ts { if (isListTerminator(kind)) { break; } - error(Diagnostics._0_expected, ","); + parseExpected(SyntaxKind.CommaToken); + continue; } - else if (isListTerminator(kind)) { + + if (isListTerminator(kind)) { break; } - else { - error(parsingContextErrors(kind)); - if (isInSomeParsingContext()) { - break; - } - nextToken(); + + if (abortParsingListOrMoveToNextToken(kind)) { + break; } } @@ -1565,8 +1617,8 @@ module ts { } // The allowReservedWords parameter controls whether reserved words are permitted after the first dot - function parseEntityName(allowReservedWords: boolean): EntityName { - var entity: EntityName = parseIdentifier(); + function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { + var entity: EntityName = parseIdentifier(diagnosticMessage); while (parseOptional(SyntaxKind.DotToken)) { var node = createNode(SyntaxKind.QualifiedName, entity.pos); node.left = entity; @@ -1603,8 +1655,10 @@ module ts { }); if (matchesPattern) { - errorAtPos(scanner.getTokenPos(), 0, Diagnostics.Identifier_expected); - return createMissingNode(); + // Report that we need an identifier. However, report it right after the dot, + // and not on the next token. This is because the next token might actually + // be an identifier and the error woudl be quite confusing. + return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentToken:*/ true, Diagnostics.Identifier_expected); } } @@ -1617,15 +1671,6 @@ module ts { return finishNode(node); } - function parseExpectedTokenNode(kind: SyntaxKind): Node { - if (token === kind) { - return parseTokenNode(); - } - - parseExpected(kind); - return createMissingNode(); - } - function parseTemplateExpression(): TemplateExpression { var template = createNode(SyntaxKind.TemplateExpression); @@ -1657,13 +1702,11 @@ module ts { literal = parseLiteralNode(); } else { - error(Diagnostics.Invalid_template_literal_expected); - literal = createMissingNode(); - literal.text = ""; + literal = createMissingNode( + SyntaxKind.TemplateTail, /*reportAtCurrentPosition:*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); } span.literal = literal; - return finishNode(span); } @@ -1696,19 +1739,11 @@ module ts { return node; } - function parseStringLiteral(): LiteralExpression { - if (token === SyntaxKind.StringLiteral) { - return parseLiteralNode(/*internName:*/ true); - } - error(Diagnostics.String_literal_expected); - return createMissingNode(); - } - // TYPES function parseTypeReference(): TypeReferenceNode { var node = createNode(SyntaxKind.TypeReference); - node.typeName = parseEntityName(/*allowReservedWords*/ false); + node.typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected); if (!scanner.hasPrecedingLineBreak() && token === SyntaxKind.LessThanToken) { node.typeArguments = parseTypeArguments(); } @@ -1756,9 +1791,7 @@ module ts { function parseParameterType(): TypeNode { return parseOptional(SyntaxKind.ColonToken) - ? token === SyntaxKind.StringLiteral - ? parseStringLiteral() - : parseType() + ? token === SyntaxKind.StringLiteral ? parseLiteralNode(/*internName:*/ true) : parseType() : undefined; } @@ -1789,7 +1822,7 @@ module ts { ? doInYieldContext(parseIdentifier) : parseIdentifier(); - if (node.name.kind === SyntaxKind.Missing && node.flags === 0 && isModifier(token)) { + if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifier(token)) { // in cases like // 'use strict' // function foo(static) @@ -2080,9 +2113,11 @@ module ts { case SyntaxKind.StringKeyword: case SyntaxKind.NumberKeyword: case SyntaxKind.BooleanKeyword: - case SyntaxKind.VoidKeyword: + // If these are followed by a dot, then parse these out as a dotted type reference instead. var node = tryParse(parseKeywordAndNoDot); return node || parseTypeReference(); + case SyntaxKind.VoidKeyword: + return parseTokenNode(); case SyntaxKind.TypeOfKeyword: return parseTypeQuery(); case SyntaxKind.OpenBraceToken: @@ -2092,12 +2127,8 @@ module ts { case SyntaxKind.OpenParenToken: return parseParenType(); default: - if (isIdentifier()) { - return parseTypeReference(); - } + return parseTypeReference(); } - error(Diagnostics.Type_expected); - return createMissingNode(); } function isStartOfType(): boolean { @@ -2445,7 +2476,7 @@ module ts { if (triState === Tristate.True) { // Arrow function are never generators. - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ false); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /*returnTokenRequired:*/ false, /*yieldAndGeneratorParameterContext:*/ false); // 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. @@ -2454,7 +2485,7 @@ module ts { } else { // If not, we're probably better off bailing out and returning a bogus function expression. - return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /*asteriskToken:*/ undefined, /*name:*/ undefined, sig, createMissingNode()); + return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /*asteriskToken:*/ undefined, /*name:*/ undefined, sig, parseIdentifier(Diagnostics.Expression_expected)); } } @@ -2904,9 +2935,6 @@ module ts { literal.text = internIdentifier(literal.text); } } - else { - indexedAccess.argumentExpression = createMissingNode(); - } parseExpected(SyntaxKind.CloseBracketToken); expression = finishNode(indexedAccess); @@ -2982,7 +3010,9 @@ module ts { // don't want to rollback just because we were missing a type arg. The grammar checker // will report the actual error later on. if (token === SyntaxKind.CommaToken) { - return createNode(SyntaxKind.Missing); + var result = createNode(SyntaxKind.TypeReference); + result.typeName = createMissingNodeWithoutError(SyntaxKind.Identifier); + return finishNode(result); } return parseType(); @@ -3018,14 +3048,9 @@ module ts { break; case SyntaxKind.TemplateHead: return parseTemplateExpression(); - - default: - if (isIdentifier()) { - return parseIdentifier(); - } } - error(Diagnostics.Expression_expected); - return createMissingNode(); + + return parseIdentifier(Diagnostics.Expression_expected); } function parseParenthesizedExpression(): ParenthesizedExpression { @@ -3170,8 +3195,8 @@ module ts { } // STATEMENTS - function parseBlock(ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean): Block { - var node = createNode(SyntaxKind.Block); + function parseBlock(kind: SyntaxKind, ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean): Block { + var node = createNode(kind); if (parseExpected(SyntaxKind.OpenBraceToken) || ignoreMissingOpenBrace) { node.statements = parseList(ParsingContext.BlockStatements, checkForStrictMode, parseStatement); parseExpected(SyntaxKind.CloseBraceToken); @@ -3186,8 +3211,7 @@ module ts { var savedYieldContext = inYieldContext(); setYieldContext(allowYield); - var block = parseBlock(ignoreMissingOpenBrace, /*checkForStrictMode*/ true); - block.kind = SyntaxKind.FunctionBlock; + var block = parseBlock(SyntaxKind.FunctionBlock, ignoreMissingOpenBrace, /*checkForStrictMode*/ true); setYieldContext(savedYieldContext); @@ -3365,12 +3389,17 @@ module ts { } function parseThrowStatement(): ThrowStatement { + // ThrowStatement[Yield] : + // throw [no LineTerminator here]Expression[In, ?Yield]; + + // Because of automatic semicolon insertion, we need to report error if this + // throw could be terminated with a semicolon. Note: we can't call 'parseExpression' + // directly as that might consume an expression on the following line. + // We just return 'undefined' in that case. The actual error will be reported in the + // grammar walker. var node = createNode(SyntaxKind.ThrowStatement); parseExpected(SyntaxKind.ThrowKeyword); - if (scanner.hasPrecedingLineBreak()) { - error(Diagnostics.Line_break_not_permitted_here); - } - node.expression = allowInAnd(parseExpression); + node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression); parseSemicolon(); return finishNode(node); } @@ -3378,24 +3407,23 @@ module ts { // TODO: Review for error recovery function parseTryStatement(): TryStatement { var node = createNode(SyntaxKind.TryStatement); - node.tryBlock = parseTokenAndBlock(SyntaxKind.TryKeyword, SyntaxKind.TryBlock); - if (token === SyntaxKind.CatchKeyword) { - node.catchBlock = parseCatchBlock(); - } - if (token === SyntaxKind.FinallyKeyword) { - node.finallyBlock = parseTokenAndBlock(SyntaxKind.FinallyKeyword, SyntaxKind.FinallyBlock); - } - if (!(node.catchBlock || node.finallyBlock)) { - error(Diagnostics.catch_or_finally_expected); - } + node.tryBlock = parseTokenAndBlock(SyntaxKind.TryKeyword); + node.catchBlock = token === SyntaxKind.CatchKeyword ? parseCatchBlock() : undefined; + + // If we don't have a catch clause, then we must have a finally clause. Try to parse + // one out no matter what. + node.finallyBlock = !node.catchBlock || token === SyntaxKind.FinallyKeyword + ? parseTokenAndBlock(SyntaxKind.FinallyKeyword) + : undefined; return finishNode(node); } - function parseTokenAndBlock(token: SyntaxKind, kind: SyntaxKind): Block { + function parseTokenAndBlock(token: SyntaxKind): Block { var pos = getNodePos(); parseExpected(token); - var result = parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); - result.kind = kind; + var result = parseBlock( + token === SyntaxKind.TryKeyword ? SyntaxKind.TryBlock : SyntaxKind.FinallyBlock, + /* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); result.pos = pos; return result; } @@ -3407,8 +3435,7 @@ module ts { var variable = parseIdentifier(); var typeAnnotation = parseTypeAnnotation(); parseExpected(SyntaxKind.CloseParenToken); - var result = parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); - result.kind = SyntaxKind.CatchBlock; + var result = parseBlock(SyntaxKind.CatchBlock, /* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); result.pos = pos; result.variable = variable; result.type = typeAnnotation; @@ -3507,7 +3534,7 @@ module ts { function parseStatement(): Statement { switch (token) { case SyntaxKind.OpenBraceToken: - return parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); + return parseBlock(SyntaxKind.Block, /* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: @@ -3556,12 +3583,8 @@ module ts { return parseFunctionBlock(isGenerator, /* ignoreMissingOpenBrace */ false); } - if (canParseSemicolon()) { - parseSemicolon(); - return undefined; - } - - error(Diagnostics.Block_or_expected); // block or ';' expected + parseSemicolon(Diagnostics.or_expected); + return undefined; } // DECLARATIONS @@ -3823,7 +3846,7 @@ module ts { var node = createNode(SyntaxKind.HeritageClause); node.token = token; nextToken(); - node.types = parseDelimitedList(ParsingContext.BaseTypeReferences, parseTypeReference); + node.types = parseDelimitedList(ParsingContext.TypeReferences, parseTypeReference); return finishNode(node); } @@ -3838,10 +3861,6 @@ module ts { return parseList(ParsingContext.ClassMembers, /*checkForStrictMode*/ false, parseClassElement); } - function parseClassBaseType(): TypeReferenceNode { - return parseOptional(SyntaxKind.ExtendsKeyword) ? parseTypeReference() : undefined; - } - function parseInterfaceDeclaration(fullStart: number, modifiers: ModifiersArray): InterfaceDeclaration { var node = createNode(SyntaxKind.InterfaceDeclaration, fullStart); setModifiers(node, modifiers); @@ -3875,12 +3894,9 @@ module ts { return finishNode(node); } - function parseAndCheckEnumDeclaration(fullStart: number, flags: NodeFlags): EnumDeclaration { + function parseAndCheckEnumDeclaration(fullStart: number, modifiers: ModifiersArray, flags: NodeFlags): EnumDeclaration { var node = createNode(SyntaxKind.EnumDeclaration, fullStart); - node.flags = flags; - if (flags & NodeFlags.Const) { - parseExpected(SyntaxKind.ConstKeyword); - } + setModifiers(node, modifiers); parseExpected(SyntaxKind.EnumKeyword); node.name = parseIdentifier(); if (parseExpected(SyntaxKind.OpenBraceToken)) { @@ -3905,29 +3921,42 @@ module ts { return finishNode(node); } - function parseInternalModuleTail(fullStart: number, flags: NodeFlags): ModuleDeclaration { + function parseInternalModuleTail(fullStart: number, modifiers: ModifiersArray, flags: NodeFlags): ModuleDeclaration { var node = createNode(SyntaxKind.ModuleDeclaration, fullStart); - node.flags = flags; + setModifiers(node, modifiers); + node.flags |= flags; node.name = parseIdentifier(); node.body = parseOptional(SyntaxKind.DotToken) - ? parseInternalModuleTail(getNodePos(), NodeFlags.Export) + ? parseInternalModuleTail(getNodePos(), /*modifiers:*/undefined, NodeFlags.Export) : parseModuleBlock(); return finishNode(node); } - function parseAmbientExternalModuleDeclaration(fullStart: number, flags: NodeFlags): ModuleDeclaration { + function parseAmbientExternalModuleDeclaration(fullStart: number, modifiers: ModifiersArray, flags: NodeFlags): ModuleDeclaration { var node = createNode(SyntaxKind.ModuleDeclaration, fullStart); - node.flags = flags; - node.name = parseStringLiteral(); + setModifiers(node, modifiers); + node.flags |= flags; + node.name = parseLiteralNode(/*internName:*/ true); node.body = parseModuleBlock(); return finishNode(node); } - function parseModuleDeclaration(fullStart: number, flags: NodeFlags): ModuleDeclaration { + function parseModuleDeclaration(fullStart: number, modifiers: ModifiersArray, flags: NodeFlags): ModuleDeclaration { parseExpected(SyntaxKind.ModuleKeyword); return token === SyntaxKind.StringLiteral - ? parseAmbientExternalModuleDeclaration(fullStart, flags) - : parseInternalModuleTail(fullStart, flags); + ? parseAmbientExternalModuleDeclaration(fullStart, modifiers, flags) + : parseInternalModuleTail(fullStart, modifiers, flags); + } + + function isExternalModuleReference() { + if (token === SyntaxKind.RequireKeyword) { + return lookAhead(() => { + nextToken(); + return token === SyntaxKind.OpenParenToken; + }); + } + + return false; } function parseImportDeclaration(fullStart: number, modifiers: ModifiersArray): ImportDeclaration { @@ -3936,18 +3965,33 @@ module ts { parseExpected(SyntaxKind.ImportKeyword); node.name = parseIdentifier(); parseExpected(SyntaxKind.EqualsToken); - var entityName = parseEntityName(/*allowReservedWords*/ false); - if (entityName.kind === SyntaxKind.Identifier && (entityName).text === "require" && parseOptional(SyntaxKind.OpenParenToken)) { - node.externalModuleName = parseStringLiteral(); - parseExpected(SyntaxKind.CloseParenToken); - } - else { - node.entityName = entityName; - } + node.moduleReference = parseModuleReference(); parseSemicolon(); return finishNode(node); } + function parseModuleReference() { + return isExternalModuleReference() + ? parseExternalModuleReference() + : parseEntityName(/*allowReservedWords*/ false); + } + + function parseExternalModuleReference() { + var node = createNode(SyntaxKind.ExternalModuleReference); + parseExpected(SyntaxKind.RequireKeyword); + parseExpected(SyntaxKind.OpenParenToken); + + // We allow arbitrary expressions here, even though the grammar only allows string + // literals. We check to ensure that it is only a string literal later in the grammar + // walker. + node.expression = parseExpression(); + if (node.expression.kind === SyntaxKind.StringLiteral) { + internIdentifier((node.expression).text); + } + parseExpected(SyntaxKind.CloseParenToken); + return finishNode(node); + } + function parseExportAssignmentTail(fullStart: number, modifiers: ModifiersArray): ExportAssignment { var node = createNode(SyntaxKind.ExportAssignment, fullStart); setModifiers(node, modifiers); @@ -3997,51 +4041,29 @@ module ts { } var flags = modifiers ? modifiers.flags : 0; - var result: ModuleElement; switch (token) { case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: - result = parseVariableStatement(fullStart, modifiers); - break; + return parseVariableStatement(fullStart, modifiers); case SyntaxKind.ConstKeyword: - var isConstEnum = lookAhead(() => nextToken() === SyntaxKind.EnumKeyword); - if (isConstEnum) { - result = parseAndCheckEnumDeclaration(fullStart, flags | NodeFlags.Const); - } - else { - result = parseVariableStatement(fullStart, modifiers); - } - break; + return parseVariableStatement(fullStart, modifiers); case SyntaxKind.FunctionKeyword: - result = parseFunctionDeclaration(fullStart, modifiers); - break; + return parseFunctionDeclaration(fullStart, modifiers); case SyntaxKind.ClassKeyword: - result = parseClassDeclaration(fullStart, modifiers); - break; + return parseClassDeclaration(fullStart, modifiers); case SyntaxKind.InterfaceKeyword: - result = parseInterfaceDeclaration(fullStart, modifiers); - break; + return parseInterfaceDeclaration(fullStart, modifiers); case SyntaxKind.TypeKeyword: - result = parseTypeAliasDeclaration(fullStart, modifiers); - break; + return parseTypeAliasDeclaration(fullStart, modifiers); case SyntaxKind.EnumKeyword: - result = parseAndCheckEnumDeclaration(fullStart, flags); - break; + return parseAndCheckEnumDeclaration(fullStart, modifiers, flags); case SyntaxKind.ModuleKeyword: - result = parseModuleDeclaration(fullStart, flags); - break; + return parseModuleDeclaration(fullStart, modifiers, flags); case SyntaxKind.ImportKeyword: - result = parseImportDeclaration(fullStart, modifiers); - break; + return parseImportDeclaration(fullStart, modifiers); default: - error(Diagnostics.Declaration_expected); + Debug.fail("Mismatch between isDeclarationStart and parseDeclaration"); } - - if (modifiers) { - result.modifiers = modifiers; - } - - return result; } function isSourceElement(inErrorRecovery: boolean): boolean { @@ -4076,12 +4098,12 @@ module ts { if (referencePathMatchResult) { var fileReference = referencePathMatchResult.fileReference; file.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; - var diagnostic = referencePathMatchResult.diagnostic; + var diagnosticMessage = referencePathMatchResult.diagnosticMessage; if (fileReference) { referencedFiles.push(fileReference); } - if (diagnostic) { - errorAtPos(range.pos, range.end - range.pos, diagnostic); + if (diagnosticMessage) { + file.parseDiagnostics.push(createFileDiagnostic(file, range.pos, range.end - range.pos, diagnosticMessage)); } } else { @@ -4089,7 +4111,7 @@ module ts { var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment); if(amdModuleNameMatchResult) { if(amdModuleName) { - errorAtPos(range.pos, range.end - range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments); + file.parseDiagnostics.push(createFileDiagnostic(file, range.pos, range.end - range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); } amdModuleName = amdModuleNameMatchResult[2]; } @@ -4112,7 +4134,7 @@ module ts { function getExternalModuleIndicator() { return forEach(file.statements, node => node.flags & NodeFlags.Export - || node.kind === SyntaxKind.ImportDeclaration && (node).externalModuleName + || node.kind === SyntaxKind.ImportDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference || node.kind === SyntaxKind.ExportAssignment ? node : undefined); @@ -4152,6 +4174,7 @@ module ts { file.parseDiagnostics = []; file.grammarDiagnostics = []; file.semanticDiagnostics = []; + var referenceComments = processReferenceComments(); file.referencedFiles = referenceComments.referencedFiles; file.amdDependencies = referenceComments.amdDependencies; @@ -4182,7 +4205,6 @@ module ts { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.FunctionExpression: case SyntaxKind.Identifier: - case SyntaxKind.Missing: case SyntaxKind.RegularExpressionLiteral: case SyntaxKind.NumericLiteral: case SyntaxKind.StringLiteral: @@ -4285,6 +4307,7 @@ module ts { case SyntaxKind.DeleteExpression: return checkDeleteExpression( node); case SyntaxKind.ElementAccessExpression: return checkElementAccessExpression(node); case SyntaxKind.ExportAssignment: return checkExportAssignment(node); + case SyntaxKind.ExternalModuleReference: return checkExternalModuleReference(node); case SyntaxKind.ForInStatement: return checkForInStatement(node); case SyntaxKind.ForStatement: return checkForStatement(node); case SyntaxKind.FunctionDeclaration: return checkFunctionDeclaration(node); @@ -4309,6 +4332,7 @@ module ts { case SyntaxKind.ShorthandPropertyAssignment: return checkShorthandPropertyAssignment(node); case SyntaxKind.SwitchStatement: return checkSwitchStatement(node); case SyntaxKind.TaggedTemplateExpression: return checkTaggedTemplateExpression(node); + case SyntaxKind.ThrowStatement: return checkThrowStatement(node); case SyntaxKind.TupleType: return checkTupleType(node); case SyntaxKind.TypeParameter: return checkTypeParameter(node); case SyntaxKind.TypeReference: return checkTypeReference(node); @@ -4319,12 +4343,22 @@ module ts { } } - function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { - var start = skipTrivia(sourceText, node.pos); + function scanToken(pos: number) { + var start = skipTrivia(sourceText, pos); scanner.setTextPos(start); scanner.scan(); - var end = scanner.getTextPos(); - grammarDiagnostics.push(createFileDiagnostic(file, start, end - start, message, arg0, arg1, arg2)); + return start; + } + + function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + var start = scanToken(node.pos); + grammarDiagnostics.push(createFileDiagnostic(file, start, scanner.getTextPos() - start, message, arg0, arg1, arg2)); + return true; + } + + function grammarErrorAfterFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + scanToken(node.pos); + grammarDiagnostics.push(createFileDiagnostic(file, scanner.getTextPos(), 0, message, arg0, arg1, arg2)); return true; } @@ -4501,7 +4535,7 @@ module ts { if (typeArguments) { for (var i = 0, n = typeArguments.length; i < n; i++) { var arg = typeArguments[i]; - if (arg.kind === SyntaxKind.Missing) { + if (arg.kind === SyntaxKind.TypeReference && getFullWidth((arg).typeName) === 0) { return grammarErrorAtPos(arg.pos, 0, Diagnostics.Type_expected); } } @@ -4671,6 +4705,12 @@ module ts { } } + function checkExternalModuleReference(node: ExternalModuleReference) { + if (node.expression.kind !== SyntaxKind.StringLiteral) { + return grammarErrorOnNode(node.expression, Diagnostics.String_literal_expected); + } + } + function checkForInStatement(node: ForInStatement) { return checkVariableDeclarations(node.declarations) || checkForMoreThanOneDeclaration(node.declarations); @@ -4719,7 +4759,7 @@ module ts { } function checkElementAccessExpression(node: ElementAccessExpression) { - if (node.argumentExpression.kind === SyntaxKind.Missing) { + if (!node.argumentExpression) { if (node.parent.kind === SyntaxKind.NewExpression && (node.parent).expression === node) { var start = skipTrivia(sourceText, node.expression.end); var end = node.end; @@ -4871,8 +4911,8 @@ module ts { // Export assignments are not allowed in an internal module return grammarErrorOnNode(statement, Diagnostics.An_export_assignment_cannot_be_used_in_an_internal_module); } - else if (statement.kind === SyntaxKind.ImportDeclaration && (statement).externalModuleName) { - return grammarErrorOnNode((statement).externalModuleName, Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module); + else if (isExternalModuleImportDeclaration(statement)) { + return grammarErrorOnNode(getExternalModuleImportDeclarationExpression(statement), Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module); } } } @@ -5336,6 +5376,12 @@ module ts { } } + function checkThrowStatement(node: ThrowStatement) { + if (node.expression === undefined) { + return grammarErrorAfterFirstToken(node, Diagnostics.Line_break_not_permitted_here); + } + } + function checkTupleType(node: TupleTypeNode) { return checkForDisallowedTrailingComma(node.elementTypes) || checkForAtLeastOneType(node); @@ -5588,8 +5634,10 @@ module ts { function processImportedModules(file: SourceFile, basePath: string) { forEach(file.statements, node => { - if (node.kind === SyntaxKind.ImportDeclaration && (node).externalModuleName) { - var nameLiteral = (node).externalModuleName; + if (isExternalModuleImportDeclaration(node) && + getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) { + + var nameLiteral = getExternalModuleImportDeclarationExpression(node); var moduleName = nameLiteral.text; if (moduleName) { var searchPath = basePath; @@ -5614,8 +5662,10 @@ module ts { // The StringLiteral must specify a top - level external module name. // Relative external module names are not permitted forEachChild((node).body, node => { - if (node.kind === SyntaxKind.ImportDeclaration && (node).externalModuleName) { - var nameLiteral = (node).externalModuleName; + if (isExternalModuleImportDeclaration(node) && + getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) { + + var nameLiteral = getExternalModuleImportDeclarationExpression(node); var moduleName = nameLiteral.text; if (moduleName) { // TypeScript 1.0 spec (April 2014): 12.1.6 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e562cbc3b61..ad74280dab5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -137,8 +137,9 @@ module ts { SetKeyword, StringKeyword, TypeKeyword, + // Parse tree nodes - Missing, + // Names QualifiedName, ComputedPropertyName, @@ -221,6 +222,8 @@ module ts { ModuleBlock, ImportDeclaration, ExportAssignment, + // Module references + ExternalModuleReference, // Clauses CaseClause, DefaultClause, @@ -233,6 +236,7 @@ module ts { // Top-level nodes SourceFile, Program, + // Synthesized list SyntaxList, // Enum value count @@ -261,7 +265,8 @@ module ts { FirstOperator = SemicolonToken, LastOperator = CaretEqualsToken, FirstBinaryOperator = LessThanToken, - LastBinaryOperator = CaretEqualsToken + LastBinaryOperator = CaretEqualsToken, + FirstNode = QualifiedName, } export const enum NodeFlags { @@ -562,7 +567,7 @@ module ts { export interface ElementAccessExpression extends MemberExpression { expression: LeftHandSideExpression; - argumentExpression: Expression; + argumentExpression?: Expression; } export interface CallExpression extends LeftHandSideExpression { @@ -730,8 +735,14 @@ module ts { export interface ImportDeclaration extends Declaration, ModuleElement { name: Identifier; - entityName?: EntityName; - externalModuleName?: LiteralExpression; + + // 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external + // module reference. + moduleReference: EntityName | ExternalModuleReference; + } + + export interface ExternalModuleReference extends Node { + expression?: Expression; } export interface ExportAssignment extends Statement, ModuleElement { @@ -1267,12 +1278,6 @@ module ts { * Early error - any error (can be produced at parsing\binding\typechecking step) that blocks emit */ isEarly?: boolean; - /** - * Parse error - error produced by parser when it scanner returns a token - * that parser does not understand in its current state - * (as opposed to grammar error when parser can interpret the token but interpretation is not legal from the grammar perespective) - */ - isParseError?: boolean; } export enum DiagnosticCategory { diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index d4aa5e40f39..6cf775487fa 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -174,7 +174,7 @@ module ts.BreakpointResolver { case SyntaxKind.ImportDeclaration: // import statement without including semicolon - return textSpan(node, (node).entityName || (node).externalModuleName); + return textSpan(node,(node).moduleReference); case SyntaxKind.ModuleDeclaration: // span on complete module if it is instantiated diff --git a/src/services/formatting.ts b/src/services/formatting.ts index fc64329c3e0..741b853b7ba 100644 --- a/src/services/formatting.ts +++ b/src/services/formatting.ts @@ -192,7 +192,7 @@ module ts.formatting { // pick only errors that fall in range var sorted = errors - .filter(d => d.isParseError && rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length)) + .filter(d => rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length)) .sort((e1, e2) => e1.start - e2.start); if (!sorted.length) { @@ -252,7 +252,7 @@ module ts.formatting { rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[] { - var rangeContainsError = prepareRangeContainsErrorFunction(sourceFile.getSyntacticDiagnostics(), originalRange); + var rangeContainsError = prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange); // formatting context is used by rules provider var formattingContext = new FormattingContext(sourceFile, requestKind); @@ -483,8 +483,8 @@ module ts.formatting { if (!rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) { return inheritedIndentation; } - - if (child.kind === SyntaxKind.Missing) { + + if (child.getFullWidth() === 0) { return inheritedIndentation; } diff --git a/src/services/services.ts b/src/services/services.ts index 37b5612c823..8bbc03aad6f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -218,7 +218,7 @@ module ts { } private createChildren(sourceFile?: SourceFile) { - if (this.kind > SyntaxKind.Missing) { + if (this.kind >= SyntaxKind.FirstNode) { scanner.setText((sourceFile || this.getSourceFile()).text); var children: Node[] = []; var pos = this.pos; @@ -264,8 +264,11 @@ module ts { var children = this.getChildren(); for (var i = 0; i < children.length; i++) { var child = children[i]; - if (child.kind < SyntaxKind.Missing) return child; - if (child.kind > SyntaxKind.Missing) return child.getFirstToken(sourceFile); + if (child.kind < SyntaxKind.FirstNode) { + return child; + } + + return child.getFirstToken(sourceFile); } } @@ -273,8 +276,11 @@ module ts { var children = this.getChildren(sourceFile); for (var i = children.length - 1; i >= 0; i--) { var child = children[i]; - if (child.kind < SyntaxKind.Missing) return child; - if (child.kind > SyntaxKind.Missing) return child.getLastToken(sourceFile); + if (child.kind < SyntaxKind.FirstNode) { + return child; + } + + return child.getLastToken(sourceFile); } } } @@ -758,7 +764,7 @@ module ts { case SyntaxKind.Method: var functionDeclaration = node; - if (functionDeclaration.name && functionDeclaration.name.kind !== SyntaxKind.Missing) { + if (functionDeclaration.name && functionDeclaration.name.getFullWidth() > 0) { var lastDeclaration = namedDeclarations.length > 0 ? namedDeclarations[namedDeclarations.length - 1] : undefined; @@ -1980,9 +1986,12 @@ module ts { } function isNameOfExternalModuleImportOrDeclaration(node: Node): boolean { - return node.kind === SyntaxKind.StringLiteral && - (isNameOfModuleDeclaration(node) || - (node.parent.kind === SyntaxKind.ImportDeclaration && (node.parent).externalModuleName === node)); + if (node.kind === SyntaxKind.StringLiteral) { + return isNameOfModuleDeclaration(node) || + (isExternalModuleImportDeclaration(node.parent.parent) && getExternalModuleImportDeclarationExpression(node.parent.parent) === node); + } + + return false; } /** Returns true if the position is within a comment */ @@ -2859,7 +2868,7 @@ module ts { if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) { var right = (location.parent).name; // Either the location is on the right of a property access, or on the left and the right is missing - if (right === location || (right && right.kind === SyntaxKind.Missing)){ + if (right === location || (right && right.getFullWidth() === 0)){ location = location.parent; } } @@ -3054,17 +3063,17 @@ module ts { ts.forEach(symbol.declarations, declaration => { if (declaration.kind === SyntaxKind.ImportDeclaration) { var importDeclaration = declaration; - if (importDeclaration.externalModuleName) { + if (isExternalModuleImportDeclaration(importDeclaration)) { displayParts.push(spacePart()); displayParts.push(punctuationPart(SyntaxKind.EqualsToken)); displayParts.push(spacePart()); displayParts.push(keywordPart(SyntaxKind.RequireKeyword)); displayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); - displayParts.push(displayPart(getTextOfNode(importDeclaration.externalModuleName), SymbolDisplayPartKind.stringLiteral)); + displayParts.push(displayPart(getTextOfNode(getExternalModuleImportDeclarationExpression(importDeclaration)), SymbolDisplayPartKind.stringLiteral)); displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } else { - var internalAliasSymbol = typeResolver.getSymbolInfo(importDeclaration.entityName); + var internalAliasSymbol = typeResolver.getSymbolInfo(importDeclaration.moduleReference); if (internalAliasSymbol) { displayParts.push(spacePart()); displayParts.push(punctuationPart(SyntaxKind.EqualsToken)); @@ -4788,7 +4797,7 @@ module ts { while (node.parent.kind === SyntaxKind.QualifiedName) { node = node.parent; } - return node.parent.kind === SyntaxKind.ImportDeclaration && (node.parent).entityName === node; + return isInternalModuleImportDeclaration(node.parent) && (node.parent).moduleReference === node; } function getMeaningFromRightHandSideOfImport(node: Node) { diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 4ec0b1dfbc2..f3604b3dfdd 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -386,7 +386,7 @@ module ts.SignatureHelp { // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail. if (template.kind === SyntaxKind.TemplateExpression) { var lastSpan = lastOrUndefined((template).templateSpans); - if (lastSpan.literal.kind === SyntaxKind.Missing) { + if (lastSpan.literal.getFullWidth() === 0) { applicableSpanEnd = skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false); } } diff --git a/src/services/smartIndenter.ts b/src/services/smartIndenter.ts index ad06d55e39d..4e32522040e 100644 --- a/src/services/smartIndenter.ts +++ b/src/services/smartIndenter.ts @@ -394,6 +394,10 @@ module ts.formatting { * This function is always called when position of the cursor is located after the node */ function isCompletedNode(n: Node, sourceFile: SourceFile): boolean { + if (n.getFullWidth() === 0) { + return false; + } + switch (n.kind) { case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: @@ -427,8 +431,6 @@ module ts.formatting { return isCompletedNode((n).expression, sourceFile); case SyntaxKind.ArrayLiteralExpression: return nodeEndsWith(n, SyntaxKind.CloseBracketToken, sourceFile); - case SyntaxKind.Missing: - return false; case SyntaxKind.CaseClause: case SyntaxKind.DefaultClause: // there is no such thing as terminator token for CaseClause\DefaultClause so for simplicitly always consider them non-completed diff --git a/tests/baselines/reference/TemplateExpression1.errors.txt b/tests/baselines/reference/TemplateExpression1.errors.txt index bf57f5ef24e..c13b0fabd54 100644 --- a/tests/baselines/reference/TemplateExpression1.errors.txt +++ b/tests/baselines/reference/TemplateExpression1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/es6/templates/TemplateExpression1.ts(1,19): error TS1158: Invalid template literal; expected '}' +tests/cases/conformance/es6/templates/TemplateExpression1.ts(1,19): error TS1005: '}' expected. tests/cases/conformance/es6/templates/TemplateExpression1.ts(1,17): error TS2304: Cannot find name 'a'. ==== tests/cases/conformance/es6/templates/TemplateExpression1.ts (2 errors) ==== var v = `foo ${ a -!!! error TS1158: Invalid template literal; expected '}' +!!! error TS1005: '}' expected. ~ !!! error TS2304: Cannot find name 'a'. \ No newline at end of file diff --git a/tests/baselines/reference/dottedModuleName.errors.txt b/tests/baselines/reference/dottedModuleName.errors.txt index 0b8c3a5c422..9d9de6ee230 100644 --- a/tests/baselines/reference/dottedModuleName.errors.txt +++ b/tests/baselines/reference/dottedModuleName.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/dottedModuleName.ts(3,29): error TS1144: Block or ';' expected. +tests/cases/compiler/dottedModuleName.ts(3,29): error TS1144: '{' or ';' expected. tests/cases/compiler/dottedModuleName.ts(3,18): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/compiler/dottedModuleName.ts(3,33): error TS2304: Cannot find name 'x'. @@ -8,7 +8,7 @@ tests/cases/compiler/dottedModuleName.ts(3,33): error TS2304: Cannot find name ' export module N { export function f(x:number)=>2*x; ~~ -!!! error TS1144: Block or ';' expected. +!!! error TS1144: '{' or ';' expected. ~ !!! error TS2391: Function implementation is missing or not immediately following the declaration. ~ diff --git a/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt b/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt index b91ddad3eb4..e6859558f74 100644 --- a/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt +++ b/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(5,1): error TS1003: Identifier expected. +tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,29): error TS1003: Identifier expected. tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,9): error TS2304: Cannot find name 'IgnoreRulesSpecific'. @@ -7,9 +7,9 @@ tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,9): error TS2304: Ca IgnoreRulesSpecific = 0, } var x = IgnoreRulesSpecific. + +!!! error TS1003: Identifier expected. ~~~~~~~~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'IgnoreRulesSpecific'. var y = Position.IgnoreRulesSpecific; - -!!! error TS1003: Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/enumMemberResolution.errors.txt b/tests/baselines/reference/enumMemberResolution.errors.txt index 18910485236..f446c0d7909 100644 --- a/tests/baselines/reference/enumMemberResolution.errors.txt +++ b/tests/baselines/reference/enumMemberResolution.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/enumMemberResolution.ts(5,1): error TS1003: Identifier expected. +tests/cases/compiler/enumMemberResolution.ts(4,29): error TS1003: Identifier expected. tests/cases/compiler/enumMemberResolution.ts(4,9): error TS2304: Cannot find name 'IgnoreRulesSpecific'. @@ -7,10 +7,10 @@ tests/cases/compiler/enumMemberResolution.ts(4,9): error TS2304: Cannot find nam IgnoreRulesSpecific = 0 } var x = IgnoreRulesSpecific. // error + +!!! error TS1003: Identifier expected. ~~~~~~~~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'IgnoreRulesSpecific'. var y = 1; - -!!! error TS1003: Identifier expected. var z = Position2.IgnoreRulesSpecific; // no error \ No newline at end of file diff --git a/tests/baselines/reference/importNonStringLiteral.errors.txt b/tests/baselines/reference/importNonStringLiteral.errors.txt index ce3dbb3e1ec..7138680d709 100644 --- a/tests/baselines/reference/importNonStringLiteral.errors.txt +++ b/tests/baselines/reference/importNonStringLiteral.errors.txt @@ -1,12 +1,9 @@ tests/cases/conformance/externalModules/importNonStringLiteral.ts(2,22): error TS1141: String literal expected. -tests/cases/conformance/externalModules/importNonStringLiteral.ts(2,23): error TS1005: ';' expected. -==== tests/cases/conformance/externalModules/importNonStringLiteral.ts (2 errors) ==== +==== tests/cases/conformance/externalModules/importNonStringLiteral.ts (1 errors) ==== var x = "filename"; import foo = require(x); // invalid ~ !!! error TS1141: String literal expected. - ~ -!!! error TS1005: ';' expected. \ No newline at end of file diff --git a/tests/baselines/reference/objectTypesWithOptionalProperties2.errors.txt b/tests/baselines/reference/objectTypesWithOptionalProperties2.errors.txt index a427681b22e..533834baea7 100644 --- a/tests/baselines/reference/objectTypesWithOptionalProperties2.errors.txt +++ b/tests/baselines/reference/objectTypesWithOptionalProperties2.errors.txt @@ -2,11 +2,11 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWith tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(4,9): error TS1131: Property or signature expected. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(8,8): error TS1005: ';' expected. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(8,9): error TS1131: Property or signature expected. -tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(12,8): error TS1144: Block or ';' expected. +tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(12,8): error TS1144: '{' or ';' expected. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(12,9): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(16,8): error TS1005: ';' expected. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(16,9): error TS1131: Property or signature expected. -tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(20,8): error TS1144: Block or ';' expected. +tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(20,8): error TS1144: '{' or ';' expected. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(20,9): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(25,8): error TS1005: '{' expected. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties2.ts(25,9): error TS1136: Property assignment expected. @@ -37,7 +37,7 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWith class C { x()?: number; // error ~ -!!! error TS1144: Block or ';' expected. +!!! error TS1144: '{' or ';' expected. ~ !!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. ~ @@ -55,7 +55,7 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWith class C2 { x()?: T; // error ~ -!!! error TS1144: Block or ';' expected. +!!! error TS1144: '{' or ';' expected. ~ !!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. ~ diff --git a/tests/baselines/reference/parseErrorInHeritageClause1.errors.txt b/tests/baselines/reference/parseErrorInHeritageClause1.errors.txt new file mode 100644 index 00000000000..944cdd78e24 --- /dev/null +++ b/tests/baselines/reference/parseErrorInHeritageClause1.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/parseErrorInHeritageClause1.ts(1,19): error TS1127: Invalid character. +tests/cases/compiler/parseErrorInHeritageClause1.ts(1,17): error TS2304: Cannot find name 'A'. + + +==== tests/cases/compiler/parseErrorInHeritageClause1.ts (2 errors) ==== + class C extends A # { + +!!! error TS1127: Invalid character. + ~ +!!! error TS2304: Cannot find name 'A'. + } \ No newline at end of file diff --git a/tests/baselines/reference/parserErrantEqualsGreaterThanAfterFunction1.errors.txt b/tests/baselines/reference/parserErrantEqualsGreaterThanAfterFunction1.errors.txt index 70d6a8481ee..7c32d4433e4 100644 --- a/tests/baselines/reference/parserErrantEqualsGreaterThanAfterFunction1.errors.txt +++ b/tests/baselines/reference/parserErrantEqualsGreaterThanAfterFunction1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction1.ts(1,14): error TS1144: Block or ';' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction1.ts(1,14): error TS1144: '{' or ';' expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction1.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration. ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction1.ts (2 errors) ==== function f() => 4; ~~ -!!! error TS1144: Block or ';' expected. +!!! error TS1144: '{' or ';' expected. ~ !!! error TS2391: Function implementation is missing or not immediately following the declaration. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrantEqualsGreaterThanAfterFunction2.errors.txt b/tests/baselines/reference/parserErrantEqualsGreaterThanAfterFunction2.errors.txt index a830b84ff6e..8df3b0bbff6 100644 --- a/tests/baselines/reference/parserErrantEqualsGreaterThanAfterFunction2.errors.txt +++ b/tests/baselines/reference/parserErrantEqualsGreaterThanAfterFunction2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction2.ts(1,18): error TS1144: Block or ';' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction2.ts(1,18): error TS1144: '{' or ';' expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction2.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction2.ts(1,15): error TS2304: Cannot find name 'A'. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction2.ts(1,21): error TS2304: Cannot find name 'p'. @@ -7,7 +7,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreat ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserErrantEqualsGreaterThanAfterFunction2.ts (4 errors) ==== function f(p: A) => p; ~~ -!!! error TS1144: Block or ';' expected. +!!! error TS1144: '{' or ';' expected. ~ !!! error TS2391: Function implementation is missing or not immediately following the declaration. ~ diff --git a/tests/baselines/reference/parserPostfixPostfixExpression1.errors.txt b/tests/baselines/reference/parserPostfixPostfixExpression1.errors.txt index ad664b91ab5..07c7352bbfc 100644 --- a/tests/baselines/reference/parserPostfixPostfixExpression1.errors.txt +++ b/tests/baselines/reference/parserPostfixPostfixExpression1.errors.txt @@ -1,16 +1,13 @@ tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixPostfixExpression1.ts(1,5): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixPostfixExpression1.ts(1,7): error TS1109: Expression expected. tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixPostfixExpression1.ts(1,1): error TS2304: Cannot find name 'a'. -tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixPostfixExpression1.ts(1,7): error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. -==== tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixPostfixExpression1.ts (4 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixPostfixExpression1.ts (3 errors) ==== a++ ++; ~~ !!! error TS1005: ';' expected. ~ !!! error TS1109: Expression expected. ~ -!!! error TS2304: Cannot find name 'a'. - -!!! error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. \ No newline at end of file +!!! error TS2304: Cannot find name 'a'. \ No newline at end of file diff --git a/tests/baselines/reference/parserPostfixUnaryExpression1.errors.txt b/tests/baselines/reference/parserPostfixUnaryExpression1.errors.txt index 1e1f4ea709a..364efe36a73 100644 --- a/tests/baselines/reference/parserPostfixUnaryExpression1.errors.txt +++ b/tests/baselines/reference/parserPostfixUnaryExpression1.errors.txt @@ -1,16 +1,13 @@ tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixUnaryExpression1.ts(1,8): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixUnaryExpression1.ts(1,10): error TS1109: Expression expected. tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixUnaryExpression1.ts(1,1): error TS2304: Cannot find name 'foo'. -tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixUnaryExpression1.ts(1,10): error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. -==== tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixUnaryExpression1.ts (4 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Expressions/parserPostfixUnaryExpression1.ts (3 errors) ==== foo ++ ++; ~~ !!! error TS1005: ';' expected. ~ !!! error TS1109: Expression expected. ~~~ -!!! error TS2304: Cannot find name 'foo'. - -!!! error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. \ No newline at end of file +!!! error TS2304: Cannot find name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/parservoidInQualifiedName1.errors.txt b/tests/baselines/reference/parservoidInQualifiedName1.errors.txt index a8a77c9a220..d5433fb9078 100644 --- a/tests/baselines/reference/parservoidInQualifiedName1.errors.txt +++ b/tests/baselines/reference/parservoidInQualifiedName1.errors.txt @@ -1,10 +1,7 @@ -tests/cases/conformance/parser/ecmascript5/parservoidInQualifiedName1.ts(1,9): error TS1003: Identifier expected. -tests/cases/conformance/parser/ecmascript5/parservoidInQualifiedName1.ts(1,13): error TS1109: Expression expected. +tests/cases/conformance/parser/ecmascript5/parservoidInQualifiedName1.ts(1,13): error TS1005: ',' expected. -==== tests/cases/conformance/parser/ecmascript5/parservoidInQualifiedName1.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/parservoidInQualifiedName1.ts (1 errors) ==== var v : void.x; - ~~~~ -!!! error TS1003: Identifier expected. ~ -!!! error TS1109: Expression expected. \ No newline at end of file +!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/cases/compiler/parseErrorInHeritageClause1.ts b/tests/cases/compiler/parseErrorInHeritageClause1.ts new file mode 100644 index 00000000000..84223192c7a --- /dev/null +++ b/tests/cases/compiler/parseErrorInHeritageClause1.ts @@ -0,0 +1,2 @@ +class C extends A # { +} \ No newline at end of file