diff --git a/Jakefile.js b/Jakefile.js index 9b95744d392..1f88ee39082 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -505,9 +505,9 @@ function cleanTestDirs() { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests, testConfigFile) { +function writeTestConfigFile(tests, light, testConfigFile) { console.log('Running test(s): ' + tests); - var testConfigContents = JSON.stringify({ test: [tests]}); + var testConfigContents = JSON.stringify({ test: [tests], light: light }); fs.writeFileSync('test.config', testConfigContents); } @@ -523,13 +523,14 @@ task("runtests", ["tests", builtLocalDirectory], function() { cleanTestDirs(); host = "mocha" tests = process.env.test || process.env.tests || process.env.t; + var light = process.env.light || false; var testConfigFile = 'test.config'; if(fs.existsSync(testConfigFile)) { fs.unlinkSync(testConfigFile); } - if(tests) { - writeTestConfigFile(tests, testConfigFile); + if(tests || light) { + writeTestConfigFile(tests, light, testConfigFile); } if (tests && tests.toLocaleLowerCase() === "rwc") { @@ -572,12 +573,13 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory], function( port = process.env.port || process.env.p || '8888'; browser = process.env.browser || process.env.b || "IE"; tests = process.env.test || process.env.tests || process.env.t; + var light = process.env.light || false; var testConfigFile = 'test.config'; if(fs.existsSync(testConfigFile)) { fs.unlinkSync(testConfigFile); } - if(tests) { - writeTestConfigFile(tests, testConfigFile); + if(tests || light) { + writeTestConfigFile(tests, light, testConfigFile); } tests = tests ? tests : ''; diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts index 9cfde5b2964..0a81b993616 100644 --- a/scripts/processDiagnosticMessages.ts +++ b/scripts/processDiagnosticMessages.ts @@ -55,7 +55,7 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: '// \r\n' + '/// \r\n' + '/* @internal */\r\n' + - 'module ts {\r\n' + + 'namespace ts {\r\n' + ' export var Diagnostics = {\r\n'; var names = Utilities.getObjectKeys(messageTable); for (var i = 0; i < names.length; i++) { diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a0e177e7659..eaad8593eee 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts { +namespace ts { export let bindTime = 0; export const enum ModuleInstanceState { @@ -88,12 +88,20 @@ module ts { let container: Node; let blockScopeContainer: Node; let lastContainer: Node; + + // If this file is an external module, then it is automatically in strict-mode according to + // ES6. If it is not an external module, then we'll determine if it is in strict mode or + // not depending on if we see "use strict" in certain places (or if we hit a class/namespace). + let inStrictMode = !!file.externalModuleIndicator; + let symbolCount = 0; let Symbol = objectAllocator.getSymbolConstructor(); + let classifiableNames: Map = {}; if (!file.locals) { bind(file); file.symbolCount = symbolCount; + file.classifiableNames = classifiableNames; } return; @@ -194,6 +202,11 @@ module ts { symbol = hasProperty(symbolTable, name) ? symbolTable[name] : (symbolTable[name] = createSymbol(SymbolFlags.None, name)); + + if (name && (includes & SymbolFlags.Classifiable)) { + classifiableNames[name] = name; + } + if (symbol.flags & excludes) { if (node.name) { node.name.parent = node; @@ -524,6 +537,51 @@ module ts { typeLiteralSymbol.members = { [symbol.name]: symbol }; } + function bindObjectLiteralExpression(node: ObjectLiteralExpression) { + const enum ElementKind { + Property = 1, + Accessor = 2 + } + + if (inStrictMode) { + let seen: Map = {}; + + for (let prop of node.properties) { + if (prop.name.kind !== SyntaxKind.Identifier) { + continue; + } + + let identifier = prop.name; + + // ECMA-262 11.1.5 Object Initialiser + // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true + // a.This production is contained in strict code and IsDataDescriptor(previous) is true and + // IsDataDescriptor(propId.descriptor) is true. + // b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true. + // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true. + // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true + // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields + let currentKind = prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment || prop.kind === SyntaxKind.MethodDeclaration + ? ElementKind.Property + : ElementKind.Accessor; + + let existingKind = seen[identifier.text]; + if (!existingKind) { + seen[identifier.text] = currentKind; + continue; + } + + if (currentKind === ElementKind.Property && existingKind === ElementKind.Property) { + let span = getErrorSpanForNode(file, identifier); + file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, + Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode)); + } + } + } + + return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object"); + } + function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) { let symbol = createSymbol(symbolFlags, name); addDeclarationToSymbol(symbol, node, symbolFlags); @@ -553,6 +611,138 @@ module ts { bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } + // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized + // check for reserved words used as identifiers in strict mode code. + function checkStrictModeIdentifier(node: Identifier) { + if (inStrictMode && + node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord && + node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord && + !isIdentifierName(node)) { + + // Report error only if there are no parse errors in file + if (!file.parseDiagnostics.length) { + file.bindDiagnostics.push(createDiagnosticForNode(node, + getStrictModeIdentifierMessage(node), declarationNameToString(node))); + } + } + } + + function getStrictModeIdentifierMessage(node: Node) { + // Provide specialized messages to help the user understand why we think they're in + // strict mode. + if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) { + return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode; + } + + if (file.externalModuleIndicator) { + return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode; + } + + return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode; + } + + function checkStrictModeBinaryExpression(node: BinaryExpression) { + if (inStrictMode && isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) { + // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an + // Assignment operator(11.13) or of a PostfixExpression(11.3) + checkStrictModeEvalOrArguments(node, node.left); + } + } + + function checkStrictModeCatchClause(node: CatchClause) { + // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the + // Catch production is eval or arguments + if (inStrictMode && node.variableDeclaration) { + checkStrictModeEvalOrArguments(node, node.variableDeclaration.name); + } + } + + function checkStrictModeDeleteExpression(node: DeleteExpression) { + // Grammar checking + if (inStrictMode && node.expression.kind === SyntaxKind.Identifier) { + // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its + // UnaryExpression is a direct reference to a variable, function argument, or function name + let span = getErrorSpanForNode(file, node.expression); + file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode)); + } + } + + function isEvalOrArgumentsIdentifier(node: Node): boolean { + return node.kind === SyntaxKind.Identifier && + ((node).text === "eval" || (node).text === "arguments"); + } + + function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) { + if (name && name.kind === SyntaxKind.Identifier) { + let identifier = name; + if (isEvalOrArgumentsIdentifier(identifier)) { + // We check first if the name is inside class declaration or class expression; if so give explicit message + // otherwise report generic error message. + let span = getErrorSpanForNode(file, name); + file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, + getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text)); + } + } + } + + function getStrictModeEvalOrArgumentsMessage(node: Node) { + // Provide specialized messages to help the user understand why we think they're in + // strict mode. + if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) { + return Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode; + } + + if (file.externalModuleIndicator) { + return Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode; + } + + return Diagnostics.Invalid_use_of_0_in_strict_mode; + } + + function checkStrictModeFunctionName(node: FunctionLikeDeclaration) { + if (inStrictMode) { + // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1)) + checkStrictModeEvalOrArguments(node, node.name); + } + } + + function checkStrictModeNumericLiteral(node: LiteralExpression) { + if (inStrictMode && node.flags & NodeFlags.OctalLiteral) { + file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode)); + } + } + + function checkStrictModePostfixUnaryExpression(node: PostfixUnaryExpression) { + // Grammar checking + // The identifier eval or arguments may not appear as the LeftHandSideExpression of an + // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression + // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator. + if (inStrictMode) { + checkStrictModeEvalOrArguments(node, node.operand); + } + } + + function checkStrictModePrefixUnaryExpression(node: PrefixUnaryExpression) { + // Grammar checking + if (inStrictMode) { + if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { + checkStrictModeEvalOrArguments(node, node.operand); + } + } + } + + function checkStrictModeWithStatement(node: WithStatement) { + // Grammar checking for withStatement + if (inStrictMode) { + grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode); + } + } + + function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) { + let span = getSpanOfTokenAtPosition(file, node.pos); + file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2)); + } + function getDestructuringParameterName(node: Declaration) { return "__" + indexOf((node.parent).parameters, node); } @@ -560,6 +750,11 @@ module ts { function bind(node: Node) { node.parent = parent; + var savedInStrictMode = inStrictMode; + if (!savedInStrictMode) { + updateStrictMode(node); + } + // First we bind declaration nodes to a symbol if possible. We'll both create a symbol // and then potentially add the symbol to an appropriate symbol table. Possible // destination symbol tables are: @@ -577,10 +772,70 @@ module ts { // the current 'container' node when it changes. This helps us know which symbol table // a local should go into for example. bindChildren(node); + + inStrictMode = savedInStrictMode; + } + + function updateStrictMode(node: Node) { + switch (node.kind) { + case SyntaxKind.SourceFile: + case SyntaxKind.ModuleBlock: + updateStrictModeStatementList((node).statements); + return; + case SyntaxKind.Block: + if (isFunctionLike(node.parent)) { + updateStrictModeStatementList((node).statements); + } + return; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + // All classes are automatically in strict mode in ES6. + inStrictMode = true; + return; + } + } + + function updateStrictModeStatementList(statements: NodeArray) { + for (let statement of statements) { + if (!isPrologueDirective(statement)) { + return; + } + + if (isUseStrictPrologueDirective(statement)) { + inStrictMode = true; + return; + } + } } + /// Should be called only on prologue directives (isPrologueDirective(node) should be true) + function isUseStrictPrologueDirective(node: ExpressionStatement): boolean { + let nodeText = getTextOfNodeFromSourceText(file.text, node.expression); + + // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the + // string to contain unicode escapes (as per ES5). + return nodeText === '"use strict"' || nodeText === "'use strict'"; + } + function bindWorker(node: Node) { switch (node.kind) { + case SyntaxKind.Identifier: + return checkStrictModeIdentifier(node); + case SyntaxKind.BinaryExpression: + return checkStrictModeBinaryExpression(node); + case SyntaxKind.CatchClause: + return checkStrictModeCatchClause(node); + case SyntaxKind.DeleteExpression: + return checkStrictModeDeleteExpression(node); + case SyntaxKind.NumericLiteral: + return checkStrictModeNumericLiteral(node); + case SyntaxKind.PostfixUnaryExpression: + return checkStrictModePostfixUnaryExpression(node); + case SyntaxKind.PrefixUnaryExpression: + return checkStrictModePrefixUnaryExpression(node); + case SyntaxKind.WithStatement: + return checkStrictModeWithStatement(node); + case SyntaxKind.TypeParameter: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); case SyntaxKind.Parameter: @@ -609,6 +864,7 @@ module ts { return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Method | ((node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes); case SyntaxKind.FunctionDeclaration: + checkStrictModeFunctionName(node); return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); case SyntaxKind.Constructor: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Constructor, /*symbolExcludes:*/ SymbolFlags.None); @@ -622,9 +878,10 @@ module ts { case SyntaxKind.TypeLiteral: return bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type"); case SyntaxKind.ObjectLiteralExpression: - return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object"); + return bindObjectLiteralExpression(node); case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: + checkStrictModeFunctionName(node); return bindAnonymousDeclaration(node, SymbolFlags.Function, "__function"); case SyntaxKind.ClassExpression: case SyntaxKind.ClassDeclaration: @@ -661,7 +918,11 @@ module ts { } function bindExportAssignment(node: ExportAssignment) { - if (node.expression.kind === SyntaxKind.Identifier) { + if (!container.symbol || !container.symbol.exports) { + // Export assignment in some sort of block construct + bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)); + } + else if (node.expression.kind === SyntaxKind.Identifier) { // An export default clause with an identifier exports all meanings of that identifier declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); } @@ -672,7 +933,11 @@ module ts { } function bindExportDeclaration(node: ExportDeclaration) { - if (!node.exportClause) { + if (!container.symbol || !container.symbol.exports) { + // Export * in some sort of block construct + bindAnonymousDeclaration(node, SymbolFlags.ExportStar, getDeclarationName(node)); + } + else if (!node.exportClause) { // All export * declarations are collected in an __export symbol declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None); } @@ -722,6 +987,10 @@ module ts { } function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) { + if (inStrictMode) { + checkStrictModeEvalOrArguments(node, node.name) + } + if (!isBindingPattern(node.name)) { if (isBlockOrCatchScoped(node)) { bindBlockScopedVariableDeclaration(node); @@ -745,6 +1014,12 @@ module ts { } function bindParameter(node: ParameterDeclaration) { + if (inStrictMode) { + // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a + // strict mode FunctionLikeDeclaration or FunctionExpression(13.1) + checkStrictModeEvalOrArguments(node, node.name); + } + if (isBindingPattern(node.name)) { bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e0407261e9d..935f5ae3340 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts { +namespace ts { let nextSymbolId = 1; let nextNodeId = 1; let nextMergeId = 1; @@ -3703,7 +3703,7 @@ module ts { // The expression is processed as an identifier expression (section 4.3) // or property access expression(section 4.10), // the widened type(section 3.9) of which becomes the result. - links.resolvedType = getWidenedType(checkExpressionOrQualifiedName(node.exprName)); + links.resolvedType = getWidenedType(checkExpression(node.exprName)); } return links.resolvedType; } @@ -4515,8 +4515,8 @@ module ts { maybeStack[depth][id] = RelationComparisonResult.Succeeded; depth++; let saveExpandingFlags = expandingFlags; - if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack)) expandingFlags |= 1; - if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack)) expandingFlags |= 2; + if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth)) expandingFlags |= 1; + if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth)) expandingFlags |= 2; let result: Ternary; if (expandingFlags === 3) { result = Ternary.Maybe; @@ -4552,27 +4552,6 @@ module ts { return result; } - // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case - // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible, - // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding. - // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at - // some level beyond that. - function isDeeplyNestedGeneric(type: ObjectType, stack: ObjectType[]): boolean { - // We track type references (created by createTypeReference) and instantiated types (created by instantiateType) - if (type.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && depth >= 10) { - let symbol = type.symbol; - let count = 0; - for (let i = 0; i < depth; i++) { - let t = stack[i]; - if (t.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && t.symbol === symbol) { - count++; - if (count >= 10) return true; - } - } - } - return false; - } - function propertiesRelatedTo(source: ObjectType, target: ObjectType, reportErrors: boolean): Ternary { if (relation === identityRelation) { return propertiesIdenticalTo(source, target); @@ -4891,6 +4870,27 @@ module ts { } } + // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case + // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible, + // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding. + // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at + // some level beyond that. + function isDeeplyNestedGeneric(type: Type, stack: Type[], depth: number): boolean { + // We track type references (created by createTypeReference) and instantiated types (created by instantiateType) + if (type.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && depth >= 5) { + let symbol = type.symbol; + let count = 0; + for (let i = 0; i < depth; i++) { + let t = stack[i]; + if (t.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && t.symbol === symbol) { + count++; + if (count >= 5) return true; + } + } + } + return false; + } + function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean { return compareProperties(sourceProp, targetProp, compareTypes) !== Ternary.False; } @@ -5205,21 +5205,6 @@ module ts { return false; } - function isWithinDepthLimit(type: Type, stack: Type[]) { - if (depth >= 5) { - let target = (type).target; - let count = 0; - for (let i = 0; i < depth; i++) { - let t = stack[i]; - if (t.flags & TypeFlags.Reference && (t).target === target) { - count++; - } - } - return count < 5; - } - return true; - } - function inferFromTypes(source: Type, target: Type) { if (source === anyFunctionType) { return; @@ -5287,22 +5272,27 @@ module ts { else if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) || (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral))) { // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members - if (!isInProcess(source, target) && isWithinDepthLimit(source, sourceStack) && isWithinDepthLimit(target, targetStack)) { - if (depth === 0) { - sourceStack = []; - targetStack = []; - } - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; - inferFromProperties(source, target); - inferFromSignatures(source, target, SignatureKind.Call); - inferFromSignatures(source, target, SignatureKind.Construct); - inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String); - inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number); - inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number); - depth--; + if (isInProcess(source, target)) { + return; } + if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { + return; + } + + if (depth === 0) { + sourceStack = []; + targetStack = []; + } + sourceStack[depth] = source; + targetStack[depth] = target; + depth++; + inferFromProperties(source, target); + inferFromSignatures(source, target, SignatureKind.Call); + inferFromSignatures(source, target, SignatureKind.Construct); + inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String); + inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number); + inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number); + depth--; } } @@ -6698,7 +6688,7 @@ module ts { } function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) { - let type = checkExpressionOrQualifiedName(left); + let type = checkExpression(left); if (isTypeAny(type)) { return type; } @@ -6739,7 +6729,7 @@ module ts { ? (node).expression : (node).left; - let type = checkExpressionOrQualifiedName(left); + let type = checkExpression(left); if (type !== unknownType && !isTypeAny(type)) { let prop = getPropertyOfType(getWidenedType(type), propertyName); if (prop && prop.parent && prop.parent.flags & SymbolFlags.Class) { @@ -7325,8 +7315,8 @@ module ts { checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true); } else if (candidateForTypeArgumentError) { - if (!isTaggedTemplate && (node).typeArguments) { - checkTypeArguments(candidateForTypeArgumentError, (node).typeArguments, [], /*reportErrors*/ true) + if (!isTaggedTemplate && typeArguments) { + checkTypeArguments(candidateForTypeArgumentError, typeArguments, [], /*reportErrors*/ true) } else { Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0); @@ -7796,9 +7786,9 @@ module ts { Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); // Grammar checking - let hasGrammarError = checkGrammarDeclarationNameInStrictMode(node) || checkGrammarFunctionLikeDeclaration(node); + let hasGrammarError = checkGrammarFunctionLikeDeclaration(node); if (!hasGrammarError && node.kind === SyntaxKind.FunctionExpression) { - checkGrammarFunctionName(node.name) || checkGrammarForGenerator(node); + checkGrammarForGenerator(node); } // The identityMapper object is used to indicate that function expressions are wildcards @@ -7955,14 +7945,7 @@ module ts { } function checkDeleteExpression(node: DeleteExpression): Type { - // Grammar checking - if (node.parserContextFlags & ParserContextFlags.StrictMode && node.expression.kind === SyntaxKind.Identifier) { - // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its - // UnaryExpression is a direct reference to a variable, function argument, or function name - grammarErrorOnNode(node.expression, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode); - } - - let operandType = checkExpression(node.expression); + checkExpression(node.expression); return booleanType; } @@ -7977,14 +7960,6 @@ module ts { } function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type { - // Grammar checking - // The identifier eval or arguments may not appear as the LeftHandSideExpression of an - // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression - // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator - if ((node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken)) { - checkGrammarEvalOrArgumentsInStrictMode(node, node.operand); - } - let operandType = checkExpression(node.operand); switch (node.operator) { case SyntaxKind.PlusToken: @@ -8011,12 +7986,6 @@ module ts { } function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type { - // Grammar checking - // The identifier eval or arguments may not appear as the LeftHandSideExpression of an - // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression - // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator. - checkGrammarEvalOrArgumentsInStrictMode(node, node.operand); - let operandType = checkExpression(node.operand); let ok = checkArithmeticOperandType(node.operand, operandType, Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type); if (ok) { @@ -8196,13 +8165,6 @@ module ts { } function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) { - // Grammar checking - if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) { - // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an - // Assignment operator(11.13) or of a PostfixExpression(11.3) - checkGrammarEvalOrArgumentsInStrictMode(node, node.left); - } - let operator = node.operatorToken.kind; if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) { return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper); @@ -8515,11 +8477,6 @@ module ts { return type; } - function checkExpression(node: Expression, contextualMapper?: TypeMapper): Type { - checkGrammarIdentifierInStrictMode(node); - return checkExpressionOrQualifiedName(node, contextualMapper); - } - // Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When // contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the // expression is being inferentially typed (section 4.12.2 in spec) and provides the type mapper to use in @@ -8527,7 +8484,7 @@ module ts { // object, it serves as an indicator that all contained function and arrow expressions should be considered to // have the wildcard function type; this form of type check is used during overload resolution to exclude // contextually typed function and arrow expressions in the initial phase. - function checkExpressionOrQualifiedName(node: Expression | QualifiedName, contextualMapper?: TypeMapper): Type { + function checkExpression(node: Expression | QualifiedName, contextualMapper?: TypeMapper): Type { let type: Type; if (node.kind == SyntaxKind.QualifiedName) { type = checkQualifiedName(node); @@ -8631,8 +8588,6 @@ module ts { // DECLARATION AND STATEMENT TYPE CHECKING function checkTypeParameter(node: TypeParameterDeclaration) { - checkGrammarDeclarationNameInStrictMode(node); - // Grammar Checking if (node.expression) { grammarErrorOnFirstToken(node.expression, Diagnostics.Type_expected); @@ -8651,11 +8606,9 @@ module ts { // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code // or if its FunctionBody is strict code(11.1.5). - // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a - // strict mode FunctionLikeDeclaration or FunctionExpression(13.1) // Grammar checking - checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, node.name); + checkGrammarDecorators(node) || checkGrammarModifiers(node); checkVariableLikeDeclaration(node); let func = getContainingFunction(node); @@ -9029,12 +8982,6 @@ module ts { } function checkTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments) { - if (node.kind === SyntaxKind.TypeReference) { - checkGrammarTypeReferenceInStrictMode((node).typeName); - } - else { - checkGrammarExpressionWithTypeArgumentsInStrictMode((node).expression); - } checkGrammarTypeArguments(node, node.typeArguments); let type = getTypeFromTypeReference(node); if (type !== unknownType && node.typeArguments) { @@ -9460,7 +9407,7 @@ module ts { return; } if (shouldCheckIfUnknownType || type.symbol.valueDeclaration) { - checkExpressionOrQualifiedName((node).typeName); + checkExpression((node).typeName); } } } @@ -9546,9 +9493,7 @@ module ts { function checkFunctionDeclaration(node: FunctionDeclaration): void { if (produceDiagnostics) { - checkFunctionLikeDeclaration(node) || - checkGrammarFunctionName(node.name) || - checkGrammarForGenerator(node); + checkFunctionLikeDeclaration(node) || checkGrammarForGenerator(node); checkCollisionWithCapturedSuperVariable(node, node.name); checkCollisionWithCapturedThisVariable(node, node.name); @@ -9557,7 +9502,6 @@ module ts { } function checkFunctionLikeDeclaration(node: FunctionLikeDeclaration): void { - checkGrammarDeclarationNameInStrictMode(node); checkDecorators(node); checkSignatureDeclaration(node); @@ -9843,7 +9787,6 @@ module ts { // Check variable, parameter, or property declaration function checkVariableLikeDeclaration(node: VariableLikeDeclaration) { - checkGrammarDeclarationNameInStrictMode(node); checkDecorators(node); checkSourceElement(node.type); // For a computed property, just check the initializer and exit @@ -10377,12 +10320,7 @@ module ts { } function checkWithStatement(node: WithStatement) { - // Grammar checking for withStatement - if (!checkGrammarStatementInAmbientContext(node)) { - if (node.parserContextFlags & ParserContextFlags.StrictMode) { - grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode); - } - } + checkGrammarStatementInAmbientContext(node); checkExpression(node.expression); error(node.expression, Diagnostics.All_symbols_within_a_with_block_will_be_resolved_to_any); @@ -10486,10 +10424,6 @@ module ts { grammarErrorOnNode(localSymbol.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, identifierName); } } - - // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the - // Catch production is eval or arguments - checkGrammarEvalOrArgumentsInStrictMode(node, catchClause.variableDeclaration.name); } } @@ -10628,7 +10562,6 @@ module ts { } function checkClassDeclaration(node: ClassDeclaration) { - checkGrammarDeclarationNameInStrictMode(node); // Grammar checking if (!node.name && !(node.flags & NodeFlags.Default)) { grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); @@ -10848,7 +10781,7 @@ module ts { function checkInterfaceDeclaration(node: InterfaceDeclaration) { // Grammar checking - checkGrammarDeclarationNameInStrictMode(node) || checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node); + checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node); checkTypeParameters(node.typeParameters); if (produceDiagnostics) { @@ -11072,7 +11005,7 @@ module ts { } // Grammar checking - checkGrammarDeclarationNameInStrictMode(node) || checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node); + checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node); checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0); checkCollisionWithCapturedThisVariable(node, node.name); @@ -11158,7 +11091,16 @@ module ts { function checkModuleDeclaration(node: ModuleDeclaration) { if (produceDiagnostics) { // Grammar checking - if (!checkGrammarDeclarationNameInStrictMode(node) && !checkGrammarDecorators(node) && !checkGrammarModifiers(node)) { + let isAmbientExternalModule = node.name.kind === SyntaxKind.StringLiteral; + let contextErrorMessage = isAmbientExternalModule + ? Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file + : Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module; + if (checkGrammarModuleElementContext(node, contextErrorMessage)) { + // If we hit a module declaration in an illegal context, just bail out to avoid cascading errors. + return; + } + + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node)) { if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) { grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names); } @@ -11194,7 +11136,7 @@ module ts { } // Checks for ambient external modules. - if (node.name.kind === SyntaxKind.StringLiteral) { + if (isAmbientExternalModule) { if (!isGlobalSourceFile(node.parent)) { error(node.name, Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules); } @@ -11270,7 +11212,11 @@ module ts { } function checkImportDeclaration(node: ImportDeclaration) { - if (!checkGrammarImportDeclarationNameInStrictMode(node) && !checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { + if (checkGrammarModuleElementContext(node, Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { + // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. + return; + } + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -11292,7 +11238,12 @@ module ts { } function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) { - checkGrammarDeclarationNameInStrictMode(node) || checkGrammarDecorators(node) || checkGrammarModifiers(node); + if (checkGrammarModuleElementContext(node, Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { + // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. + return; + } + + checkGrammarDecorators(node) || checkGrammarModifiers(node); if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); if (node.flags & NodeFlags.Export) { @@ -11323,9 +11274,15 @@ module ts { } function checkExportDeclaration(node: ExportDeclaration) { + if (checkGrammarModuleElementContext(node, Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) { + // If we hit an export in an illegal context, just bail out to avoid cascading errors. + return; + } + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers); } + if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { if (node.exportClause) { // export { x, y } @@ -11347,6 +11304,12 @@ module ts { } } + function checkGrammarModuleElementContext(node: Statement, errorMessage: DiagnosticMessage): boolean { + if (node.parent.kind !== SyntaxKind.SourceFile && node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.ModuleDeclaration) { + return grammarErrorOnFirstToken(node, errorMessage); + } + } + function checkExportSpecifier(node: ExportSpecifier) { checkAliasSymbol(node); if (!(node.parent.parent).moduleSpecifier) { @@ -11355,6 +11318,11 @@ module ts { } function checkExportAssignment(node: ExportAssignment) { + if (checkGrammarModuleElementContext(node, Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) { + // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors. + return; + } + let container = node.parent.kind === SyntaxKind.SourceFile ? node.parent : node.parent.parent; if (container.kind === SyntaxKind.ModuleDeclaration && (container).name.kind === SyntaxKind.Identifier) { error(node, Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace); @@ -11370,7 +11338,8 @@ module ts { else { checkExpressionCached(node.expression); } - checkExternalModuleExports(container); + + checkExternalModuleExports(container); if (node.isExportEquals && !isInAmbientContext(node)) { if (languageVersion >= ScriptTarget.ES6) { @@ -11384,7 +11353,7 @@ module ts { } } - function getModuleStatements(node: Declaration): ModuleElement[] { + function getModuleStatements(node: Declaration): Statement[] { if (node.kind === SyntaxKind.SourceFile) { return (node).statements; } @@ -11627,7 +11596,9 @@ module ts { function checkSourceFile(node: SourceFile) { let start = new Date().getTime(); + checkSourceFileWorker(node); + checkTime += new Date().getTime() - start; } @@ -11635,6 +11606,8 @@ module ts { function checkSourceFileWorker(node: SourceFile) { let links = getNodeLinks(node); if (!(links.flags & NodeCheckFlags.TypeChecked)) { + // Check whether the file has declared it is the default lib, + // and whether the user has specifically chosen to avoid checking it. if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) { return; } @@ -12636,153 +12609,6 @@ module ts { } // GRAMMAR CHECKING - function isReservedWordInStrictMode(node: Identifier): boolean { - // Check that originalKeywordKind is less than LastFutureReservedWord to see if an Identifier is a strict-mode reserved word - return (node.parserContextFlags & ParserContextFlags.StrictMode) && - (SyntaxKind.FirstFutureReservedWord <= node.originalKeywordKind && node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord); - } - - function reportStrictModeGrammarErrorInClassDeclaration(identifier: Identifier, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { - // We are checking if this name is inside class declaration or class expression (which are under class definitions inside ES6 spec.) - // if so, we would like to give more explicit invalid usage error. - if (getAncestor(identifier, SyntaxKind.ClassDeclaration) || getAncestor(identifier, SyntaxKind.ClassExpression)) { - return grammarErrorOnNode(identifier, message, arg0); - } - return false; - } - - function checkGrammarImportDeclarationNameInStrictMode(node: ImportDeclaration): boolean { - // Check if the import declaration used strict-mode reserved word in its names bindings - if (node.importClause) { - let impotClause = node.importClause; - if (impotClause.namedBindings) { - let nameBindings = impotClause.namedBindings; - if (nameBindings.kind === SyntaxKind.NamespaceImport) { - let name = (nameBindings).name; - if (isReservedWordInStrictMode(name)) { - let nameText = declarationNameToString(name); - return grammarErrorOnNode(name, Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); - } - } - else if (nameBindings.kind === SyntaxKind.NamedImports) { - let reportError = false; - for (let element of (nameBindings).elements) { - let name = element.name; - if (isReservedWordInStrictMode(name)) { - let nameText = declarationNameToString(name); - reportError = reportError || grammarErrorOnNode(name, Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); - } - } - return reportError; - } - } - } - return false; - } - - function checkGrammarDeclarationNameInStrictMode(node: Declaration): boolean { - let name = node.name; - if (name && name.kind === SyntaxKind.Identifier && isReservedWordInStrictMode(name)) { - let nameText = declarationNameToString(name); - switch (node.kind) { - case SyntaxKind.Parameter: - case SyntaxKind.VariableDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.TypeParameter: - case SyntaxKind.BindingElement: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.EnumDeclaration: - return checkGrammarIdentifierInStrictMode(name); - - case SyntaxKind.ClassDeclaration: - // Report an error if the class declaration uses strict-mode reserved word. - return grammarErrorOnNode(name, Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode, nameText); - - case SyntaxKind.ModuleDeclaration: - // Report an error if the module declaration uses strict-mode reserved word. - // TODO(yuisu): fix this when having external module in strict mode - return grammarErrorOnNode(name, Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); - - case SyntaxKind.ImportEqualsDeclaration: - // TODO(yuisu): fix this when having external module in strict mode - return grammarErrorOnNode(name, Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); - } - } - return false; - } - - function checkGrammarTypeReferenceInStrictMode(typeName: Identifier | QualifiedName) { - // Check if the type reference is using strict mode keyword - // Example: - // class C { - // foo(x: public){} // Error. - // } - if (typeName.kind === SyntaxKind.Identifier) { - checkGrammarTypeNameInStrictMode(typeName); - } - // Report an error for each identifier in QualifiedName - // Example: - // foo (x: B.private.bar) // error at private - // foo (x: public.private.package) // error at public, private, and package - else if (typeName.kind === SyntaxKind.QualifiedName) { - // Walk from right to left and report a possible error at each Identifier in QualifiedName - // Example: - // x1: public.private.package // error at public and private - checkGrammarTypeNameInStrictMode((typeName).right); - checkGrammarTypeReferenceInStrictMode((typeName).left); - } - } - - // This function will report an error for every identifier in property access expression - // whether it violates strict mode reserved words. - // Example: - // public // error at public - // public.private.package // error at public - // B.private.B // no error - function checkGrammarExpressionWithTypeArgumentsInStrictMode(expression: Expression) { - // Example: - // class C extends public // error at public - if (expression && expression.kind === SyntaxKind.Identifier) { - return checkGrammarIdentifierInStrictMode(expression); - } - else if (expression && expression.kind === SyntaxKind.PropertyAccessExpression) { - // Walk from left to right in PropertyAccessExpression until we are at the left most expression - // in PropertyAccessExpression. According to grammar production of MemberExpression, - // the left component expression is a PrimaryExpression (i.e. Identifier) while the other - // component after dots can be IdentifierName. - checkGrammarExpressionWithTypeArgumentsInStrictMode((expression).expression); - } - - } - - // The function takes an identifier itself or an expression which has SyntaxKind.Identifier. - function checkGrammarIdentifierInStrictMode(node: Expression | Identifier, nameText?: string): boolean { - if (node && node.kind === SyntaxKind.Identifier && isReservedWordInStrictMode(node)) { - if (!nameText) { - nameText = declarationNameToString(node); - } - - // TODO (yuisu): Fix when module is a strict mode - let errorReport = reportStrictModeGrammarErrorInClassDeclaration(node, Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode, nameText)|| - grammarErrorOnNode(node, Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); - return errorReport; - } - return false; - } - - // The function takes an identifier when uses as a typeName in TypeReferenceNode - function checkGrammarTypeNameInStrictMode(node: Identifier): boolean { - if (node && node.kind === SyntaxKind.Identifier && isReservedWordInStrictMode(node)) { - let nameText = declarationNameToString(node); - - // TODO (yuisu): Fix when module is a strict mode - let errorReport = reportStrictModeGrammarErrorInClassDeclaration(node, Diagnostics.Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode, nameText) || - grammarErrorOnNode(node, Diagnostics.Type_expected_0_is_a_reserved_word_in_strict_mode, nameText); - return errorReport; - } - return false; - } function checkGrammarDecorators(node: Node): boolean { if (!node.decorators) { @@ -13202,11 +13028,6 @@ module ts { } } - function checkGrammarFunctionName(name: Node) { - // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1)) - return checkGrammarEvalOrArgumentsInStrictMode(name, name); - } - function checkGrammarForInvalidQuestionMark(node: Declaration, questionToken: Node, message: DiagnosticMessage): boolean { if (questionToken) { return grammarErrorOnNode(questionToken, message); @@ -13219,7 +13040,6 @@ module ts { let GetAccessor = 2; let SetAccesor = 4; let GetOrSetAccessor = GetAccessor | SetAccesor; - let inStrictMode = (node.parserContextFlags & ParserContextFlags.StrictMode) !== 0; for (let prop of node.properties) { let name = prop.name; @@ -13266,9 +13086,7 @@ module ts { else { let existingKind = seen[(name).text]; if (currentKind === Property && existingKind === Property) { - if (inStrictMode) { - grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); - } + continue; } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { @@ -13491,9 +13309,6 @@ module ts { return grammarErrorAtPos(getSourceFileOfNode(node), node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer); } } - // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code - // and its Identifier is eval or arguments - return checkGrammarEvalOrArgumentsInStrictMode(node, node.name); } function checkGrammarVariableDeclaration(node: VariableDeclaration) { @@ -13525,8 +13340,7 @@ module ts { // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code // and its Identifier is eval or arguments - return (checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name)) || - checkGrammarEvalOrArgumentsInStrictMode(node, node.name); + return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name); } function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean { @@ -13665,29 +13479,6 @@ module ts { } } - function checkGrammarEvalOrArgumentsInStrictMode(contextNode: Node, name: Node): boolean { - if (name && name.kind === SyntaxKind.Identifier) { - let identifier = name; - if (contextNode && (contextNode.parserContextFlags & ParserContextFlags.StrictMode) && isEvalOrArgumentsIdentifier(identifier)) { - let nameText = declarationNameToString(identifier); - - // We check first if the name is inside class declaration or class expression; if so give explicit message - // otherwise report generic error message. - // reportGrammarErrorInClassDeclaration only return true if grammar error is successfully reported and false otherwise - let reportErrorInClassDeclaration = reportStrictModeGrammarErrorInClassDeclaration(identifier, Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode, nameText); - if (!reportErrorInClassDeclaration){ - return grammarErrorOnNode(identifier, Diagnostics.Invalid_use_of_0_in_strict_mode, nameText); - } - return reportErrorInClassDeclaration; - } - } - } - - function isEvalOrArgumentsIdentifier(node: Node): boolean { - return node.kind === SyntaxKind.Identifier && - ((node).text === "eval" || (node).text === "arguments"); - } - function checkGrammarConstructorTypeParameters(node: ConstructorDeclaration) { if (node.typeParameters) { return grammarErrorAtPos(getSourceFileOfNode(node), node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration); @@ -13797,13 +13588,8 @@ module ts { function checkGrammarNumericLiteral(node: Identifier): boolean { // Grammar checking - if (node.flags & NodeFlags.OctalLiteral) { - if (node.parserContextFlags & ParserContextFlags.StrictMode) { - return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode); - } - else if (languageVersion >= ScriptTarget.ES5) { - return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher); - } + if (node.flags & NodeFlags.OctalLiteral && languageVersion >= ScriptTarget.ES5) { + return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher); } } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index a3065bd7a4b..07bccf4a5ef 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -3,7 +3,7 @@ /// /// -module ts { +namespace ts { /* @internal */ export var optionDeclarations: CommandLineOption[] = [ { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index dde1e3d6b57..0c0414f3b12 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts { +namespace ts { // Ternary values are defined such that // x & y is False if either x or y is False. // x & y is Maybe if either x or y is Maybe, but neither x or y is False. diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 5c705f18190..a2edc632de3 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts { +namespace ts { interface ModuleElementDeclarationEmitInfo { node: Node; outputPos: number; diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 7d61a4bb6cd..2eada488a68 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -1,7 +1,7 @@ // /// /* @internal */ -module ts { +namespace ts { export var Diagnostics = { Unterminated_string_literal: { code: 1002, category: DiagnosticCategory.Error, key: "Unterminated string literal." }, Identifier_expected: { code: 1003, category: DiagnosticCategory.Error, key: "Identifier expected." }, @@ -171,8 +171,8 @@ module ts { A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" }, Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode" }, Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1213, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, - Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" }, - Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, + Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode: { code: 1214, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode." }, + Invalid_use_of_0_Modules_are_automatically_in_strict_mode: { code: 1215, category: DiagnosticCategory.Error, key: "Invalid use of '{0}'. Modules are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, Generators_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 1220, category: DiagnosticCategory.Error, key: "Generators are only available when targeting ECMAScript 6 or higher." }, @@ -186,6 +186,11 @@ module ts { A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: { code: 1228, category: DiagnosticCategory.Error, key: "A type predicate is only allowed in return type position for functions and methods." }, A_type_predicate_cannot_reference_a_rest_parameter: { code: 1229, category: DiagnosticCategory.Error, key: "A type predicate cannot reference a rest parameter." }, A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: { code: 1230, category: DiagnosticCategory.Error, key: "A type predicate cannot reference element '{0}' in a binding pattern." }, + An_export_assignment_can_only_be_used_in_a_module: { code: 1231, category: DiagnosticCategory.Error, key: "An export assignment can only be used in a module." }, + An_import_declaration_can_only_be_used_in_a_namespace_or_module: { code: 1232, category: DiagnosticCategory.Error, key: "An import declaration can only be used in a namespace or module." }, + An_export_declaration_can_only_be_used_in_a_module: { code: 1233, category: DiagnosticCategory.Error, key: "An export declaration can only be used in a module." }, + An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: { code: 1234, category: DiagnosticCategory.Error, key: "An ambient module declaration is only allowed at the top level in a file." }, + A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: { code: 1235, category: DiagnosticCategory.Error, key: "A namespace declaration is only allowed in a namespace or module." }, 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 89171ca1753..dae42d20e27 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -671,14 +671,14 @@ "category": "Error", "code": 1213 }, - "Type expected. '{0}' is a reserved word in strict mode": { + "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode.": { + "category": "Error", + "code": 1214 + }, + "Invalid use of '{0}'. Modules are automatically in strict mode.": { "category": "Error", "code": 1215 }, - "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode.": { - "category": "Error", - "code": 1216 - }, "Export assignment is not supported when '--module' flag is 'system'.": { "category": "Error", "code": 1218 @@ -731,6 +731,26 @@ "category": "Error", "code": 1230 }, + "An export assignment can only be used in a module.": { + "category": "Error", + "code": 1231 + }, + "An import declaration can only be used in a namespace or module.": { + "category": "Error", + "code": 1232 + }, + "An export declaration can only be used in a module.": { + "category": "Error", + "code": 1233 + }, + "An ambient module declaration is only allowed at the top level in a file.": { + "category": "Error", + "code": 1234 + }, + "A namespace declaration is only allowed in a namespace or module.": { + "category": "Error", + "code": 1235 + }, "Duplicate identifier '{0}'.": { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index df40d10ddf1..8081668f98c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2,7 +2,7 @@ /// /* @internal */ -module ts { +namespace ts { export function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) { return isExternalModule(sourceFile) || isDeclarationFile(sourceFile); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 394bb0f401d..a507125d4bb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1,7 +1,7 @@ /// /// -module ts { +namespace ts { let nodeConstructors = new Array Node>(SyntaxKind.Count); /* @internal */ export let parseTime = 0; @@ -495,13 +495,6 @@ module ts { // attached to the EOF token. let parseErrorBeforeNextFinishedNode: boolean = false; - export const enum StatementFlags { - None = 0, - Statement = 1, - ModuleElement = 2, - StatementOrModuleElement = Statement | ModuleElement - } - export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): SourceFile { initializeState(fileName, _sourceText, languageVersion, _syntaxCursor); @@ -551,7 +544,7 @@ module ts { token = nextToken(); processReferenceComments(sourceFile); - sourceFile.statements = parseList(ParsingContext.SourceElements, /*checkForStrictMode*/ true, parseSourceElement); + sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement); Debug.assert(token === SyntaxKind.EndOfFileToken); sourceFile.endOfFileToken = parseTokenNode(); @@ -654,10 +647,6 @@ module ts { } } - function setStrictModeContext(val: boolean) { - setContextFlag(val, ParserContextFlags.StrictMode); - } - function setDisallowInContext(val: boolean) { setContextFlag(val, ParserContextFlags.DisallowIn); } @@ -751,10 +740,6 @@ module ts { return (contextFlags & ParserContextFlags.Yield) !== 0; } - function inStrictModeContext() { - return (contextFlags & ParserContextFlags.StrictMode) !== 0; - } - function inGeneratorParameterContext() { return (contextFlags & ParserContextFlags.GeneratorParameter) !== 0; } @@ -1129,17 +1114,14 @@ module ts { switch (parsingContext) { case ParsingContext.SourceElements: - case ParsingContext.ModuleElements: + case ParsingContext.BlockStatements: + case ParsingContext.SwitchClauseStatements: // If we're in error recovery, then we don't want to treat ';' as an empty statement. // The problem is that ';' can show up in far too many contexts, and if we see one // and assume it's a statement, then we may bail out inappropriately from whatever // we're parsing. For example, if we have a semicolon in the middle of a class, then // we really don't want to assume the class is over and we're on a statement in the // outer module. We just want to consume and move on. - return !(token === SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfModuleElement(); - case ParsingContext.BlockStatements: - case ParsingContext.SwitchClauseStatements: - // During error recovery we don't treat empty statements as statements return !(token === SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfStatement(); case ParsingContext.SwitchClauses: return token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword; @@ -1250,7 +1232,6 @@ module ts { } switch (kind) { - case ParsingContext.ModuleElements: case ParsingContext.BlockStatements: case ParsingContext.SwitchClauses: case ParsingContext.TypeMembers: @@ -1334,31 +1315,17 @@ module ts { } // Parses a list of elements - function parseList(kind: ParsingContext, checkForStrictMode: boolean, parseElement: () => T): NodeArray { + function parseList(kind: ParsingContext, parseElement: () => T): NodeArray { let saveParsingContext = parsingContext; parsingContext |= 1 << kind; let result = >[]; result.pos = getNodePos(); - let savedStrictModeContext = inStrictModeContext(); while (!isListTerminator(kind)) { if (isListElement(kind, /* inErrorRecovery */ false)) { let element = parseListElement(kind, parseElement); result.push(element); - // test elements only if we are not already in strict mode - if (checkForStrictMode && !inStrictModeContext()) { - if (isPrologueDirective(element)) { - if (isUseStrictPrologueDirective(element)) { - setStrictModeContext(true); - checkForStrictMode = false; - } - } - else { - checkForStrictMode = false; - } - } - continue; } @@ -1367,22 +1334,11 @@ module ts { } } - setStrictModeContext(savedStrictModeContext); result.end = getNodeEnd(); parsingContext = saveParsingContext; return result; } - /// Should be called only on prologue directives (isPrologueDirective(node) should be true) - function isUseStrictPrologueDirective(node: Node): boolean { - Debug.assert(isPrologueDirective(node)); - let nodeText = getTextOfNodeFromSourceText(sourceText, (node).expression); - - // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the - // string to contain unicode escapes (as per ES5). - return nodeText === '"use strict"' || nodeText === "'use strict'"; - } - function parseListElement(parsingContext: ParsingContext, parseElement: () => T): T { let node = currentNode(parsingContext); if (node) { @@ -1461,15 +1417,13 @@ module ts { function canReuseNode(node: Node, parsingContext: ParsingContext): boolean { switch (parsingContext) { - case ParsingContext.ModuleElements: - return isReusableModuleElement(node); - case ParsingContext.ClassMembers: return isReusableClassMember(node); case ParsingContext.SwitchClauses: return isReusableSwitchClause(node); + case ParsingContext.SourceElements: case ParsingContext.BlockStatements: case ParsingContext.SwitchClauseStatements: return isReusableStatement(node); @@ -1532,26 +1486,6 @@ module ts { return false; } - function isReusableModuleElement(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ExportAssignment: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.EnumDeclaration: - return true; - } - - return isReusableStatement(node); - } - - return false; - } - function isReusableClassMember(node: Node) { if (node) { switch (node.kind) { @@ -1604,6 +1538,15 @@ module ts { case SyntaxKind.LabeledStatement: case SyntaxKind.DoStatement: case SyntaxKind.DebuggerStatement: + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.ExportDeclaration: + case SyntaxKind.ExportAssignment: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.TypeAliasDeclaration: return true; } } @@ -1677,8 +1620,7 @@ module ts { function parsingContextErrors(context: ParsingContext): DiagnosticMessage { switch (context) { case ParsingContext.SourceElements: return Diagnostics.Declaration_or_statement_expected; - case ParsingContext.ModuleElements: return Diagnostics.Declaration_or_statement_expected; - case ParsingContext.BlockStatements: return Diagnostics.Statement_expected; + case ParsingContext.BlockStatements: return Diagnostics.Declaration_or_statement_expected; case ParsingContext.SwitchClauses: return Diagnostics.case_or_default_expected; case ParsingContext.SwitchClauseStatements: return Diagnostics.Statement_expected; case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected; @@ -1795,26 +1737,26 @@ module ts { } function parseRightSideOfDot(allowIdentifierNames: boolean): Identifier { - // Technically a keyword is valid here as all keywords are identifier names. - // However, often we'll encounter this in error situations when the keyword + // Technically a keyword is valid here as all identifiers and keywords are identifier names. + // However, often we'll encounter this in error situations when the identifier or keyword // is actually starting another valid construct. // // So, we check for the following specific case: // // name. - // keyword identifierNameOrKeyword + // identifierOrKeyword identifierNameOrKeyword // // Note: the newlines are important here. For example, if that above code // were rewritten into: // - // name.keyword + // name.identifierOrKeyword // identifierNameOrKeyword // // Then we would consider it valid. That's because ASI would take effect and - // the code would be implicitly: "name.keyword; identifierNameOrKeyword". + // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword". // In the first case though, ASI will not take effect because there is not a - // line terminator after the keyword. - if (scanner.hasPrecedingLineBreak() && scanner.isReservedWord()) { + // line terminator after the identifier or keyword. + if (scanner.hasPrecedingLineBreak() && isIdentifierOrKeyword()) { let matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); if (matchesPattern) { @@ -2301,7 +2243,7 @@ module ts { function parseObjectTypeMembers(): NodeArray { let members: NodeArray; if (parseExpected(SyntaxKind.OpenBraceToken)) { - members = parseList(ParsingContext.TypeMembers, /*checkForStrictMode*/ false, parseTypeMember); + members = parseList(ParsingContext.TypeMembers, parseTypeMember); parseExpected(SyntaxKind.CloseBraceToken); } else { @@ -2670,12 +2612,6 @@ module ts { return true; } - if (inStrictModeContext()) { - // If we're in strict mode, then 'yield' is a keyword, could only ever start - // a yield expression. - return true; - } - // We're in a context where 'yield expr' is not allowed. However, if we can // definitely tell that the user was trying to parse a 'yield expr' and not // just a normal expr that start with a 'yield' identifier, then parse out @@ -2690,7 +2626,7 @@ module ts { // for now we just check if the next token is an identifier. More heuristics // can be added here later as necessary. We just need to make sure that we // don't accidently consume something legal. - return lookAhead(nextTokenIsIdentifierOnSameLine); + return lookAhead(nextTokenIsIdentifierOrKeywordOrNumberOnSameLine); } return false; @@ -3533,10 +3469,10 @@ module ts { } // STATEMENTS - function parseBlock(ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean, diagnosticMessage?: DiagnosticMessage): Block { + function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block { let node = createNode(SyntaxKind.Block); if (parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage) || ignoreMissingOpenBrace) { - node.statements = parseList(ParsingContext.BlockStatements, checkForStrictMode, parseStatement); + node.statements = parseList(ParsingContext.BlockStatements, parseStatement); parseExpected(SyntaxKind.CloseBraceToken); } else { @@ -3556,7 +3492,7 @@ module ts { setDecoratorContext(false); } - let block = parseBlock(ignoreMissingOpenBrace, /*checkForStrictMode*/ true, diagnosticMessage); + let block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage); if (saveDecoratorContext) { setDecoratorContext(true); @@ -3698,7 +3634,7 @@ module ts { parseExpected(SyntaxKind.CaseKeyword); node.expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.ColonToken); - node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement); + node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); return finishNode(node); } @@ -3706,7 +3642,7 @@ module ts { let node = createNode(SyntaxKind.DefaultClause); parseExpected(SyntaxKind.DefaultKeyword); parseExpected(SyntaxKind.ColonToken); - node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement); + node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); return finishNode(node); } @@ -3722,7 +3658,7 @@ module ts { parseExpected(SyntaxKind.CloseParenToken); let caseBlock = createNode(SyntaxKind.CaseBlock, scanner.getStartPos()); parseExpected(SyntaxKind.OpenBraceToken); - caseBlock.clauses = parseList(ParsingContext.SwitchClauses, /*checkForStrictMode*/ false, parseCaseOrDefaultClause); + caseBlock.clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause); parseExpected(SyntaxKind.CloseBraceToken); node.caseBlock = finishNode(caseBlock); return finishNode(node); @@ -3749,14 +3685,14 @@ module ts { let node = createNode(SyntaxKind.TryStatement); parseExpected(SyntaxKind.TryKeyword); - node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false, /*checkForStrictMode*/ false); + node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); node.catchClause = token === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; // If we don't have a catch clause, then we must have a finally clause. Try to parse // one out no matter what. if (!node.catchClause || token === SyntaxKind.FinallyKeyword) { parseExpected(SyntaxKind.FinallyKeyword); - node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false, /*checkForStrictMode*/ false); + node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); } return finishNode(node); @@ -3770,7 +3706,7 @@ module ts { } parseExpected(SyntaxKind.CloseParenToken); - result.block = parseBlock(/*ignoreMissingOpenBrace*/ false, /*checkForStrictMode*/ false); + result.block = parseBlock(/*ignoreMissingOpenBrace*/ false); return finishNode(result); } @@ -3811,7 +3747,12 @@ module ts { return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); } - function parseDeclarationFlags(): StatementFlags { + function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() { + nextToken(); + return (isIdentifierOrKeyword() || token === SyntaxKind.NumericLiteral) && !scanner.hasPrecedingLineBreak(); + } + + function isDeclaration(): boolean { while (true) { switch (token) { case SyntaxKind.VarKeyword: @@ -3820,7 +3761,7 @@ module ts { case SyntaxKind.FunctionKeyword: case SyntaxKind.ClassKeyword: case SyntaxKind.EnumKeyword: - return StatementFlags.Statement; + return true; // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers; // however, an identifier cannot be followed by another identifier on the same line. This is what we @@ -3845,28 +3786,27 @@ module ts { // could be legal, it would add complexity for very little gain. case SyntaxKind.InterfaceKeyword: case SyntaxKind.TypeKeyword: - return nextTokenIsIdentifierOnSameLine() ? StatementFlags.Statement : StatementFlags.None; + return nextTokenIsIdentifierOnSameLine(); case SyntaxKind.ModuleKeyword: case SyntaxKind.NamespaceKeyword: - return nextTokenIsIdentifierOrStringLiteralOnSameLine() ? StatementFlags.ModuleElement : StatementFlags.None; + return nextTokenIsIdentifierOrStringLiteralOnSameLine(); case SyntaxKind.DeclareKeyword: nextToken(); // ASI takes effect for this modifier. if (scanner.hasPrecedingLineBreak()) { - return StatementFlags.None; + return false; } continue; case SyntaxKind.ImportKeyword: nextToken(); return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken || - token === SyntaxKind.OpenBraceToken || isIdentifierOrKeyword() ? - StatementFlags.ModuleElement : StatementFlags.None; + token === SyntaxKind.OpenBraceToken || isIdentifierOrKeyword(); case SyntaxKind.ExportKeyword: nextToken(); if (token === SyntaxKind.EqualsToken || token === SyntaxKind.AsteriskToken || token === SyntaxKind.OpenBraceToken || token === SyntaxKind.DefaultKeyword) { - return StatementFlags.ModuleElement; + return true; } continue; case SyntaxKind.PublicKeyword: @@ -3876,16 +3816,16 @@ module ts { nextToken(); continue; default: - return StatementFlags.None; + return false; } } } - function getDeclarationFlags(): StatementFlags { - return lookAhead(parseDeclarationFlags); + function isStartOfDeclaration(): boolean { + return lookAhead(isDeclaration); } - function getStatementFlags(): StatementFlags { + function isStartOfStatement(): boolean { switch (token) { case SyntaxKind.AtToken: case SyntaxKind.SemicolonToken: @@ -3911,12 +3851,12 @@ module ts { // however, we say they are here so that we may gracefully parse them and error later. case SyntaxKind.CatchKeyword: case SyntaxKind.FinallyKeyword: - return StatementFlags.Statement; + return true; case SyntaxKind.ConstKeyword: case SyntaxKind.ExportKeyword: case SyntaxKind.ImportKeyword: - return getDeclarationFlags(); + return isStartOfDeclaration(); case SyntaxKind.DeclareKeyword: case SyntaxKind.InterfaceKeyword: @@ -3924,7 +3864,7 @@ module ts { case SyntaxKind.NamespaceKeyword: case SyntaxKind.TypeKeyword: // When these don't start a declaration, they're an identifier in an expression statement - return getDeclarationFlags() || StatementFlags.Statement; + return true; case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: @@ -3932,52 +3872,30 @@ module ts { case SyntaxKind.StaticKeyword: // When these don't start a declaration, they may be the start of a class member if an identifier // immediately follows. Otherwise they're an identifier in an expression statement. - return getDeclarationFlags() || - (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? StatementFlags.None : StatementFlags.Statement); + return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); default: - return isStartOfExpression() ? StatementFlags.Statement : StatementFlags.None; + return isStartOfExpression(); } } - function isStartOfStatement(): boolean { - return (getStatementFlags() & StatementFlags.Statement) !== 0; - } - - function isStartOfModuleElement(): boolean { - return (getStatementFlags() & StatementFlags.StatementOrModuleElement) !== 0; - } - - function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { + function nextTokenIsIdentifierOrStartOfDestructuring() { nextToken(); - return !scanner.hasPrecedingLineBreak() && - (isIdentifier() || token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken); + return isIdentifier() || token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken; } function isLetDeclaration() { - // It is let declaration if in strict mode or next token is identifier\open bracket\open curly on same line. - // otherwise it needs to be treated like identifier - return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); + // In ES6 'let' always starts a lexical declaration if followed by an identifier or { + // or [. + return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring); } function parseStatement(): Statement { - return parseModuleElementOfKind(StatementFlags.Statement); - } - - function parseModuleElement(): ModuleElement { - return parseModuleElementOfKind(StatementFlags.StatementOrModuleElement); - } - - function parseSourceElement(): ModuleElement { - return parseModuleElementOfKind(StatementFlags.StatementOrModuleElement); - } - - function parseModuleElementOfKind(flags: StatementFlags): ModuleElement { switch (token) { case SyntaxKind.SemicolonToken: return parseEmptyStatement(); case SyntaxKind.OpenBraceToken: - return parseBlock(/*ignoreMissingOpenBrace*/ false, /*checkForStrictMode*/ false); + return parseBlock(/*ignoreMissingOpenBrace*/ false); case SyntaxKind.VarKeyword: return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined); case SyntaxKind.LetKeyword: @@ -4032,7 +3950,7 @@ module ts { case SyntaxKind.ProtectedKeyword: case SyntaxKind.PublicKeyword: case SyntaxKind.StaticKeyword: - if (getDeclarationFlags() & flags) { + if (isStartOfDeclaration()) { return parseDeclaration(); } break; @@ -4040,7 +3958,7 @@ module ts { return parseExpressionOrLabeledStatement(); } - function parseDeclaration(): ModuleElement { + function parseDeclaration(): Statement { let fullStart = getNodePos(); let decorators = parseDecorators(); let modifiers = parseModifiers(); @@ -4073,7 +3991,7 @@ module ts { if (decorators) { // We reached this point because we encountered decorators and/or modifiers and assumed a declaration // would follow. For recovery and error reporting purposes, return an incomplete declaration. - let node = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); + let node = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); node.pos = fullStart; node.decorators = decorators; setModifiers(node, modifiers); @@ -4495,10 +4413,6 @@ module ts { } function parseClassDeclarationOrExpression(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray, kind: SyntaxKind): ClassLikeDeclaration { - // In ES6 specification, All parts of a ClassDeclaration or a ClassExpression are strict mode code - let savedStrictModeContext = inStrictModeContext(); - setStrictModeContext(true); - var node = createNode(kind, fullStart); node.decorators = decorators; setModifiers(node, modifiers); @@ -4521,9 +4435,7 @@ module ts { node.members = createMissingList(); } - var finishedNode = finishNode(node); - setStrictModeContext(savedStrictModeContext); - return finishedNode; + return finishNode(node); } function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray { @@ -4541,7 +4453,7 @@ module ts { } function parseHeritageClausesWorker() { - return parseList(ParsingContext.HeritageClauses, /*checkForStrictMode*/ false, parseHeritageClause); + return parseList(ParsingContext.HeritageClauses, parseHeritageClause); } function parseHeritageClause() { @@ -4571,7 +4483,7 @@ module ts { } function parseClassMembers() { - return parseList(ParsingContext.ClassMembers, /*checkForStrictMode*/ false, parseClassElement); + return parseList(ParsingContext.ClassMembers, parseClassElement); } function parseInterfaceDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): InterfaceDeclaration { @@ -4629,7 +4541,7 @@ module ts { function parseModuleBlock(): ModuleBlock { let node = createNode(SyntaxKind.ModuleBlock, scanner.getStartPos()); if (parseExpected(SyntaxKind.OpenBraceToken)) { - node.statements = parseList(ParsingContext.ModuleElements, /*checkForStrictMode*/ false, parseModuleElement); + node.statements = parseList(ParsingContext.BlockStatements, parseStatement); parseExpected(SyntaxKind.CloseBraceToken); } else { @@ -4957,7 +4869,6 @@ module ts { const enum ParsingContext { SourceElements, // Elements in source file - ModuleElements, // Elements in module declaration BlockStatements, // Statements in block SwitchClauses, // Clauses in switch statement SwitchClauseStatements, // Statements in switch clause diff --git a/src/compiler/program.ts b/src/compiler/program.ts index c09b70a0c6d..562654c2ed0 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1,7 +1,7 @@ /// /// -module ts { +namespace ts { /* @internal */ export let programTime = 0; /* @internal */ export let emitTime = 0; /* @internal */ export let ioReadTime = 0; @@ -144,20 +144,30 @@ module ts { let program: Program; let files: SourceFile[] = []; let diagnostics = createDiagnosticCollection(); - let skipDefaultLib = options.noLib; + let commonSourceDirectory: string; let diagnosticsProducingTypeChecker: TypeChecker; let noDiagnosticsTypeChecker: TypeChecker; + let classifiableNames: Map; + + let skipDefaultLib = options.noLib; let start = new Date().getTime(); host = host || createCompilerHost(options); + let filesByName = createFileMap(fileName => host.getCanonicalFileName(fileName)); forEach(rootNames, name => processRootFile(name, /*isDefaultLib:*/ false)); + + // Do not process the default library if: + // - The '--noLib' flag is used. + // - A 'no-default-lib' reference comment is encountered in + // processing the root files. if (!skipDefaultLib) { processRootFile(host.getDefaultLibFileName(options), /*isDefaultLib:*/ true); } + verifyCompilerOptions(); programTime += new Date().getTime() - start; @@ -172,6 +182,7 @@ module ts { getDeclarationDiagnostics, getCompilerOptionsDiagnostics, getTypeChecker, + getClassifiableNames, getDiagnosticsProducingTypeChecker, getCommonSourceDirectory: () => commonSourceDirectory, emit, @@ -183,6 +194,20 @@ module ts { }; return program; + function getClassifiableNames() { + if (!classifiableNames) { + // Initialize a checker so that all our files are bound. + getTypeChecker(); + classifiableNames = {}; + + for (let sourceFile of files) { + copyMap(sourceFile.classifiableNames, classifiableNames); + } + } + + return classifiableNames; + } + function getEmitHost(writeFileCallback?: WriteFileCallback): EmitHost { return { getCanonicalFileName: fileName => host.getCanonicalFileName(fileName), @@ -335,14 +360,17 @@ module ts { } } else { - if (options.allowNonTsExtensions && !findSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd)) { - diagnostic = Diagnostics.File_0_not_found; - diagnosticArgument = [fileName]; - } - else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, isDefaultLib, refFile, refPos, refEnd))) { - diagnostic = Diagnostics.File_0_not_found; - fileName += ".ts"; - diagnosticArgument = [fileName]; + var nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd); + if (!nonTsFile) { + if (options.allowNonTsExtensions) { + diagnostic = Diagnostics.File_0_not_found; + diagnosticArgument = [fileName]; + } + else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, isDefaultLib, refFile, refPos, refEnd))) { + diagnostic = Diagnostics.File_0_not_found; + fileName += ".ts"; + diagnosticArgument = [fileName]; + } } } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index d7e65dff81c..fd8883045fe 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1,7 +1,7 @@ /// /// -module ts { +namespace ts { export interface ErrorCallback { (message: DiagnosticMessage, length: number): void; } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 75e8af357bb..a47d6959ba8 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1,6 +1,6 @@ /// -module ts { +namespace ts { export interface System { args: string[]; newLine: string; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 15cc665e351..2903c3a31f4 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -1,7 +1,7 @@ /// /// -module ts { +namespace ts { export interface SourceFile { fileWatcher: FileWatcher; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 177aaf10af0..c39426a2e22 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1,4 +1,4 @@ -module ts { +namespace ts { export interface Map { [index: string]: T; } @@ -362,10 +362,6 @@ module ts { export const enum ParserContextFlags { None = 0, - // Set if this node was parsed in strict mode. Used for grammar error checks, as well as - // checking if the node can be reused in incremental settings. - StrictMode = 1 << 0, - // If this node was parsed in a context where 'in-expressions' are not allowed. DisallowIn = 1 << 1, @@ -388,7 +384,7 @@ module ts { JavaScriptFile = 1 << 6, // Context flags set directly by the parser. - ParserGeneratedFlags = StrictMode | DisallowIn | Yield | GeneratorParameter | Decorator | ThisNodeHasError, + ParserGeneratedFlags = DisallowIn | Yield | GeneratorParameter | Decorator | ThisNodeHasError, // Context flags computed by aggregating child flags upwards. @@ -808,7 +804,7 @@ module ts { expression: UnaryExpression; } - export interface Statement extends Node, ModuleElement { + export interface Statement extends Node { _statementBrand: any; } @@ -911,10 +907,6 @@ module ts { block: Block; } - export interface ModuleElement extends Node { - _moduleElementBrand: any; - } - export interface ClassLikeDeclaration extends Declaration { name?: Identifier; typeParameters?: NodeArray; @@ -962,16 +954,16 @@ module ts { members: NodeArray; } - export interface ModuleDeclaration extends Declaration, ModuleElement { + export interface ModuleDeclaration extends Declaration, Statement { name: Identifier | LiteralExpression; body: ModuleBlock | ModuleDeclaration; } - export interface ModuleBlock extends Node, ModuleElement { - statements: NodeArray + export interface ModuleBlock extends Node, Statement { + statements: NodeArray } - export interface ImportEqualsDeclaration extends Declaration, ModuleElement { + export interface ImportEqualsDeclaration extends Declaration, Statement { name: Identifier; // 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external @@ -987,7 +979,7 @@ module ts { // import "mod" => importClause = undefined, moduleSpecifier = "mod" // In rest of the cases, module specifier is string literal corresponding to module // ImportClause information is shown at its declaration below. - export interface ImportDeclaration extends ModuleElement { + export interface ImportDeclaration extends Statement { importClause?: ImportClause; moduleSpecifier: Expression; } @@ -1007,7 +999,7 @@ module ts { name: Identifier; } - export interface ExportDeclaration extends Declaration, ModuleElement { + export interface ExportDeclaration extends Declaration, Statement { exportClause?: NamedExports; moduleSpecifier?: Expression; } @@ -1027,7 +1019,7 @@ module ts { export type ImportSpecifier = ImportOrExportSpecifier; export type ExportSpecifier = ImportOrExportSpecifier; - export interface ExportAssignment extends Declaration, ModuleElement { + export interface ExportAssignment extends Declaration, Statement { isExportEquals?: boolean; expression: Expression; } @@ -1143,7 +1135,7 @@ module ts { // Source files are declarations when they are external modules. export interface SourceFile extends Declaration { - statements: NodeArray; + statements: NodeArray; endOfFileToken: Node; fileName: string; @@ -1153,6 +1145,14 @@ module ts { moduleName: string; referencedFiles: FileReference[]; + /** + * lib.d.ts should have a reference comment like + * + * /// + * + * If any other file has this comment, it signals not to include lib.d.ts + * because this containing file is intended to act as a default library. + */ hasNoDefaultLib: boolean; languageVersion: ScriptTarget; @@ -1176,6 +1176,8 @@ module ts { // Stores a line map for the file. // This field should never be used directly to obtain line map, use getLineMap function instead. /* @internal */ lineMap: number[]; + + /* @internal */ classifiableNames?: Map; } export interface ScriptReferenceHost { @@ -1227,6 +1229,8 @@ module ts { // language service). /* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker; + /* @internal */ getClassifiableNames(): Map; + /* @internal */ getNodeCount(): number; /* @internal */ getIdentifierCount(): number; /* @internal */ getSymbolCount(): number; @@ -1523,6 +1527,11 @@ module ts { PropertyOrAccessor = Property | Accessor, Export = ExportNamespace | ExportType | ExportValue, + + /* @internal */ + // The set of things we consider semantically classifiable. Used to speed up the LS during + // classification. + Classifiable = Class | Enum | TypeAlias | Interface | TypeParameter | Module, } export interface Symbol { @@ -1853,7 +1862,10 @@ module ts { experimentalDecorators?: boolean; emitDecoratorMetadata?: boolean; /* @internal */ stripInternal?: boolean; + + // Skip checking lib.d.ts to help speed up tests. /* @internal */ skipDefaultLibCheck?: boolean; + [option: string]: string | number | boolean; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 799f9efb44d..dc55b9fac5f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts { +namespace ts { export interface ReferencePathMatchResult { fileReference?: FileReference diagnosticMessage?: DiagnosticMessage @@ -1178,6 +1178,41 @@ module ts { return false; } + // Return true if the given identifier is classified as an IdentifierName + export function isIdentifierName(node: Identifier): boolean { + let parent = node.parent; + switch (parent.kind) { + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.EnumMember: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.PropertyAccessExpression: + // Name in member declaration or property name in property access + return (parent).name === node; + case SyntaxKind.QualifiedName: + // Name on right hand side of dot in a type query + if ((parent).right === node) { + while (parent.kind === SyntaxKind.QualifiedName) { + parent = parent.parent; + } + return parent.kind === SyntaxKind.TypeQuery; + } + return false; + case SyntaxKind.BindingElement: + case SyntaxKind.ImportSpecifier: + // Property name in binding element or import specifier + return (parent).propertyName === node; + case SyntaxKind.ExportSpecifier: + // Any name in an export specifier + return true; + } + return false; + } + // An alias symbol is created by one of the following declarations: // import = ... // import from ... @@ -2009,7 +2044,7 @@ module ts { } } -module ts { +namespace ts { export function getDefaultLibFileName(options: CompilerOptions): string { return options.target === ScriptTarget.ES6 ? "lib.es6.d.ts" : "lib.d.ts"; } diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index b6997e705b9..21e88b9e41a 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -1,7 +1,6 @@ /// /// /// -/// const enum CompilerTestType { Conformance, @@ -18,7 +17,7 @@ class CompilerBaselineRunner extends RunnerBase { public options: string; - constructor(public testType?: CompilerTestType) { + constructor(public testType: CompilerTestType) { super(); this.errors = true; this.emit = true; @@ -171,7 +170,6 @@ class CompilerBaselineRunner extends RunnerBase { } }); - it('Correct JS output for ' + fileName, () => { if (!ts.fileExtensionIs(lastUnit.name, '.d.ts') && this.emit) { if (result.files.length === 0 && result.errors.length === 0) { @@ -195,8 +193,6 @@ class CompilerBaselineRunner extends RunnerBase { jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n'; jsCode += getByteOrderMarkText(result.files[i]); jsCode += result.files[i].code; - // Re-enable this if we want to do another comparison of old vs new compiler baselines - // jsCode += SyntacticCleaner.clean(result.files[i].code); } if (result.declFilesCode.length > 0) { diff --git a/src/harness/exec.ts b/src/harness/exec.ts deleted file mode 100644 index 6ed538b1d40..00000000000 --- a/src/harness/exec.ts +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -// Allows for executing a program with command-line arguments and reading the result -interface IExec { - exec: (fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) => void; -} - -class ExecResult { - public stdout = ""; - public stderr = ""; - public exitCode: number; -} - -class WindowsScriptHostExec implements IExec { - public exec(fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) : void { - var result = new ExecResult(); - var shell = new ActiveXObject('WScript.Shell'); - try { - var process = shell.Exec(fileName + ' ' + cmdLineArgs.join(' ')); - } catch(e) { - result.stderr = e.message; - result.exitCode = 1; - handleResult(result); - return; - } - // Wait for it to finish running - while (process.Status != 0) { /* todo: sleep? */ } - - - result.exitCode = process.ExitCode; - if(!process.StdOut.AtEndOfStream) result.stdout = process.StdOut.ReadAll(); - if(!process.StdErr.AtEndOfStream) result.stderr = process.StdErr.ReadAll(); - - handleResult(result); - } -} - -class NodeExec implements IExec { - public exec(fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) : void { - var nodeExec = require('child_process').exec; - - var result = new ExecResult(); - result.exitCode = null; - var cmdLine = fileName + ' ' + cmdLineArgs.join(' '); - var process = nodeExec(cmdLine, function(error: any, stdout: string, stderr: string) { - result.stdout = stdout; - result.stderr = stderr; - result.exitCode = error ? error.code : 0; - handleResult(result); - }); - } -} - -var Exec: IExec = function() : IExec { - var global = Function("return this;").call(null); - if(typeof global.ActiveXObject !== "undefined") { - return new WindowsScriptHostExec(); - } else { - return new NodeExec(); - } -}(); \ No newline at end of file diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 8d313c9a1a6..bf6e120ec3c 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -343,7 +343,8 @@ module FourSlash { if (!resolvedResult.isLibFile) { this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text); } - } else { + } + else { // resolveReference file-option is not specified then do not resolve any files and include all inputFiles ts.forEachKey(this.inputFiles, fileName => { if (!Harness.isLibraryFile(fileName)) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 82afea4cf4d..6a559488150 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -99,7 +99,7 @@ module Utils { } try { - var content = ts.sys.readFile(Harness.userSpecifiedroot + path); + var content = ts.sys.readFile(Harness.userSpecifiedRoot + path); } catch (err) { return undefined; @@ -732,7 +732,8 @@ module Harness { } // Settings - export var userSpecifiedroot = ""; + export let userSpecifiedRoot = ""; + export let lightMode = false; /** Functionality for compiling TypeScript code */ export module Compiler { @@ -809,17 +810,19 @@ module Harness { } export function createSourceFileAndAssertInvariants( - fileName: string, - sourceText: string, - languageVersion: ts.ScriptTarget, - assertInvariants: boolean) { - + fileName: string, + sourceText: string, + languageVersion: ts.ScriptTarget) { + // We'll only assert invariants outside of light mode. + const shouldAssertInvariants = !Harness.lightMode; + // Only set the parent nodes if we're asserting invariants. We don't need them otherwise. - var result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ assertInvariants); + var result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants); - if (assertInvariants) { + if (shouldAssertInvariants) { Utils.assertInvariants(result, /*parent:*/ undefined); } + return result; } @@ -827,8 +830,8 @@ module Harness { const lineFeed = "\n"; export var defaultLibFileName = 'lib.d.ts'; - export var defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest, /*assertInvariants:*/ true); - export var defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest, /*assertInvariants:*/ true); + export var defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest); + export var defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest); // Cache these between executions so we don't have to re-parse them for every test export var fourslashFileName = 'fourslash.ts'; @@ -859,7 +862,7 @@ module Harness { function register(file: { unitName: string; content: string; }) { if (file.content !== undefined) { var fileName = ts.normalizePath(file.unitName); - filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget, /*assertInvariants:*/ true); + filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget); } }; inputFiles.forEach(register); @@ -882,7 +885,7 @@ module Harness { } else if (fn === fourslashFileName) { var tsFn = 'tests/cases/fourslash/' + fourslashFileName; - fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget, /*assertInvariants:*/ true); + fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget); return fourslashSourceFile; } else { @@ -939,17 +942,19 @@ module Harness { } public emitAll(ioHost?: IEmitterIOHost) { - this.compileFiles(this.inputFiles, [],(result) => { - result.files.forEach(file => { - ioHost.writeFile(file.fileName, file.code, false); - }); - result.declFilesCode.forEach(file => { - ioHost.writeFile(file.fileName, file.code, false); - }); - result.sourceMaps.forEach(file => { - ioHost.writeFile(file.fileName, file.code, false); - }); - },() => { }, this.compileOptions); + this.compileFiles(this.inputFiles, + /*otherFiles*/ [], + /*onComplete*/ result => { + result.files.forEach(writeFile); + result.declFilesCode.forEach(writeFile); + result.sourceMaps.forEach(writeFile); + }, + /*settingsCallback*/ () => { }, + this.compileOptions); + + function writeFile(file: GeneratedFile) { + ioHost.writeFile(file.fileName, file.code, false); + } } public compileFiles(inputFiles: { unitName: string; content: string }[], @@ -958,8 +963,7 @@ module Harness { settingsCallback?: (settings: ts.CompilerOptions) => void, options?: ts.CompilerOptions, // Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file - currentDirectory?: string, - assertInvariants = true) { + currentDirectory?: string) { options = options || { noResolve: false }; options.target = options.target || ts.ScriptTarget.ES3; @@ -979,7 +983,31 @@ module Harness { var includeBuiltFiles: { unitName: string; content: string }[] = []; var useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames; - this.settings.forEach(setting => { + this.settings.forEach(setCompilerOptionForSetting); + + var fileOutputs: GeneratedFile[] = []; + + var programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName); + + var compilerHost = createCompilerHost( + inputFiles.concat(includeBuiltFiles).concat(otherFiles), + (fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }), + options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine); + var program = ts.createProgram(programFiles, options, compilerHost); + + var emitResult = program.emit(); + + var errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); + this.lastErrors = errors; + + var result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps); + onComplete(result, program); + + // reset what newline means in case the last test changed it + ts.sys.newLine = newLine; + return options; + + function setCompilerOptionForSetting(setting: Harness.TestCaseParser.CompilerSetting) { switch (setting.flag.toLowerCase()) { // "fileName", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noimplicitany", "noresolve" case "module": @@ -1133,7 +1161,7 @@ module Harness { case 'inlinesourcemap': options.inlineSourceMap = setting.value === 'true'; break; - + case 'inlinesources': options.inlineSources = setting.value === 'true'; break; @@ -1141,28 +1169,7 @@ module Harness { default: throw new Error('Unsupported compiler setting ' + setting.flag); } - }); - - var fileOutputs: GeneratedFile[] = []; - - var programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName); - var compilerHost = createCompilerHost( - inputFiles.concat(includeBuiltFiles).concat(otherFiles), - (fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }), - options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine); - var program = ts.createProgram(programFiles, options, compilerHost); - - var emitResult = program.emit(); - - var errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); - this.lastErrors = errors; - - var result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps); - onComplete(result, program); - - // reset what newline means in case the last test changed it - ts.sys.newLine = newLine; - return options; + } } public compileDeclarationFiles(inputFiles: { unitName: string; content: string; }[], @@ -1363,29 +1370,30 @@ module Harness { ts.sys.newLine + ts.sys.newLine + outputLines.join('\r\n'); } - export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[], clean?: (s: string) => string) { + export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string { // Collect, test, and sort the fileNames - function cleanName(fn: string) { - var lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/'); - return fn.substr(lastSlash + 1).toLowerCase(); - } outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName))); // Emit them var result = ''; - ts.forEach(outputFiles, outputFile => { + for (let outputFile of outputFiles) { // Some extra spacing if this isn't the first file - if (result.length) result = result + '\r\n\r\n'; + if (result.length) { + result += '\r\n\r\n'; + } // FileName header + content - result = result + '/*====== ' + outputFile.fileName + ' ======*/\r\n'; - if (clean) { - result = result + clean(outputFile.code); - } else { - result = result + outputFile.code; - } - }); + result += '/*====== ' + outputFile.fileName + ' ======*/\r\n'; + + result += outputFile.code; + } + return result; + + function cleanName(fn: string) { + var lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/'); + return fn.substr(lastSlash + 1).toLowerCase(); + } } /** The harness' compiler instance used when tests are actually run. Reseting or changing settings of this compiler instance must be done within a test case (i.e., describe/it) */ @@ -1487,16 +1495,6 @@ module Harness { // Regex for parsing options in the format "@Alpha: Value of any sort" var optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines - // List of allowed metadata names - var fileMetadataNames = ["filename", "comments", "declaration", "module", - "nolib", "sourcemap", "target", "out", "outdir", "noemithelpers", "noemitonerror", - "noimplicitany", "noresolve", "newline", "normalizenewline", "emitbom", - "errortruncation", "usecasesensitivefilenames", "preserveconstenums", - "includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal", - "isolatedmodules", "inlinesourcemap", "maproot", "sourceroot", - "inlinesources", "emitdecoratormetadata", "experimentaldecorators", - "skipdefaultlibcheck"]; - function extractCompilerSettings(content: string): CompilerSetting[] { var opts: CompilerSetting[] = []; @@ -1530,10 +1528,8 @@ module Harness { if (testMetaData) { // Comment line, check for global/file @options and record them optionRegex.lastIndex = 0; - var fileNameIndex = fileMetadataNames.indexOf(testMetaData[1].toLowerCase()); - if (fileNameIndex === -1) { - throw new Error('Unrecognized metadata name "' + testMetaData[1] + '". Available file metadata names are: ' + fileMetadataNames.join(', ')); - } else if (fileNameIndex === 0) { + var metaDataName = testMetaData[1].toLowerCase(); + if (metaDataName === "filename") { currentFileOptions[testMetaData[1]] = testMetaData[2]; } else { continue; @@ -1619,9 +1615,9 @@ module Harness { function baselinePath(fileName: string, type: string, baselineFolder: string, subfolder?: string) { if (subfolder !== undefined) { - return Harness.userSpecifiedroot + baselineFolder + '/' + subfolder + '/' + type + '/' + fileName; + return Harness.userSpecifiedRoot + baselineFolder + '/' + subfolder + '/' + type + '/' + fileName; } else { - return Harness.userSpecifiedroot + baselineFolder + '/' + type + '/' + fileName; + return Harness.userSpecifiedRoot + baselineFolder + '/' + type + '/' + fileName; } } @@ -1730,7 +1726,7 @@ module Harness { } export function getDefaultLibraryFile(): { unitName: string, content: string } { - var libFile = Harness.userSpecifiedroot + Harness.libFolder + "/" + "lib.d.ts"; + var libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts"; return { unitName: libFile, content: IO.readFile(libFile) diff --git a/src/harness/project.ts b/src/harness/project.ts deleted file mode 100644 index d94cbd576d5..00000000000 --- a/src/harness/project.ts +++ /dev/null @@ -1,19 +0,0 @@ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -/// -/// -/// -/// diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index cb454c00e6a..324524272e0 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -174,7 +174,7 @@ class ProjectRunner extends RunnerBase { else { var text = getSourceFileText(fileName); if (text !== undefined) { - sourceFile = Harness.Compiler.createSourceFileAndAssertInvariants(fileName, text, languageVersion, /*assertInvariants:*/ true); + sourceFile = Harness.Compiler.createSourceFileAndAssertInvariants(fileName, text, languageVersion); } } diff --git a/src/harness/runner.ts b/src/harness/runner.ts index eae4d77bb2c..42c2d5667c4 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -18,6 +18,7 @@ /// /// /// +/// function runTests(runners: RunnerBase[]) { for (var i = iterations; i > 0; i--) { @@ -39,6 +40,9 @@ var testConfigFile = if (testConfigFile !== '') { var testConfig = JSON.parse(testConfigFile); + if (testConfig.light) { + Harness.lightMode = true; + } if (testConfig.test && testConfig.test.length > 0) { for (let option of testConfig.test) { diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 49ca796448a..269e889704c 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -12,7 +12,7 @@ class RunnerBase { } public enumerateFiles(folder: string, regex?: RegExp, options?: { recursive: boolean }): string[] { - return Harness.IO.listFiles(Harness.userSpecifiedroot + folder, regex, { recursive: (options ? options.recursive : false) }); + return Harness.IO.listFiles(Harness.userSpecifiedRoot + folder, regex, { recursive: (options ? options.recursive : false) }); } /** Setup the runner's tests so that they are ready to be executed by the harness diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 49a15112e9f..43a118b6aec 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// @@ -75,7 +74,7 @@ module RWC { }); // Add files to compilation - for(let fileRead of ioLog.filesRead) { + for (let fileRead of ioLog.filesRead) { // Check if the file is already added into the set of input files. var resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path)); var inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath); @@ -107,14 +106,14 @@ module RWC { opts.options.noLib = true; // Emit the results - compilerOptions = harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => { - compilerResult = compileResult; - }, + compilerOptions = harnessCompiler.compileFiles( + inputFiles, + otherFiles, + newCompilerResults => { compilerResult = newCompilerResults; }, /*settingsCallback*/ undefined, opts.options, - // Since all Rwc json file specified current directory in its json file, we need to pass this information to compilerHost - // so that when the host is asked for current directory, it should give the value from json rather than from process - currentDirectory, - /*assertInvariants:*/ false); + // Since each RWC json file specifies its current directory in its json file, we need + // to pass this information in explicitly instead of acquiring it from the process. + currentDirectory); }); function getHarnessCompilerInputUnit(fileName: string) { @@ -132,7 +131,7 @@ module RWC { it('has the expected emitted code', () => { Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => { - return Harness.Compiler.collateOutputs(compilerResult.files, s => SyntacticCleaner.clean(s)); + return Harness.Compiler.collateOutputs(compilerResult.files); }, false, baselineOpts); }); diff --git a/src/harness/syntacticCleaner.ts b/src/harness/syntacticCleaner.ts deleted file mode 100644 index 05b42951246..00000000000 --- a/src/harness/syntacticCleaner.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Use this to get emitter-agnostic baselines - -class SyntacticCleaner { - static clean(sourceFileContents: string) { - return sourceFileContents; - } -} - -/* TODO: Re-implement or maybe delete -class SyntacticCleaner extends TypeScript.SyntaxWalker { - private emit: string[] = []; - - public visitToken(token: TypeScript.ISyntaxToken): void { - this.emit.push(token.text()); - if (token.kind() === TypeScript.SyntaxKind.SemicolonToken) { - this.emit.push('\r\n'); - } else { - this.emit.push(' '); - - } - } - - static clean(sourceFileContents: string): string { - var parsed = TypeScript.Parser.parse('_emitted.ts', TypeScript.SimpleText.fromString(sourceFileContents), TypeScript.LanguageVersion.EcmaScript5, false); - var cleaner = new SyntacticCleaner(); - cleaner.visitSourceUnit(parsed.sourceUnit()); - return cleaner.emit.join(''); - } -} -*/ diff --git a/src/harness/test262Runner.ts b/src/harness/test262Runner.ts index 0091da5e911..5f8250c5e23 100644 --- a/src/harness/test262Runner.ts +++ b/src/harness/test262Runner.ts @@ -1,6 +1,5 @@ /// /// -/// class Test262BaselineRunner extends RunnerBase { private static basePath = 'internal/cases/test262'; @@ -65,7 +64,7 @@ class Test262BaselineRunner extends RunnerBase { it('has the expected emitted code', () => { Harness.Baseline.runBaseline('has the expected emitted code', testState.filename + '.output.js', () => { var files = testState.compilerResult.files.filter(f=> f.fileName !== Test262BaselineRunner.helpersFilePath); - return Harness.Compiler.collateOutputs(files, s => SyntacticCleaner.clean(s)); + return Harness.Compiler.collateOutputs(files); }, false, Test262BaselineRunner.baselineOptions); }); diff --git a/src/lib/core.d.ts b/src/lib/core.d.ts index c03ab344ab2..78971965664 100644 --- a/src/lib/core.d.ts +++ b/src/lib/core.d.ts @@ -1150,7 +1150,7 @@ interface ArrayConstructor { (arrayLength?: number): any[]; (arrayLength: number): T[]; (...items: T[]): T[]; - isArray(arg: any): boolean; + isArray(arg: any): arg is Array; prototype: Array; } diff --git a/src/server/client.ts b/src/server/client.ts index f1c5e424d47..3546f8339ee 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -1,6 +1,6 @@ /// -module ts.server { +namespace ts.server { export interface SessionClientHost extends LanguageServiceHost { writeMessage(message: string): void; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index bc9e685825c..9e235e2cc7d 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -4,7 +4,7 @@ /// /// -module ts.server { +namespace ts.server { export interface Logger { close(): void; isVerbose(): boolean; diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index ef9ad7984f6..336bc11c9f3 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -1,7 +1,7 @@ /** * Declaration module describing the TypeScript Server protocol */ -declare module ts.server.protocol { +declare namespace ts.server.protocol { /** * A TypeScript Server message */ diff --git a/src/server/server.ts b/src/server/server.ts index 828deca2b2d..b4b35edd3f3 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -1,7 +1,7 @@ /// /// -module ts.server { +namespace ts.server { var nodeproto: typeof NodeJS._debugger = require('_debugger'); var readline: NodeJS.ReadLine = require('readline'); var path: NodeJS.Path = require('path'); diff --git a/src/server/session.ts b/src/server/session.ts index a4cb3e59b4e..f9cfb4f9f7d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -4,7 +4,7 @@ /// /// -module ts.server { +namespace ts.server { var spaceCache:string[] = []; interface StackTraceError extends Error { diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 41079c08201..4d3d7d331a5 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -4,7 +4,7 @@ /// /* @internal */ -module ts.BreakpointResolver { +namespace ts.BreakpointResolver { /** * Get the breakpoint span in given sourceFile */ diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index ef25d23a5c9..011f7d7fa5e 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -4,7 +4,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export interface TextRangeWithKind extends TextRange { kind: SyntaxKind; diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts index 84c09b86bb9..c9b9952a49e 100644 --- a/src/services/formatting/formattingContext.ts +++ b/src/services/formatting/formattingContext.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export class FormattingContext { public currentTokenSpan: TextRangeWithKind; public nextTokenSpan: TextRangeWithKind; diff --git a/src/services/formatting/formattingRequestKind.ts b/src/services/formatting/formattingRequestKind.ts index 4bdc83ffd45..d0397e4a8d9 100644 --- a/src/services/formatting/formattingRequestKind.ts +++ b/src/services/formatting/formattingRequestKind.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export const enum FormattingRequestKind { FormatDocument, FormatSelection, diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index e09b5dfba92..7e77878051c 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -2,7 +2,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); export interface FormattingScanner { @@ -224,7 +224,7 @@ module ts.formatting { } function isOnToken(): boolean { - let current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken(); + let current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken(); let startPos = (lastTokenInfo && lastTokenInfo.token.pos) || scanner.getStartPos(); return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current); } diff --git a/src/services/formatting/rule.ts b/src/services/formatting/rule.ts index f1bb39e69c2..543295f364f 100644 --- a/src/services/formatting/rule.ts +++ b/src/services/formatting/rule.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export class Rule { constructor( public Descriptor: RuleDescriptor, diff --git a/src/services/formatting/ruleAction.ts b/src/services/formatting/ruleAction.ts index e5734b1a03c..13e9043e1c6 100644 --- a/src/services/formatting/ruleAction.ts +++ b/src/services/formatting/ruleAction.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export const enum RuleAction { Ignore = 0x00000001, Space = 0x00000002, diff --git a/src/services/formatting/ruleDescriptor.ts b/src/services/formatting/ruleDescriptor.ts index f3492715f3a..96506adc3dc 100644 --- a/src/services/formatting/ruleDescriptor.ts +++ b/src/services/formatting/ruleDescriptor.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export class RuleDescriptor { constructor(public LeftTokenRange: Shared.TokenRange, public RightTokenRange: Shared.TokenRange) { } diff --git a/src/services/formatting/ruleFlag.ts b/src/services/formatting/ruleFlag.ts index 4e6e002c184..7619f232ad4 100644 --- a/src/services/formatting/ruleFlag.ts +++ b/src/services/formatting/ruleFlag.ts @@ -2,7 +2,7 @@ /* @internal */ -module ts.formatting { +namespace ts.formatting { export const enum RuleFlags { None, CanDeleteNewLines diff --git a/src/services/formatting/ruleOperation.ts b/src/services/formatting/ruleOperation.ts index 1cca437e491..e897513bd27 100644 --- a/src/services/formatting/ruleOperation.ts +++ b/src/services/formatting/ruleOperation.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export class RuleOperation { public Context: RuleOperationContext; public Action: RuleAction; diff --git a/src/services/formatting/ruleOperationContext.ts b/src/services/formatting/ruleOperationContext.ts index 69ed3453a75..515250d7264 100644 --- a/src/services/formatting/ruleOperationContext.ts +++ b/src/services/formatting/ruleOperationContext.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export class RuleOperationContext { private customContextChecks: { (context: FormattingContext): boolean; }[]; diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 9cf6d8ff4bc..c10e3ee69ea 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export class Rules { public getRuleName(rule: Rule) { let o: ts.Map = this; @@ -193,7 +193,7 @@ module ts.formatting { // Insert space after function keyword for anonymous functions public SpaceAfterAnonymousFunctionKeyword: Rule; public NoSpaceAfterAnonymousFunctionKeyword: Rule; - + // Insert space after @ in decorator public SpaceBeforeAt: Rule; public NoSpaceAfterAt: Rule; @@ -470,8 +470,9 @@ module ts.formatting { switch (context.contextNode.kind) { case SyntaxKind.BinaryExpression: case SyntaxKind.ConditionalExpression: + case SyntaxKind.TypePredicate: return true; - + // equals in binding elements: function foo([[x, y] = [1, 2]]) case SyntaxKind.BindingElement: // equals in type X = ... diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts index 5aae6f40fcd..4f231bd842e 100644 --- a/src/services/formatting/rulesMap.ts +++ b/src/services/formatting/rulesMap.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export class RulesMap { public map: RulesBucket[]; public mapRowLength: number; diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts index 0867bcf31c0..bd8f4fc3a5e 100644 --- a/src/services/formatting/rulesProvider.ts +++ b/src/services/formatting/rulesProvider.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export class RulesProvider { private globalRules: Rules; private options: ts.FormatCodeOptions; diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 9cd28a40a54..a82e57f050f 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export module SmartIndenter { const enum Value { diff --git a/src/services/formatting/tokenRange.ts b/src/services/formatting/tokenRange.ts index 712d6f3792e..27a43280f2c 100644 --- a/src/services/formatting/tokenRange.ts +++ b/src/services/formatting/tokenRange.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.formatting { +namespace ts.formatting { export module Shared { export interface ITokenAccess { GetTokens(): SyntaxKind[]; @@ -112,7 +112,7 @@ module ts.formatting { static AnyIncludingMultilineComments = TokenRange.FromTokens(TokenRange.Any.GetTokens().concat([SyntaxKind.MultiLineCommentTrivia])); static Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword); static BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator); - static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword]); + static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.IsKeyword]); static UnaryPrefixOperators = TokenRange.FromTokens([SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]); static UnaryPrefixExpressions = TokenRange.FromTokens([SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); static UnaryPreincrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index aec3bdf765f..a4cc7ec2ad5 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -1,5 +1,5 @@ /* @internal */ -module ts.NavigateTo { +namespace ts.NavigateTo { type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration }; export function getNavigateToItems(program: Program, cancellationToken: CancellationTokenObject, searchValue: string, maxResultCount: number): NavigateToItem[] { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 8acdbac20c5..ead9bc519ce 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -1,7 +1,7 @@ /// /* @internal */ -module ts.NavigationBar { +namespace ts.NavigationBar { export function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[] { // If the source file has any child items, then it included in the tree // and takes lexical ownership of all other top-level items. diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index d413f611209..08b089cd75e 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -1,5 +1,5 @@ /* @internal */ -module ts { +namespace ts { export module OutliningElementsCollector { export function collectElements(sourceFile: SourceFile): OutliningSpan[] { let elements: OutliningSpan[] = []; diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index 88cd9fdbb0f..d56c7fac975 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -1,5 +1,5 @@ /* @internal */ -module ts { +namespace ts { // Note(cyrusn): this enum is ordered from strongest match type to weakest match type. export enum PatternMatchKind { exact, diff --git a/src/services/services.ts b/src/services/services.ts index 0ed67f322ac..9d57ff75679 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -10,7 +10,7 @@ /// /// -module ts { +namespace ts { /** The version of the language service API */ export let servicesVersion = "0.4" @@ -5993,6 +5993,7 @@ module ts { let typeChecker = program.getTypeChecker(); let result: number[] = []; + let classifiableNames = program.getClassifiableNames(); processNode(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6005,6 +6006,9 @@ module ts { function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning): ClassificationType { let flags = symbol.getFlags(); + if ((flags & SymbolFlags.Classifiable) === SymbolFlags.None) { + return; + } if (flags & SymbolFlags.Class) { return ClassificationType.className; @@ -6047,13 +6051,20 @@ module ts { function processNode(node: Node) { // Only walk into nodes that intersect the requested span. - if (node && textSpanIntersectsWith(span, node.getStart(), node.getWidth())) { - if (node.kind === SyntaxKind.Identifier && node.getWidth() > 0) { - let symbol = typeChecker.getSymbolAtLocation(node); - if (symbol) { - let type = classifySymbol(symbol, getMeaningFromLocation(node)); - if (type) { - pushClassification(node.getStart(), node.getWidth(), type); + if (node && textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) { + if (node.kind === SyntaxKind.Identifier && !nodeIsMissing(node)) { + let identifier = node; + + // Only bother calling into the typechecker if this is an identifier that + // could possibly resolve to a type name. This makes classification run + // in a third of the time it would normally take. + if (classifiableNames[identifier.text]) { + let symbol = typeChecker.getSymbolAtLocation(node); + if (symbol) { + let type = classifySymbol(symbol, getMeaningFromLocation(node)); + if (type) { + pushClassification(node.getStart(), node.getWidth(), type); + } } } } diff --git a/src/services/shims.ts b/src/services/shims.ts index 004393fb3b5..9a586a1ec12 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -19,7 +19,7 @@ var debugObjectHost = (this); /* @internal */ -module ts { +namespace ts { export interface ScriptSnapshotShim { /** Gets a portion of the script snapshot specified by [start, end). */ getText(start: number, end: number): string; @@ -246,16 +246,22 @@ module ts { export class LanguageServiceShimHostAdapter implements LanguageServiceHost { private files: string[]; + private loggingEnabled = false; + private tracingEnabled = false; constructor(private shimHost: LanguageServiceShimHost) { } public log(s: string): void { - this.shimHost.log(s); + if (this.loggingEnabled) { + this.shimHost.log(s); + } } public trace(s: string): void { - this.shimHost.trace(s); + if (this.tracingEnabled) { + this.shimHost.trace(s); + } } public error(s: string): void { @@ -349,15 +355,15 @@ module ts { } } - function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, noPerfLogging: boolean): any { - if (!noPerfLogging) { + function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): any { + if (logPerformance) { logger.log(actionDescription); var start = Date.now(); } var result = action(); - if (!noPerfLogging) { + if (logPerformance) { var end = Date.now(); logger.log(actionDescription + " completed in " + (end - start) + " msec"); if (typeof (result) === "string") { @@ -372,9 +378,9 @@ module ts { return result; } - function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any, noPerfLogging: boolean): string { + function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): string { try { - var result = simpleForwardCall(logger, actionDescription, action, noPerfLogging); + var result = simpleForwardCall(logger, actionDescription, action, logPerformance); return JSON.stringify({ result: result }); } catch (err) { @@ -413,6 +419,7 @@ module ts { class LanguageServiceShimObject extends ShimBase implements LanguageServiceShim { private logger: Logger; + private logPerformance = false; constructor(factory: ShimFactory, private host: LanguageServiceShimHost, @@ -422,7 +429,7 @@ module ts { } public forwardJSONCall(actionDescription: string, action: () => any): string { - return forwardJSONCall(this.logger, actionDescription, action, /*noPerfLogging:*/ false); + return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance); } /// DISPOSE @@ -811,6 +818,7 @@ module ts { class ClassifierShimObject extends ShimBase implements ClassifierShim { public classifier: Classifier; + private logPerformance = false; constructor(factory: ShimFactory, private logger: Logger) { super(factory); @@ -820,7 +828,7 @@ module ts { public getEncodedLexicalClassifications(text: string, lexState: EndOfLineState, syntacticClassifierAbsent?: boolean): string { return forwardJSONCall(this.logger, "getEncodedLexicalClassifications", () => convertClassifications(this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)), - /*noPerfLogging:*/ true); + this.logPerformance); } /// COLORIZATION @@ -838,13 +846,14 @@ module ts { } class CoreServicesShimObject extends ShimBase implements CoreServicesShim { + private logPerformance = false; constructor(factory: ShimFactory, public logger: Logger, private host: CoreServicesShimHostAdapter) { super(factory); } private forwardJSONCall(actionDescription: string, action: () => any): any { - return forwardJSONCall(this.logger, actionDescription, action, /*noPerfLogging:*/ false); + return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance); } public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string { diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 77aba4c85c1..fce4e2c3025 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -1,6 +1,6 @@ /// /* @internal */ -module ts.SignatureHelp { +namespace ts.SignatureHelp { // A partially written generic type expression is not guaranteed to have the correct syntax tree. the expression could be parsed as less than/greater than expression or a comma expression // or some other combination depending on what the user has typed so far. For the purposes of signature help we need to consider any location after "<" as a possible generic type reference. diff --git a/src/services/utilities.ts b/src/services/utilities.ts index da0a0aa96c1..73b88a3df26 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1,6 +1,6 @@ // These utilities are common to multiple language service features. /* @internal */ -module ts { +namespace ts { export interface ListItemInfo { listItemIndex: number; list: Node; @@ -502,7 +502,7 @@ module ts { // Display-part writer helpers /* @internal */ -module ts { +namespace ts { export function isFirstDeclarationOfSymbolParameter(symbol: Symbol) { return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === SyntaxKind.Parameter; } diff --git a/tests/baselines/reference/VariableDeclaration11_es6.errors.txt b/tests/baselines/reference/VariableDeclaration11_es6.errors.txt index 8c0ef5f8690..d1e6ab7c154 100644 --- a/tests/baselines/reference/VariableDeclaration11_es6.errors.txt +++ b/tests/baselines/reference/VariableDeclaration11_es6.errors.txt @@ -1,8 +1,11 @@ -tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts(2,4): error TS1123: Variable declaration list cannot be empty. +tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts(2,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode +tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts(2,1): error TS2304: Cannot find name 'let'. -==== tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts (1 errors) ==== +==== tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts (2 errors) ==== "use strict"; let - -!!! error TS1123: Variable declaration list cannot be empty. \ No newline at end of file + ~~~ +!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode + ~~~ +!!! error TS2304: Cannot find name 'let'. \ No newline at end of file diff --git a/tests/baselines/reference/VariableDeclaration11_es6.js b/tests/baselines/reference/VariableDeclaration11_es6.js index 83eec6d9a13..cf4c14617bc 100644 --- a/tests/baselines/reference/VariableDeclaration11_es6.js +++ b/tests/baselines/reference/VariableDeclaration11_es6.js @@ -4,4 +4,4 @@ let //// [VariableDeclaration11_es6.js] "use strict"; -let ; +let; diff --git a/tests/baselines/reference/YieldExpression18_es6.errors.txt b/tests/baselines/reference/YieldExpression18_es6.errors.txt index 056fc0e950a..5dd2807716f 100644 --- a/tests/baselines/reference/YieldExpression18_es6.errors.txt +++ b/tests/baselines/reference/YieldExpression18_es6.errors.txt @@ -1,8 +1,14 @@ -tests/cases/conformance/es6/yieldExpressions/YieldExpression18_es6.ts(2,1): error TS1163: A 'yield' expression is only allowed in a generator body. +tests/cases/conformance/es6/yieldExpressions/YieldExpression18_es6.ts(2,1): error TS1212: Identifier expected. 'yield' is a reserved word in strict mode +tests/cases/conformance/es6/yieldExpressions/YieldExpression18_es6.ts(2,1): error TS2304: Cannot find name 'yield'. +tests/cases/conformance/es6/yieldExpressions/YieldExpression18_es6.ts(2,7): error TS2304: Cannot find name 'foo'. -==== tests/cases/conformance/es6/yieldExpressions/YieldExpression18_es6.ts (1 errors) ==== +==== tests/cases/conformance/es6/yieldExpressions/YieldExpression18_es6.ts (3 errors) ==== "use strict"; yield(foo); ~~~~~ -!!! error TS1163: A 'yield' expression is only allowed in a generator body. \ No newline at end of file +!!! error TS1212: Identifier expected. 'yield' is a reserved word in strict mode + ~~~~~ +!!! error TS2304: Cannot find name 'yield'. + ~~~ +!!! error TS2304: Cannot find name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/YieldExpression18_es6.js b/tests/baselines/reference/YieldExpression18_es6.js index b4ba37d3ac4..36be3faabfe 100644 --- a/tests/baselines/reference/YieldExpression18_es6.js +++ b/tests/baselines/reference/YieldExpression18_es6.js @@ -4,4 +4,4 @@ yield(foo); //// [YieldExpression18_es6.js] "use strict"; -yield (foo); +yield(foo); diff --git a/tests/baselines/reference/class2.errors.txt b/tests/baselines/reference/class2.errors.txt index dde3612b68f..62542b41e40 100644 --- a/tests/baselines/reference/class2.errors.txt +++ b/tests/baselines/reference/class2.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/class2.ts(1,29): error TS1129: Statement expected. +tests/cases/compiler/class2.ts(1,29): error TS1128: Declaration or statement expected. tests/cases/compiler/class2.ts(1,45): error TS1128: Declaration or statement expected. ==== tests/cases/compiler/class2.ts (2 errors) ==== class foo { constructor() { static f = 3; } } ~~~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. ~ !!! error TS1128: Declaration or statement expected. \ No newline at end of file diff --git a/tests/baselines/reference/classUpdateTests.errors.txt b/tests/baselines/reference/classUpdateTests.errors.txt index a8c24dc63a2..59e9bc9ced1 100644 --- a/tests/baselines/reference/classUpdateTests.errors.txt +++ b/tests/baselines/reference/classUpdateTests.errors.txt @@ -6,14 +6,14 @@ tests/cases/compiler/classUpdateTests.ts(63,7): error TS2415: Class 'L' incorrec tests/cases/compiler/classUpdateTests.ts(69,7): error TS2415: Class 'M' incorrectly extends base class 'G'. Property 'p1' is private in type 'M' but not in type 'G'. tests/cases/compiler/classUpdateTests.ts(70,2): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. -tests/cases/compiler/classUpdateTests.ts(93,3): error TS1129: Statement expected. +tests/cases/compiler/classUpdateTests.ts(93,3): error TS1128: Declaration or statement expected. tests/cases/compiler/classUpdateTests.ts(95,1): error TS1128: Declaration or statement expected. -tests/cases/compiler/classUpdateTests.ts(99,3): error TS1129: Statement expected. +tests/cases/compiler/classUpdateTests.ts(99,3): error TS1128: Declaration or statement expected. tests/cases/compiler/classUpdateTests.ts(101,1): error TS1128: Declaration or statement expected. -tests/cases/compiler/classUpdateTests.ts(105,3): error TS1129: Statement expected. +tests/cases/compiler/classUpdateTests.ts(105,3): error TS1128: Declaration or statement expected. tests/cases/compiler/classUpdateTests.ts(105,14): error TS1005: ';' expected. tests/cases/compiler/classUpdateTests.ts(107,1): error TS1128: Declaration or statement expected. -tests/cases/compiler/classUpdateTests.ts(111,3): error TS1129: Statement expected. +tests/cases/compiler/classUpdateTests.ts(111,3): error TS1128: Declaration or statement expected. tests/cases/compiler/classUpdateTests.ts(111,15): error TS1005: ';' expected. tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or statement expected. @@ -133,7 +133,7 @@ tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or st constructor() { public p1 = 0; // ERROR ~~~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. } } ~ @@ -143,7 +143,7 @@ tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or st constructor() { private p1 = 0; // ERROR ~~~~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. } } ~ @@ -153,7 +153,7 @@ tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or st constructor() { public this.p1 = 0; // ERROR ~~~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. ~ !!! error TS1005: ';' expected. } @@ -165,7 +165,7 @@ tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or st constructor() { private this.p1 = 0; // ERROR ~~~~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. ~ !!! error TS1005: ';' expected. } diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt index 2818793948f..12f397ff06c 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt @@ -5,7 +5,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(22,35): error TS tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(22,39): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(24,28): error TS1005: ':' expected. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(24,29): error TS1005: ',' expected. -tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(27,18): error TS1129: Statement expected. +tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(27,18): error TS1128: Declaration or statement expected. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(27,26): error TS2304: Cannot find name 'bfs'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(28,30): error TS1005: '=' expected. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(31,18): error TS1109: Expression expected. @@ -129,7 +129,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS case = bfs.STATEMENTS(4); ~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. ~~~ !!! error TS2304: Cannot find name 'bfs'. if (retValue != 0) { diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiationInference.js b/tests/baselines/reference/cyclicGenericTypeInstantiationInference.js new file mode 100644 index 00000000000..4e093fecf79 --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiationInference.js @@ -0,0 +1,39 @@ +//// [cyclicGenericTypeInstantiationInference.ts] +function foo() { + var z = foo(); + var y: { + y2: typeof z + }; + return y; +} + + +function bar() { + var z = bar(); + var y: { + y2: typeof z; + } + return y; +} + +var a = foo(); +var b = bar(); + +function test(x: typeof a): void { } +test(b); + +//// [cyclicGenericTypeInstantiationInference.js] +function foo() { + var z = foo(); + var y; + return y; +} +function bar() { + var z = bar(); + var y; + return y; +} +var a = foo(); +var b = bar(); +function test(x) { } +test(b); diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiationInference.symbols b/tests/baselines/reference/cyclicGenericTypeInstantiationInference.symbols new file mode 100644 index 00000000000..962a1e12cc5 --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiationInference.symbols @@ -0,0 +1,61 @@ +=== tests/cases/compiler/cyclicGenericTypeInstantiationInference.ts === +function foo() { +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiationInference.ts, 0, 0)) +>T : Symbol(T, Decl(cyclicGenericTypeInstantiationInference.ts, 0, 13)) + + var z = foo(); +>z : Symbol(z, Decl(cyclicGenericTypeInstantiationInference.ts, 1, 7)) +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiationInference.ts, 0, 0)) +>y : Symbol(y, Decl(cyclicGenericTypeInstantiationInference.ts, 2, 7)) + + var y: { +>y : Symbol(y, Decl(cyclicGenericTypeInstantiationInference.ts, 2, 7)) + + y2: typeof z +>y2 : Symbol(y2, Decl(cyclicGenericTypeInstantiationInference.ts, 2, 12)) +>z : Symbol(z, Decl(cyclicGenericTypeInstantiationInference.ts, 1, 7)) + + }; + return y; +>y : Symbol(y, Decl(cyclicGenericTypeInstantiationInference.ts, 2, 7)) +} + + +function bar() { +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiationInference.ts, 6, 1)) +>T : Symbol(T, Decl(cyclicGenericTypeInstantiationInference.ts, 9, 13)) + + var z = bar(); +>z : Symbol(z, Decl(cyclicGenericTypeInstantiationInference.ts, 10, 7)) +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiationInference.ts, 6, 1)) +>y : Symbol(y, Decl(cyclicGenericTypeInstantiationInference.ts, 11, 7)) + + var y: { +>y : Symbol(y, Decl(cyclicGenericTypeInstantiationInference.ts, 11, 7)) + + y2: typeof z; +>y2 : Symbol(y2, Decl(cyclicGenericTypeInstantiationInference.ts, 11, 12)) +>z : Symbol(z, Decl(cyclicGenericTypeInstantiationInference.ts, 10, 7)) + } + return y; +>y : Symbol(y, Decl(cyclicGenericTypeInstantiationInference.ts, 11, 7)) +} + +var a = foo(); +>a : Symbol(a, Decl(cyclicGenericTypeInstantiationInference.ts, 17, 3)) +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiationInference.ts, 0, 0)) + +var b = bar(); +>b : Symbol(b, Decl(cyclicGenericTypeInstantiationInference.ts, 18, 3)) +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiationInference.ts, 6, 1)) + +function test(x: typeof a): void { } +>test : Symbol(test, Decl(cyclicGenericTypeInstantiationInference.ts, 18, 22)) +>T : Symbol(T, Decl(cyclicGenericTypeInstantiationInference.ts, 20, 14)) +>x : Symbol(x, Decl(cyclicGenericTypeInstantiationInference.ts, 20, 17)) +>a : Symbol(a, Decl(cyclicGenericTypeInstantiationInference.ts, 17, 3)) + +test(b); +>test : Symbol(test, Decl(cyclicGenericTypeInstantiationInference.ts, 18, 22)) +>b : Symbol(b, Decl(cyclicGenericTypeInstantiationInference.ts, 18, 3)) + diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiationInference.types b/tests/baselines/reference/cyclicGenericTypeInstantiationInference.types new file mode 100644 index 00000000000..765e8349716 --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiationInference.types @@ -0,0 +1,66 @@ +=== tests/cases/compiler/cyclicGenericTypeInstantiationInference.ts === +function foo() { +>foo : () => { y2: any; } +>T : T + + var z = foo(); +>z : { y2: any; } +>foo() : { y2: any; } +>foo : () => { y2: any; } +>y : { y2: any; } + + var y: { +>y : { y2: any; } + + y2: typeof z +>y2 : { y2: any; } +>z : { y2: any; } + + }; + return y; +>y : { y2: any; } +} + + +function bar() { +>bar : () => { y2: any; } +>T : T + + var z = bar(); +>z : { y2: any; } +>bar() : { y2: any; } +>bar : () => { y2: any; } +>y : { y2: any; } + + var y: { +>y : { y2: any; } + + y2: typeof z; +>y2 : { y2: any; } +>z : { y2: any; } + } + return y; +>y : { y2: any; } +} + +var a = foo(); +>a : { y2: any; } +>foo() : { y2: any; } +>foo : () => { y2: any; } + +var b = bar(); +>b : { y2: any; } +>bar() : { y2: any; } +>bar : () => { y2: any; } + +function test(x: typeof a): void { } +>test : (x: { y2: any; }) => void +>T : T +>x : { y2: any; } +>a : { y2: any; } + +test(b); +>test(b) : void +>test : (x: { y2: any; }) => void +>b : { y2: any; } + diff --git a/tests/baselines/reference/deleteOperatorInvalidOperations.errors.txt b/tests/baselines/reference/deleteOperatorInvalidOperations.errors.txt index 5f7c6d70450..d50be713d0a 100644 --- a/tests/baselines/reference/deleteOperatorInvalidOperations.errors.txt +++ b/tests/baselines/reference/deleteOperatorInvalidOperations.errors.txt @@ -1,9 +1,10 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(5,20): error TS1005: ',' expected. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(5,27): error TS1109: Expression expected. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(8,23): error TS1109: Expression expected. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(13,16): error TS1102: 'delete' cannot be called on an identifier in strict mode. -==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts (3 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts (4 errors) ==== // Unary operator delete var ANY; @@ -23,5 +24,7 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator class testADelx { constructor(public s: () => {}) { delete s; //expect error + ~ +!!! error TS1102: 'delete' cannot be called on an identifier in strict mode. } } \ No newline at end of file diff --git a/tests/baselines/reference/downlevelLetConst11.errors.txt b/tests/baselines/reference/downlevelLetConst11.errors.txt index 42449bd3c8a..29932f55c1f 100644 --- a/tests/baselines/reference/downlevelLetConst11.errors.txt +++ b/tests/baselines/reference/downlevelLetConst11.errors.txt @@ -1,8 +1,11 @@ -tests/cases/compiler/downlevelLetConst11.ts(2,4): error TS1123: Variable declaration list cannot be empty. +tests/cases/compiler/downlevelLetConst11.ts(2,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode +tests/cases/compiler/downlevelLetConst11.ts(2,1): error TS2304: Cannot find name 'let'. -==== tests/cases/compiler/downlevelLetConst11.ts (1 errors) ==== +==== tests/cases/compiler/downlevelLetConst11.ts (2 errors) ==== "use strict"; let - -!!! error TS1123: Variable declaration list cannot be empty. \ No newline at end of file + ~~~ +!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode + ~~~ +!!! error TS2304: Cannot find name 'let'. \ No newline at end of file diff --git a/tests/baselines/reference/downlevelLetConst11.js b/tests/baselines/reference/downlevelLetConst11.js index 377c7e6a9ed..e9749923d09 100644 --- a/tests/baselines/reference/downlevelLetConst11.js +++ b/tests/baselines/reference/downlevelLetConst11.js @@ -4,4 +4,4 @@ let //// [downlevelLetConst11.js] "use strict"; -var ; +let; diff --git a/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.errors.txt b/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.errors.txt new file mode 100644 index 00000000000..f22c018e9ea --- /dev/null +++ b/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts(4,15): error TS1003: Identifier expected. +tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts(9,2): error TS1005: '}' expected. + + +==== tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts (2 errors) ==== + namespace A { + function foo() { + if (true) { + B. + +!!! error TS1003: Identifier expected. + + + namespace B { + export function baz() { } + } + +!!! error TS1005: '}' expected. \ No newline at end of file diff --git a/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.js b/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.js new file mode 100644 index 00000000000..7eccb5c25ee --- /dev/null +++ b/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.js @@ -0,0 +1,26 @@ +//// [errorRecoveryWithDotFollowedByNamespaceKeyword.ts] +namespace A { + function foo() { + if (true) { + B. + + + namespace B { + export function baz() { } +} + +//// [errorRecoveryWithDotFollowedByNamespaceKeyword.js] +var A; +(function (A) { + function foo() { + if (true) { + B. + ; + var B; + (function (B) { + function baz() { } + B.baz = baz; + })(B || (B = {})); + } + } +})(A || (A = {})); diff --git a/tests/baselines/reference/exportNonInitializedVariablesAMD.errors.txt b/tests/baselines/reference/exportNonInitializedVariablesAMD.errors.txt index ae79675d8dd..28d7253a70c 100644 --- a/tests/baselines/reference/exportNonInitializedVariablesAMD.errors.txt +++ b/tests/baselines/reference/exportNonInitializedVariablesAMD.errors.txt @@ -1,15 +1,18 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(2,4): error TS1123: Variable declaration list cannot be empty. +tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(3,1): error TS2304: Cannot find name 'let'. tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(4,6): error TS1123: Variable declaration list cannot be empty. -==== tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts (3 errors) ==== +==== tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts (4 errors) ==== var; !!! error TS1123: Variable declaration list cannot be empty. let; ~~~ +!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. + ~~~ !!! error TS2304: Cannot find name 'let'. const; diff --git a/tests/baselines/reference/exportNonInitializedVariablesCommonJS.errors.txt b/tests/baselines/reference/exportNonInitializedVariablesCommonJS.errors.txt index 65a18649af3..84d4cab9c83 100644 --- a/tests/baselines/reference/exportNonInitializedVariablesCommonJS.errors.txt +++ b/tests/baselines/reference/exportNonInitializedVariablesCommonJS.errors.txt @@ -1,15 +1,18 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(2,4): error TS1123: Variable declaration list cannot be empty. +tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(3,1): error TS2304: Cannot find name 'let'. tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(4,6): error TS1123: Variable declaration list cannot be empty. -==== tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts (3 errors) ==== +==== tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts (4 errors) ==== var; !!! error TS1123: Variable declaration list cannot be empty. let; ~~~ +!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. + ~~~ !!! error TS2304: Cannot find name 'let'. const; diff --git a/tests/baselines/reference/exportNonInitializedVariablesES6.errors.txt b/tests/baselines/reference/exportNonInitializedVariablesES6.errors.txt index 905d16b360f..08e1d9588b6 100644 --- a/tests/baselines/reference/exportNonInitializedVariablesES6.errors.txt +++ b/tests/baselines/reference/exportNonInitializedVariablesES6.errors.txt @@ -1,15 +1,18 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(2,4): error TS1123: Variable declaration list cannot be empty. +tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(3,1): error TS2304: Cannot find name 'let'. tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(4,6): error TS1123: Variable declaration list cannot be empty. -==== tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts (3 errors) ==== +==== tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts (4 errors) ==== var; !!! error TS1123: Variable declaration list cannot be empty. let; ~~~ +!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. + ~~~ !!! error TS2304: Cannot find name 'let'. const; diff --git a/tests/baselines/reference/exportNonInitializedVariablesSystem.errors.txt b/tests/baselines/reference/exportNonInitializedVariablesSystem.errors.txt index d7aeb5d2ac0..1e461ea7253 100644 --- a/tests/baselines/reference/exportNonInitializedVariablesSystem.errors.txt +++ b/tests/baselines/reference/exportNonInitializedVariablesSystem.errors.txt @@ -1,15 +1,18 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(2,4): error TS1123: Variable declaration list cannot be empty. +tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(3,1): error TS2304: Cannot find name 'let'. tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(4,6): error TS1123: Variable declaration list cannot be empty. -==== tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts (3 errors) ==== +==== tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts (4 errors) ==== var; !!! error TS1123: Variable declaration list cannot be empty. let; ~~~ +!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. + ~~~ !!! error TS2304: Cannot find name 'let'. const; diff --git a/tests/baselines/reference/exportNonInitializedVariablesUMD.errors.txt b/tests/baselines/reference/exportNonInitializedVariablesUMD.errors.txt index eaf68e67055..b180c138501 100644 --- a/tests/baselines/reference/exportNonInitializedVariablesUMD.errors.txt +++ b/tests/baselines/reference/exportNonInitializedVariablesUMD.errors.txt @@ -1,15 +1,18 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(2,4): error TS1123: Variable declaration list cannot be empty. +tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(3,1): error TS2304: Cannot find name 'let'. tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(4,6): error TS1123: Variable declaration list cannot be empty. -==== tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts (3 errors) ==== +==== tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts (4 errors) ==== var; !!! error TS1123: Variable declaration list cannot be empty. let; ~~~ +!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. + ~~~ !!! error TS2304: Cannot find name 'let'. const; diff --git a/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.errors.txt b/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.errors.txt new file mode 100644 index 00000000000..6d443464d99 --- /dev/null +++ b/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.errors.txt @@ -0,0 +1,23 @@ +tests/cases/conformance/es6/modules/t3.ts(1,17): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. + + +==== tests/cases/conformance/es6/modules/t1.ts (0 errors) ==== + + let set = { + set foo(x: number) { + } + } + let get = 10; + + export { set, get }; + +==== tests/cases/conformance/es6/modules/t2.ts (0 errors) ==== + import * as set from "./t1"; + +==== tests/cases/conformance/es6/modules/t3.ts (1 errors) ==== + import { set as yield } from "./t1"; + ~~~~~ +!!! error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. + +==== tests/cases/conformance/es6/modules/t4.ts (0 errors) ==== + import { get } from "./t1"; \ No newline at end of file diff --git a/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.symbols b/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.symbols deleted file mode 100644 index f6695a9cf37..00000000000 --- a/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.symbols +++ /dev/null @@ -1,30 +0,0 @@ -=== tests/cases/conformance/es6/modules/t1.ts === - -let set = { ->set : Symbol(set, Decl(t1.ts, 1, 3)) - - set foo(x: number) { ->foo : Symbol(foo, Decl(t1.ts, 1, 11)) ->x : Symbol(x, Decl(t1.ts, 2, 12)) - } -} -let get = 10; ->get : Symbol(get, Decl(t1.ts, 5, 3)) - -export { set, get }; ->set : Symbol(set, Decl(t1.ts, 7, 8)) ->get : Symbol(get, Decl(t1.ts, 7, 13)) - -=== tests/cases/conformance/es6/modules/t2.ts === -import * as set from "./t1"; ->set : Symbol(set, Decl(t2.ts, 0, 6)) - -=== tests/cases/conformance/es6/modules/t3.ts === -import { set as yield } from "./t1"; ->set : Symbol(yield, Decl(t3.ts, 0, 8)) ->yield : Symbol(yield, Decl(t3.ts, 0, 8)) - -=== tests/cases/conformance/es6/modules/t4.ts === -import { get } from "./t1"; ->get : Symbol(get, Decl(t4.ts, 0, 8)) - diff --git a/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.types b/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.types deleted file mode 100644 index a687787c462..00000000000 --- a/tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.types +++ /dev/null @@ -1,32 +0,0 @@ -=== tests/cases/conformance/es6/modules/t1.ts === - -let set = { ->set : { foo: number; } ->{ set foo(x: number) { }} : { foo: number; } - - set foo(x: number) { ->foo : number ->x : number - } -} -let get = 10; ->get : number ->10 : number - -export { set, get }; ->set : { foo: number; } ->get : number - -=== tests/cases/conformance/es6/modules/t2.ts === -import * as set from "./t1"; ->set : typeof set - -=== tests/cases/conformance/es6/modules/t3.ts === -import { set as yield } from "./t1"; ->set : { foo: number; } ->yield : { foo: number; } - -=== tests/cases/conformance/es6/modules/t4.ts === -import { get } from "./t1"; ->get : number - diff --git a/tests/baselines/reference/genericTypeConstraints.errors.txt b/tests/baselines/reference/genericTypeConstraints.errors.txt new file mode 100644 index 00000000000..9fd8b5f15be --- /dev/null +++ b/tests/baselines/reference/genericTypeConstraints.errors.txt @@ -0,0 +1,24 @@ +tests/cases/compiler/genericTypeConstraints.ts(9,27): error TS2344: Type 'FooExtended' does not satisfy the constraint 'Foo'. + Property 'fooMethod' is missing in type 'FooExtended'. +tests/cases/compiler/genericTypeConstraints.ts(9,31): error TS2344: Type 'FooExtended' does not satisfy the constraint 'Foo'. + + +==== tests/cases/compiler/genericTypeConstraints.ts (2 errors) ==== + class Foo { + fooMethod() {} + } + + class FooExtended { } + + class Bar { } + + class BarExtended extends Bar { + ~~~~~~~~~~~~~~~~ +!!! error TS2344: Type 'FooExtended' does not satisfy the constraint 'Foo'. +!!! error TS2344: Property 'fooMethod' is missing in type 'FooExtended'. + ~~~~~~~~~~~ +!!! error TS2344: Type 'FooExtended' does not satisfy the constraint 'Foo'. + constructor() { + super(); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/genericTypeConstraints.js b/tests/baselines/reference/genericTypeConstraints.js new file mode 100644 index 00000000000..6f0f235ccb8 --- /dev/null +++ b/tests/baselines/reference/genericTypeConstraints.js @@ -0,0 +1,45 @@ +//// [genericTypeConstraints.ts] +class Foo { + fooMethod() {} +} + +class FooExtended { } + +class Bar { } + +class BarExtended extends Bar { + constructor() { + super(); + } +} + +//// [genericTypeConstraints.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var Foo = (function () { + function Foo() { + } + Foo.prototype.fooMethod = function () { }; + return Foo; +})(); +var FooExtended = (function () { + function FooExtended() { + } + return FooExtended; +})(); +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +var BarExtended = (function (_super) { + __extends(BarExtended, _super); + function BarExtended() { + _super.call(this); + } + return BarExtended; +})(Bar); diff --git a/tests/baselines/reference/isArray.js b/tests/baselines/reference/isArray.js new file mode 100644 index 00000000000..a90898fd65b --- /dev/null +++ b/tests/baselines/reference/isArray.js @@ -0,0 +1,19 @@ +//// [isArray.ts] +var maybeArray: number | number[]; + + +if (Array.isArray(maybeArray)) { + maybeArray.length; // OK +} +else { + maybeArray.toFixed(); // OK +} + +//// [isArray.js] +var maybeArray; +if (Array.isArray(maybeArray)) { + maybeArray.length; // OK +} +else { + maybeArray.toFixed(); // OK +} diff --git a/tests/baselines/reference/isArray.symbols b/tests/baselines/reference/isArray.symbols new file mode 100644 index 00000000000..75351b377be --- /dev/null +++ b/tests/baselines/reference/isArray.symbols @@ -0,0 +1,22 @@ +=== tests/cases/compiler/isArray.ts === +var maybeArray: number | number[]; +>maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) + + +if (Array.isArray(maybeArray)) { +>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.d.ts, 1166, 28)) +>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.d.ts, 1166, 28)) +>maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) + + maybeArray.length; // OK +>maybeArray.length : Symbol(Array.length, Decl(lib.d.ts, 1007, 20)) +>maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) +>length : Symbol(Array.length, Decl(lib.d.ts, 1007, 20)) +} +else { + maybeArray.toFixed(); // OK +>maybeArray.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, 463, 37)) +>maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, 463, 37)) +} diff --git a/tests/baselines/reference/isArray.types b/tests/baselines/reference/isArray.types new file mode 100644 index 00000000000..8865ff73bc0 --- /dev/null +++ b/tests/baselines/reference/isArray.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/isArray.ts === +var maybeArray: number | number[]; +>maybeArray : number | number[] + + +if (Array.isArray(maybeArray)) { +>Array.isArray(maybeArray) : boolean +>Array.isArray : (arg: any) => boolean +>Array : ArrayConstructor +>isArray : (arg: any) => boolean +>maybeArray : number | number[] + + maybeArray.length; // OK +>maybeArray.length : number +>maybeArray : number[] +>length : number +} +else { + maybeArray.toFixed(); // OK +>maybeArray.toFixed() : string +>maybeArray.toFixed : (fractionDigits?: number) => string +>maybeArray : number +>toFixed : (fractionDigits?: number) => string +} diff --git a/tests/baselines/reference/letAsIdentifier.errors.txt b/tests/baselines/reference/letAsIdentifier.errors.txt new file mode 100644 index 00000000000..b4e4db22853 --- /dev/null +++ b/tests/baselines/reference/letAsIdentifier.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/letAsIdentifier.ts(3,5): error TS2300: Duplicate identifier 'a'. +tests/cases/compiler/letAsIdentifier.ts(6,1): error TS2300: Duplicate identifier 'a'. + + +==== tests/cases/compiler/letAsIdentifier.ts (2 errors) ==== + + var let = 10; + var a = 10; + ~ +!!! error TS2300: Duplicate identifier 'a'. + let = 30; + let + a; + ~ +!!! error TS2300: Duplicate identifier 'a'. \ No newline at end of file diff --git a/tests/baselines/reference/letAsIdentifier.js b/tests/baselines/reference/letAsIdentifier.js index ae45b4b491c..05811ce1088 100644 --- a/tests/baselines/reference/letAsIdentifier.js +++ b/tests/baselines/reference/letAsIdentifier.js @@ -10,10 +10,10 @@ a; var let = 10; var a = 10; let = 30; -let; -a; +var a; //// [letAsIdentifier.d.ts] declare var let: number; declare var a: number; +declare let a: any; diff --git a/tests/baselines/reference/letAsIdentifier.symbols b/tests/baselines/reference/letAsIdentifier.symbols deleted file mode 100644 index be5066f5ac7..00000000000 --- a/tests/baselines/reference/letAsIdentifier.symbols +++ /dev/null @@ -1,17 +0,0 @@ -=== tests/cases/compiler/letAsIdentifier.ts === - -var let = 10; ->let : Symbol(let, Decl(letAsIdentifier.ts, 1, 3)) - -var a = 10; ->a : Symbol(a, Decl(letAsIdentifier.ts, 2, 3)) - -let = 30; ->let : Symbol(let, Decl(letAsIdentifier.ts, 1, 3)) - -let ->let : Symbol(let, Decl(letAsIdentifier.ts, 1, 3)) - -a; ->a : Symbol(a, Decl(letAsIdentifier.ts, 2, 3)) - diff --git a/tests/baselines/reference/letAsIdentifier.types b/tests/baselines/reference/letAsIdentifier.types deleted file mode 100644 index 36c190a92e4..00000000000 --- a/tests/baselines/reference/letAsIdentifier.types +++ /dev/null @@ -1,21 +0,0 @@ -=== tests/cases/compiler/letAsIdentifier.ts === - -var let = 10; ->let : number ->10 : number - -var a = 10; ->a : number ->10 : number - -let = 30; ->let = 30 : number ->let : number ->30 : number - -let ->let : number - -a; ->a : number - diff --git a/tests/baselines/reference/letAsIdentifierInStrictMode.errors.txt b/tests/baselines/reference/letAsIdentifierInStrictMode.errors.txt index b59daca008c..42f71669c66 100644 --- a/tests/baselines/reference/letAsIdentifierInStrictMode.errors.txt +++ b/tests/baselines/reference/letAsIdentifierInStrictMode.errors.txt @@ -1,20 +1,20 @@ +tests/cases/compiler/letAsIdentifierInStrictMode.ts(2,5): error TS1212: Identifier expected. 'let' is a reserved word in strict mode tests/cases/compiler/letAsIdentifierInStrictMode.ts(3,5): error TS2300: Duplicate identifier 'a'. -tests/cases/compiler/letAsIdentifierInStrictMode.ts(4,5): error TS1134: Variable declaration expected. -tests/cases/compiler/letAsIdentifierInStrictMode.ts(4,7): error TS1134: Variable declaration expected. +tests/cases/compiler/letAsIdentifierInStrictMode.ts(4,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode tests/cases/compiler/letAsIdentifierInStrictMode.ts(6,1): error TS2300: Duplicate identifier 'a'. ==== tests/cases/compiler/letAsIdentifierInStrictMode.ts (4 errors) ==== "use strict"; var let = 10; + ~~~ +!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode var a = 10; ~ !!! error TS2300: Duplicate identifier 'a'. let = 30; - ~ -!!! error TS1134: Variable declaration expected. - ~~ -!!! error TS1134: Variable declaration expected. + ~~~ +!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode let a; ~ diff --git a/tests/baselines/reference/letAsIdentifierInStrictMode.js b/tests/baselines/reference/letAsIdentifierInStrictMode.js index eb840e1a641..cce0b13cf64 100644 --- a/tests/baselines/reference/letAsIdentifierInStrictMode.js +++ b/tests/baselines/reference/letAsIdentifierInStrictMode.js @@ -10,6 +10,5 @@ a; "use strict"; var let = 10; var a = 10; -var ; -30; +let = 30; var a; diff --git a/tests/baselines/reference/library_ArraySlice.symbols b/tests/baselines/reference/library_ArraySlice.symbols index 25e6fbd5b5b..02c58859d40 100644 --- a/tests/baselines/reference/library_ArraySlice.symbols +++ b/tests/baselines/reference/library_ArraySlice.symbols @@ -2,22 +2,22 @@ // Array.prototype.slice can have zero, one, or two arguments Array.prototype.slice(); >Array.prototype.slice : Symbol(Array.slice, Decl(lib.d.ts, 1048, 15)) ->Array.prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 31)) +>Array.prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 41)) >Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) ->prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 31)) +>prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 41)) >slice : Symbol(Array.slice, Decl(lib.d.ts, 1048, 15)) Array.prototype.slice(0); >Array.prototype.slice : Symbol(Array.slice, Decl(lib.d.ts, 1048, 15)) ->Array.prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 31)) +>Array.prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 41)) >Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) ->prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 31)) +>prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 41)) >slice : Symbol(Array.slice, Decl(lib.d.ts, 1048, 15)) Array.prototype.slice(0, 1); >Array.prototype.slice : Symbol(Array.slice, Decl(lib.d.ts, 1048, 15)) ->Array.prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 31)) +>Array.prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 41)) >Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) ->prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 31)) +>prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, 1167, 41)) >slice : Symbol(Array.slice, Decl(lib.d.ts, 1048, 15)) diff --git a/tests/baselines/reference/moduleElementsInWrongContext.errors.txt b/tests/baselines/reference/moduleElementsInWrongContext.errors.txt new file mode 100644 index 00000000000..4ab5c5b42c0 --- /dev/null +++ b/tests/baselines/reference/moduleElementsInWrongContext.errors.txt @@ -0,0 +1,87 @@ +tests/cases/compiler/moduleElementsInWrongContext.ts(2,5): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext.ts(3,5): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext.ts(7,5): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext.ts(9,5): error TS1234: An ambient module declaration is only allowed at the top level in a file. +tests/cases/compiler/moduleElementsInWrongContext.ts(13,5): error TS1231: An export assignment can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext.ts(17,5): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext.ts(18,5): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext.ts(19,5): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext.ts(19,14): error TS2305: Module '"ambient"' has no exported member 'baz'. +tests/cases/compiler/moduleElementsInWrongContext.ts(20,5): error TS1231: An export assignment can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext.ts(21,5): error TS1184: Modifiers cannot appear here. +tests/cases/compiler/moduleElementsInWrongContext.ts(22,5): error TS1184: Modifiers cannot appear here. +tests/cases/compiler/moduleElementsInWrongContext.ts(23,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext.ts(24,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext.ts(25,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext.ts(26,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext.ts(27,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext.ts(28,5): error TS1232: An import declaration can only be used in a namespace or module. + + +==== tests/cases/compiler/moduleElementsInWrongContext.ts (18 errors) ==== + { + module M { } + ~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + export namespace N { + ~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + export interface I { } + } + + namespace Q.K { } + ~~~~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + + declare module "ambient" { + ~~~~~~~ +!!! error TS1234: An ambient module declaration is only allowed at the top level in a file. + + } + + export = M; + ~~~~~~ +!!! error TS1231: An export assignment can only be used in a module. + + var v; + function foo() { } + export * from "ambient"; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + export { foo }; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + export { baz as b } from "ambient"; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + ~~~ +!!! error TS2305: Module '"ambient"' has no exported member 'baz'. + export default v; + ~~~~~~ +!!! error TS1231: An export assignment can only be used in a module. + export default class C { } + ~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + export function bee() { } + ~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + import I = M; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import I2 = require("foo"); + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import * as Foo from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import bar from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import { baz } from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + } + \ No newline at end of file diff --git a/tests/baselines/reference/moduleElementsInWrongContext.js b/tests/baselines/reference/moduleElementsInWrongContext.js new file mode 100644 index 00000000000..635da02bdf2 --- /dev/null +++ b/tests/baselines/reference/moduleElementsInWrongContext.js @@ -0,0 +1,47 @@ +//// [moduleElementsInWrongContext.ts] +{ + module M { } + export namespace N { + export interface I { } + } + + namespace Q.K { } + + declare module "ambient" { + + } + + export = M; + + var v; + function foo() { } + export * from "ambient"; + export { foo }; + export { baz as b } from "ambient"; + export default v; + export default class C { } + export function bee() { } + import I = M; + import I2 = require("foo"); + import * as Foo from "ambient"; + import bar from "ambient"; + import { baz } from "ambient"; + import "ambient"; +} + + +//// [moduleElementsInWrongContext.js] +{ + var v; + function foo() { } + __export(require("ambient")); + exports["default"] = v; + var C = (function () { + function C() { + } + return C; + })(); + exports["default"] = C; + function bee() { } + exports.bee = bee; +} diff --git a/tests/baselines/reference/moduleElementsInWrongContext2.errors.txt b/tests/baselines/reference/moduleElementsInWrongContext2.errors.txt new file mode 100644 index 00000000000..d6611e71831 --- /dev/null +++ b/tests/baselines/reference/moduleElementsInWrongContext2.errors.txt @@ -0,0 +1,87 @@ +tests/cases/compiler/moduleElementsInWrongContext2.ts(2,5): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(3,5): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(7,5): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(9,5): error TS1234: An ambient module declaration is only allowed at the top level in a file. +tests/cases/compiler/moduleElementsInWrongContext2.ts(13,5): error TS1231: An export assignment can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(17,5): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(18,5): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(19,5): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(19,30): error TS2307: Cannot find module 'ambient'. +tests/cases/compiler/moduleElementsInWrongContext2.ts(20,5): error TS1231: An export assignment can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(21,5): error TS1184: Modifiers cannot appear here. +tests/cases/compiler/moduleElementsInWrongContext2.ts(22,5): error TS1184: Modifiers cannot appear here. +tests/cases/compiler/moduleElementsInWrongContext2.ts(23,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(24,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(25,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(26,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(27,5): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext2.ts(28,5): error TS1232: An import declaration can only be used in a namespace or module. + + +==== tests/cases/compiler/moduleElementsInWrongContext2.ts (18 errors) ==== + function blah () { + module M { } + ~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + export namespace N { + ~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + export interface I { } + } + + namespace Q.K { } + ~~~~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + + declare module "ambient" { + ~~~~~~~ +!!! error TS1234: An ambient module declaration is only allowed at the top level in a file. + + } + + export = M; + ~~~~~~ +!!! error TS1231: An export assignment can only be used in a module. + + var v; + function foo() { } + export * from "ambient"; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + export { foo }; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + export { baz as b } from "ambient"; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + ~~~~~~~~~ +!!! error TS2307: Cannot find module 'ambient'. + export default v; + ~~~~~~ +!!! error TS1231: An export assignment can only be used in a module. + export default class C { } + ~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + export function bee() { } + ~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + import I = M; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import I2 = require("foo"); + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import * as Foo from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import bar from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import { baz } from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + } + \ No newline at end of file diff --git a/tests/baselines/reference/moduleElementsInWrongContext2.js b/tests/baselines/reference/moduleElementsInWrongContext2.js new file mode 100644 index 00000000000..fdf1222e549 --- /dev/null +++ b/tests/baselines/reference/moduleElementsInWrongContext2.js @@ -0,0 +1,47 @@ +//// [moduleElementsInWrongContext2.ts] +function blah () { + module M { } + export namespace N { + export interface I { } + } + + namespace Q.K { } + + declare module "ambient" { + + } + + export = M; + + var v; + function foo() { } + export * from "ambient"; + export { foo }; + export { baz as b } from "ambient"; + export default v; + export default class C { } + export function bee() { } + import I = M; + import I2 = require("foo"); + import * as Foo from "ambient"; + import bar from "ambient"; + import { baz } from "ambient"; + import "ambient"; +} + + +//// [moduleElementsInWrongContext2.js] +function blah() { + var v; + function foo() { } + __export(require("ambient")); + exports["default"] = v; + var C = (function () { + function C() { + } + return C; + })(); + exports["default"] = C; + function bee() { } + exports.bee = bee; +} diff --git a/tests/baselines/reference/moduleElementsInWrongContext3.errors.txt b/tests/baselines/reference/moduleElementsInWrongContext3.errors.txt new file mode 100644 index 00000000000..f5361319b68 --- /dev/null +++ b/tests/baselines/reference/moduleElementsInWrongContext3.errors.txt @@ -0,0 +1,88 @@ +tests/cases/compiler/moduleElementsInWrongContext3.ts(3,9): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(4,9): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(8,9): error TS1235: A namespace declaration is only allowed in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(10,9): error TS1234: An ambient module declaration is only allowed at the top level in a file. +tests/cases/compiler/moduleElementsInWrongContext3.ts(14,9): error TS1231: An export assignment can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(18,9): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(19,9): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(20,9): error TS1233: An export declaration can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(20,34): error TS2307: Cannot find module 'ambient'. +tests/cases/compiler/moduleElementsInWrongContext3.ts(21,9): error TS1231: An export assignment can only be used in a module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(22,9): error TS1184: Modifiers cannot appear here. +tests/cases/compiler/moduleElementsInWrongContext3.ts(23,9): error TS1184: Modifiers cannot appear here. +tests/cases/compiler/moduleElementsInWrongContext3.ts(24,9): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(25,9): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(26,9): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(27,9): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(28,9): error TS1232: An import declaration can only be used in a namespace or module. +tests/cases/compiler/moduleElementsInWrongContext3.ts(29,9): error TS1232: An import declaration can only be used in a namespace or module. + + +==== tests/cases/compiler/moduleElementsInWrongContext3.ts (18 errors) ==== + module P { + { + module M { } + ~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + export namespace N { + ~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + export interface I { } + } + + namespace Q.K { } + ~~~~~~~~~ +!!! error TS1235: A namespace declaration is only allowed in a namespace or module. + + declare module "ambient" { + ~~~~~~~ +!!! error TS1234: An ambient module declaration is only allowed at the top level in a file. + + } + + export = M; + ~~~~~~ +!!! error TS1231: An export assignment can only be used in a module. + + var v; + function foo() { } + export * from "ambient"; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + export { foo }; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + export { baz as b } from "ambient"; + ~~~~~~ +!!! error TS1233: An export declaration can only be used in a module. + ~~~~~~~~~ +!!! error TS2307: Cannot find module 'ambient'. + export default v; + ~~~~~~ +!!! error TS1231: An export assignment can only be used in a module. + export default class C { } + ~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + export function bee() { } + ~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + import I = M; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import I2 = require("foo"); + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import * as Foo from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import bar from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import { baz } from "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + import "ambient"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used in a namespace or module. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/moduleElementsInWrongContext3.js b/tests/baselines/reference/moduleElementsInWrongContext3.js new file mode 100644 index 00000000000..d464d9d31b1 --- /dev/null +++ b/tests/baselines/reference/moduleElementsInWrongContext3.js @@ -0,0 +1,51 @@ +//// [moduleElementsInWrongContext3.ts] +module P { + { + module M { } + export namespace N { + export interface I { } + } + + namespace Q.K { } + + declare module "ambient" { + + } + + export = M; + + var v; + function foo() { } + export * from "ambient"; + export { foo }; + export { baz as b } from "ambient"; + export default v; + export default class C { } + export function bee() { } + import I = M; + import I2 = require("foo"); + import * as Foo from "ambient"; + import bar from "ambient"; + import { baz } from "ambient"; + import "ambient"; + } +} + +//// [moduleElementsInWrongContext3.js] +var P; +(function (P) { + { + var v; + function foo() { } + __export(require("ambient")); + P["default"] = v; + var C = (function () { + function C() { + } + return C; + })(); + exports["default"] = C; + function bee() { } + P.bee = bee; + } +})(P || (P = {})); diff --git a/tests/baselines/reference/overloadingStaticFunctionsInFunctions.errors.txt b/tests/baselines/reference/overloadingStaticFunctionsInFunctions.errors.txt index e340e5596cd..ae16b59b095 100644 --- a/tests/baselines/reference/overloadingStaticFunctionsInFunctions.errors.txt +++ b/tests/baselines/reference/overloadingStaticFunctionsInFunctions.errors.txt @@ -1,12 +1,12 @@ tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(1,14): error TS1005: '(' expected. -tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(2,3): error TS1129: Statement expected. +tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(2,3): error TS1128: Declaration or statement expected. tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(2,10): error TS2304: Cannot find name 'test'. -tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(3,3): error TS1129: Statement expected. +tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(3,3): error TS1128: Declaration or statement expected. tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(3,10): error TS2304: Cannot find name 'test'. tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(3,15): error TS2304: Cannot find name 'name'. tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(3,19): error TS1005: ',' expected. tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(3,20): error TS2304: Cannot find name 'string'. -tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(4,3): error TS1129: Statement expected. +tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(4,3): error TS1128: Declaration or statement expected. tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(4,10): error TS2304: Cannot find name 'test'. tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(4,15): error TS2304: Cannot find name 'name'. tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(4,20): error TS1109: Expression expected. @@ -20,12 +20,12 @@ tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(4,25): error TS100 !!! error TS1005: '(' expected. static test() ~~~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. ~~~~ !!! error TS2304: Cannot find name 'test'. static test(name:string) ~~~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. ~~~~ !!! error TS2304: Cannot find name 'test'. ~~~~ @@ -36,7 +36,7 @@ tests/cases/compiler/overloadingStaticFunctionsInFunctions.ts(4,25): error TS100 !!! error TS2304: Cannot find name 'string'. static test(name?:any){ } ~~~~~~ -!!! error TS1129: Statement expected. +!!! error TS1128: Declaration or statement expected. ~~~~ !!! error TS2304: Cannot find name 'test'. ~~~~ diff --git a/tests/baselines/reference/parser509698.errors.txt b/tests/baselines/reference/parser509698.errors.txt index 2aaaec18dc2..dfc155dd364 100644 --- a/tests/baselines/reference/parser509698.errors.txt +++ b/tests/baselines/reference/parser509698.errors.txt @@ -18,7 +18,6 @@ error TS2318: Cannot find global type 'String'. !!! error TS2318: Cannot find global type 'String'. ==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509698.ts (0 errors) ==== ///