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..42bcd8ac610 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 { @@ -90,10 +90,12 @@ module ts { let lastContainer: Node; let symbolCount = 0; let Symbol = objectAllocator.getSymbolConstructor(); + let classifiableNames: Map = {}; if (!file.locals) { bind(file); file.symbolCount = symbolCount; + file.classifiableNames = classifiableNames; } return; @@ -194,6 +196,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; @@ -553,6 +560,23 @@ 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 (node.parserContextFlags & ParserContextFlags.StrictMode && + 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) { + let message = getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression) ? + Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode : + Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode; + file.bindDiagnostics.push(createDiagnosticForNode(node, message, declarationNameToString(node))); + } + } + } + function getDestructuringParameterName(node: Declaration) { return "__" + indexOf((node.parent).parameters, node); } @@ -581,6 +605,8 @@ module ts { function bindWorker(node: Node) { switch (node.kind) { + case SyntaxKind.Identifier: + return checkStrictModeIdentifier(node); case SyntaxKind.TypeParameter: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); case SyntaxKind.Parameter: @@ -661,7 +687,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 +702,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); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d3211a8475f..04e7c636354 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; @@ -3627,7 +3627,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; } @@ -4439,8 +4439,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; @@ -4476,27 +4476,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); @@ -4815,6 +4794,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; } @@ -5129,21 +5129,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; @@ -5211,22 +5196,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--; } } @@ -5256,14 +5246,14 @@ module ts { if (source.typePredicate && target.typePredicate) { if (target.typePredicate.parameterIndex === source.typePredicate.parameterIndex) { // Return types from type predicates are treated as booleans. In order to infer types - // from type predicates we would need to infer from the type of type predicates. Since - // we can't infer any type information from the return types — we can just add a return - // statement after the below infer type statement. + // from type predicates we would need to infer using the type within the type predicate + // (i.e. 'Foo' from 'x is Foo'). inferFromTypes(source.typePredicate.type, target.typePredicate.type); } - return; } - inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); + else { + inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); + } } function inferFromIndexTypes(source: Type, target: Type, sourceKind: IndexKind, targetKind: IndexKind) { @@ -6626,7 +6616,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; } @@ -6667,7 +6657,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) { @@ -7275,8 +7265,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); @@ -7757,7 +7747,7 @@ 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); } @@ -8476,11 +8466,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 @@ -8488,7 +8473,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); @@ -8592,8 +8577,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); @@ -8979,13 +8962,10 @@ module ts { } function checkTypeReferenceNode(node: TypeReferenceNode) { - checkGrammarTypeReferenceInStrictMode(node.typeName); return checkTypeReferenceOrExpressionWithTypeArguments(node); } function checkExpressionWithTypeArguments(node: ExpressionWithTypeArguments) { - checkGrammarExpressionWithTypeArgumentsInStrictMode(node.expression); - return checkTypeReferenceOrExpressionWithTypeArguments(node); } @@ -9431,7 +9411,7 @@ module ts { return; } if (shouldCheckIfUnknownType || type.symbol.valueDeclaration) { - checkExpressionOrQualifiedName((node).typeName); + checkExpression((node).typeName); } } } @@ -9528,7 +9508,6 @@ module ts { } function checkFunctionLikeDeclaration(node: FunctionLikeDeclaration): void { - checkGrammarDeclarationNameInStrictMode(node); checkDecorators(node); checkSignatureDeclaration(node); @@ -9814,7 +9793,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 @@ -10599,7 +10577,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); @@ -10645,7 +10622,7 @@ module ts { if (baseTypes.length || (baseTypeNode && compilerOptions.isolatedModules)) { // Check that base type can be evaluated as expression - checkExpressionOrQualifiedName(baseTypeNode.expression); + checkExpression(baseTypeNode.expression); } let implementedTypeNodes = getClassImplementsHeritageClauseElements(node); @@ -10824,7 +10801,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) { @@ -11049,7 +11026,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); @@ -11135,7 +11112,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); } @@ -11171,7 +11157,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); } @@ -11247,7 +11233,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)) { @@ -11269,7 +11259,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) { @@ -11300,9 +11295,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 } @@ -11324,6 +11325,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) { @@ -11332,6 +11339,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); @@ -11347,7 +11359,8 @@ module ts { else { checkExpressionCached(node.expression); } - checkExternalModuleExports(container); + + checkExternalModuleExports(container); if (node.isExportEquals && !isInAmbientContext(node)) { if (languageVersion >= ScriptTarget.ES6) { @@ -11361,7 +11374,7 @@ module ts { } } - function getModuleStatements(node: Declaration): ModuleElement[] { + function getModuleStatements(node: Declaration): Statement[] { if (node.kind === SyntaxKind.SourceFile) { return (node).statements; } @@ -11604,7 +11617,9 @@ module ts { function checkSourceFile(node: SourceFile) { let start = new Date().getTime(); + checkSourceFileWorker(node); + checkTime += new Date().getTime() - start; } @@ -11612,6 +11627,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; } @@ -12607,153 +12624,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) { @@ -13670,16 +13540,13 @@ module ts { 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; + + let message = getAncestor(identifier, SyntaxKind.ClassDeclaration) || getAncestor(identifier, SyntaxKind.ClassExpression) ? + Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode : + Diagnostics.Invalid_use_of_0_in_strict_mode; + return grammarErrorOnNode(identifier, message, declarationNameToString(identifier)); } } } 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 3082c12e2d6..8e9f3e5c352 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 47e1b8e2b39..6616556382f 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,6 @@ 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." }, 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,9 +184,14 @@ 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." }, - _0_modifier_can_only_appear_on_a_class_or_member_function_declaration: { code: 1231, category: DiagnosticCategory.Error, key: "'{0}' modifier can only appear on a class or member function declaration." }, - _0_modifier_cannot_be_used_with_1_modifier: { code: 1232, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot be used with '{1}' modifier." }, - Abstract_methods_can_only_appear_within_an_abstract_class: { code: 1233, category: DiagnosticCategory.Error, key: "Abstract methods can only appear within an abstract class." }, + 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." }, + _0_modifier_can_only_appear_on_a_class_or_member_function_declaration: { code: 1236, category: DiagnosticCategory.Error, key: "'{0}' modifier can only appear on a class or member function declaration." }, + _0_modifier_cannot_be_used_with_1_modifier: { code: 1237, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot be used with '{1}' modifier." }, + Abstract_methods_can_only_appear_within_an_abstract_class: { code: 1238, category: DiagnosticCategory.Error, key: "Abstract methods can only appear within an abstract class." }, 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 6a7c5ef6581..1b55a6dc214 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -671,14 +671,6 @@ "category": "Error", "code": 1213 }, - "Type expected. '{0}' is a reserved word 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,18 +723,38 @@ "category": "Error", "code": 1230 }, - "'{0}' modifier can only appear on a class or member function declaration.": { + "An export assignment can only be used in a module.": { "category": "Error", "code": 1231 }, - "'{0}' modifier cannot be used with '{1}' modifier.": { + "An import declaration can only be used in a namespace or module.": { "category": "Error", "code": 1232 }, - "Abstract methods can only appear within an abstract class.": { + "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 + }, + "'{0}' modifier can only appear on a class or member function declaration.": { + "category": "Error", + "code": 1236 + }, + "'{0}' modifier cannot be used with '{1}' modifier.": { + "category": "Error", + "code": 1237 + }, + "Abstract methods can only appear within an abstract class.": { + "category": "Error", + "code": 1238 + }, "Duplicate identifier '{0}'.": { "category": "Error", "code": 2300 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 2f29ce0b405..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); } @@ -1903,23 +1903,21 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { function emitNewExpression(node: NewExpression) { write("new "); - // Spread operator logic can be supported in new expressions in ES5 using a combination + // Spread operator logic is supported in new expressions in ES5 using a combination // of Function.prototype.bind() and Function.prototype.apply(). // // Example: // - // var arguments = [1, 2, 3, 4, 5]; - // new Array(...arguments); + // var args = [1, 2, 3, 4, 5]; + // new Array(...args); // - // Could be transpiled into ES5: + // is compiled into the following ES5: // - // var arguments = [1, 2, 3, 4, 5]; - // new (Array.bind.apply(Array, [void 0].concat(arguments))); + // var args = [1, 2, 3, 4, 5]; + // new (Array.bind.apply(Array, [void 0].concat(args))); // - // `[void 0]` is the first argument which represents `thisArg` to the bind method above. - // And `thisArg` will be set to the return value of the constructor when instantiated - // with the new operator — regardless of any value we set `thisArg` to. Thus, we set it - // to an undefined, `void 0`. + // The 'thisArg' to 'bind' is ignored when invoking the result of 'bind' with 'new', + // Thus, we set it to undefined ('void 0'). if (languageVersion === ScriptTarget.ES5 && node.arguments && hasSpreadElement(node.arguments)) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f0a5850220b..4611b1d1657 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, /*checkForStrictMode*/ true, parseStatement); Debug.assert(token === SyntaxKind.EndOfFileToken); sourceFile.endOfFileToken = parseTokenNode(); @@ -1134,17 +1127,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; @@ -1255,7 +1245,6 @@ module ts { } switch (kind) { - case ParsingContext.ModuleElements: case ParsingContext.BlockStatements: case ParsingContext.SwitchClauses: case ParsingContext.TypeMembers: @@ -1466,15 +1455,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); @@ -1537,26 +1524,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) { @@ -1609,6 +1576,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; } } @@ -1682,8 +1658,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; @@ -1800,26 +1775,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) { @@ -3816,7 +3791,7 @@ module ts { return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); } - function parseDeclarationFlags(): StatementFlags { + function isDeclaration(): boolean { while (true) { switch (token) { case SyntaxKind.VarKeyword: @@ -3825,7 +3800,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 @@ -3850,28 +3825,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: @@ -3882,16 +3856,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: @@ -3917,12 +3891,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: @@ -3930,7 +3904,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: @@ -3938,22 +3912,13 @@ 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() { nextToken(); return !scanner.hasPrecedingLineBreak() && @@ -3967,18 +3932,6 @@ module ts { } 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(); @@ -4039,7 +3992,7 @@ module ts { case SyntaxKind.PublicKeyword: case SyntaxKind.AbstractKeyword: case SyntaxKind.StaticKeyword: - if (getDeclarationFlags() & flags) { + if (isStartOfDeclaration()) { return parseDeclaration(); } break; @@ -4047,7 +4000,7 @@ module ts { return parseExpressionOrLabeledStatement(); } - function parseDeclaration(): ModuleElement { + function parseDeclaration(): Statement { let fullStart = getNodePos(); let decorators = parseDecorators(); let modifiers = parseModifiers(); @@ -4080,7 +4033,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); @@ -4636,7 +4589,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, /*checkForStrictMode*/ false, parseStatement); parseExpected(SyntaxKind.CloseBraceToken); } else { @@ -4964,7 +4917,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 cff3fc10372..15f51775e0b 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 6cacbd827a7..7d03b19483d 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; } @@ -810,7 +810,7 @@ module ts { expression: UnaryExpression; } - export interface Statement extends Node, ModuleElement { + export interface Statement extends Node { _statementBrand: any; } @@ -913,10 +913,6 @@ module ts { block: Block; } - export interface ModuleElement extends Node { - _moduleElementBrand: any; - } - export interface ClassLikeDeclaration extends Declaration { name?: Identifier; typeParameters?: NodeArray; @@ -964,16 +960,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 @@ -989,7 +985,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; } @@ -1009,7 +1005,7 @@ module ts { name: Identifier; } - export interface ExportDeclaration extends Declaration, ModuleElement { + export interface ExportDeclaration extends Declaration, Statement { exportClause?: NamedExports; moduleSpecifier?: Expression; } @@ -1029,7 +1025,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; } @@ -1145,7 +1141,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; @@ -1155,6 +1151,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; @@ -1178,6 +1182,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 { @@ -1229,6 +1235,8 @@ module ts { // language service). /* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker; + /* @internal */ getClassifiableNames(): Map; + /* @internal */ getNodeCount(): number; /* @internal */ getIdentifierCount(): number; /* @internal */ getSymbolCount(): number; @@ -1525,6 +1533,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 { @@ -1857,7 +1870,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 26237803b87..09e02d63b54 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 @@ -1177,6 +1177,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 ... @@ -2004,7 +2039,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 cdd6e4358e8..3e150e61a81 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 c8c0f332001..49afeb780bb 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" @@ -5994,6 +5994,7 @@ module ts { let typeChecker = program.getTypeChecker(); let result: number[] = []; + let classifiableNames = program.getClassifiableNames(); processNode(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6006,6 +6007,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; @@ -6048,13 +6052,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 548822ddee4..60c8a9e8af8 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; @@ -503,7 +503,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/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 e7f34fec546..536c69023ad 100644 --- a/tests/baselines/reference/classUpdateTests.errors.txt +++ b/tests/baselines/reference/classUpdateTests.errors.txt @@ -8,14 +8,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. @@ -139,7 +139,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. } } ~ @@ -149,7 +149,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. } } ~ @@ -159,7 +159,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. } @@ -171,7 +171,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/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/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/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) ==== ///