diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d904c670195..dbd5da96684 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1485,7 +1485,7 @@ module ts { return appendParentTypeArgumentsAndSymbolName(symbol); } - function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, typeStack?: Type[]) { + function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { let globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike; return writeType(type, globalFlags); @@ -1608,49 +1608,54 @@ module ts { } function writeAnonymousType(type: ObjectType, flags: TypeFormatFlags) { - // Always use 'typeof T' for type of class, enum, and module objects - if (type.symbol && type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { - writeTypeofSymbol(type, flags); - } - // Use 'typeof T' for types of functions and methods that circularly reference themselves - else if (shouldWriteTypeOfFunctionSymbol()) { - writeTypeofSymbol(type, flags); - } - else if (typeStack && contains(typeStack, type)) { - // If type is an anonymous type literal in a type alias declaration, use type alias name - let typeAlias = getTypeAliasForTypeLiteral(type); - if (typeAlias) { - // The specified symbol flags need to be reinterpreted as type flags - buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags); + let symbol = type.symbol; + if (symbol) { + // Always use 'typeof T' for type of class, enum, and module objects + if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { + writeTypeofSymbol(type, flags); + } + else if (shouldWriteTypeOfFunctionSymbol()) { + writeTypeofSymbol(type, flags); + } + else if (contains(symbolStack, symbol)) { + // If type is an anonymous type literal in a type alias declaration, use type alias name + let typeAlias = getTypeAliasForTypeLiteral(type); + if (typeAlias) { + // The specified symbol flags need to be reinterpreted as type flags + buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags); + } + else { + // Recursive usage, use any + writeKeyword(writer, SyntaxKind.AnyKeyword); + } } else { - // Recursive usage, use any - writeKeyword(writer, SyntaxKind.AnyKeyword); + // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead + // of types allows us to catch circular references to instantiations of the same anonymous type + if (!symbolStack) { + symbolStack = []; + } + symbolStack.push(symbol); + writeLiteralType(type, flags); + symbolStack.pop(); } } else { - if (!typeStack) { - typeStack = []; - } - typeStack.push(type); + // Anonymous types with no symbol are never circular writeLiteralType(type, flags); - typeStack.pop(); } function shouldWriteTypeOfFunctionSymbol() { - if (type.symbol) { - let isStaticMethodSymbol = !!(type.symbol.flags & SymbolFlags.Method && // typeof static method - ts.forEach(type.symbol.declarations, declaration => declaration.flags & NodeFlags.Static)); - let isNonLocalFunctionSymbol = !!(type.symbol.flags & SymbolFlags.Function) && - (type.symbol.parent || // is exported function symbol - ts.forEach(type.symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); - - if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { - // typeof is allowed only for static/non local functions - return !!(flags & TypeFormatFlags.UseTypeOfFunction) || // use typeof if format flags specify it - (typeStack && contains(typeStack, type)); // it is type of the symbol uses itself recursively - } + let isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method + forEach(symbol.declarations, declaration => declaration.flags & NodeFlags.Static)); + let isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && + (symbol.parent || // is exported function symbol + forEach(symbol.declarations, declaration => + declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); + if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { + // typeof is allowed only for static/non local functions + return !!(flags & TypeFormatFlags.UseTypeOfFunction) || // use typeof if format flags specify it + (contains(symbolStack, symbol)); // it is type of the symbol uses itself recursively } } } @@ -1685,7 +1690,7 @@ module ts { if (flags & TypeFormatFlags.InElementType) { writePunctuation(writer, SyntaxKind.OpenParenToken); } - buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, typeStack); + buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, symbolStack); if (flags & TypeFormatFlags.InElementType) { writePunctuation(writer, SyntaxKind.CloseParenToken); } @@ -1697,7 +1702,7 @@ module ts { } writeKeyword(writer, SyntaxKind.NewKeyword); writeSpace(writer); - buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, typeStack); + buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, symbolStack); if (flags & TypeFormatFlags.InElementType) { writePunctuation(writer, SyntaxKind.CloseParenToken); } @@ -1709,7 +1714,7 @@ module ts { writer.writeLine(); writer.increaseIndent(); for (let signature of resolved.callSignatures) { - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, typeStack); + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, symbolStack); writePunctuation(writer, SyntaxKind.SemicolonToken); writer.writeLine(); } @@ -1717,7 +1722,7 @@ module ts { writeKeyword(writer, SyntaxKind.NewKeyword); writeSpace(writer); - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, typeStack); + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, symbolStack); writePunctuation(writer, SyntaxKind.SemicolonToken); writer.writeLine(); } @@ -1758,7 +1763,7 @@ module ts { if (p.flags & SymbolFlags.Optional) { writePunctuation(writer, SyntaxKind.QuestionToken); } - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, typeStack); + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, symbolStack); writePunctuation(writer, SyntaxKind.SemicolonToken); writer.writeLine(); } @@ -1787,18 +1792,18 @@ module ts { } } - function buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { appendSymbolNameOnly(tp.symbol, writer); let constraint = getConstraintOfTypeParameter(tp); if (constraint) { writeSpace(writer); writeKeyword(writer, SyntaxKind.ExtendsKeyword); writeSpace(writer); - buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, typeStack); + buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack); } } - function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { let parameterNode = p.valueDeclaration; if (isRestParameter(parameterNode)) { writePunctuation(writer, SyntaxKind.DotDotDotToken); @@ -1810,10 +1815,10 @@ module ts { writePunctuation(writer, SyntaxKind.ColonToken); writeSpace(writer); - buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, typeStack); + buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, symbolStack); } - function buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (typeParameters && typeParameters.length) { writePunctuation(writer, SyntaxKind.LessThanToken); for (let i = 0; i < typeParameters.length; i++) { @@ -1821,13 +1826,13 @@ module ts { writePunctuation(writer, SyntaxKind.CommaToken); writeSpace(writer); } - buildTypeParameterDisplay(typeParameters[i], writer, enclosingDeclaration, flags, typeStack); + buildTypeParameterDisplay(typeParameters[i], writer, enclosingDeclaration, flags, symbolStack); } writePunctuation(writer, SyntaxKind.GreaterThanToken); } } - function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (typeParameters && typeParameters.length) { writePunctuation(writer, SyntaxKind.LessThanToken); for (let i = 0; i < typeParameters.length; i++) { @@ -1841,19 +1846,19 @@ module ts { } } - function buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { writePunctuation(writer, SyntaxKind.OpenParenToken); for (let i = 0; i < parameters.length; i++) { if (i > 0) { writePunctuation(writer, SyntaxKind.CommaToken); writeSpace(writer); } - buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, typeStack); + buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, symbolStack); } writePunctuation(writer, SyntaxKind.CloseParenToken); } - function buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (flags & TypeFormatFlags.WriteArrowStyleSignature) { writeSpace(writer); writePunctuation(writer, SyntaxKind.EqualsGreaterThanToken); @@ -1862,21 +1867,21 @@ module ts { writePunctuation(writer, SyntaxKind.ColonToken); } writeSpace(writer); - buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags, typeStack); + buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags, symbolStack); } - function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (signature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature)) { // Instantiated signature, write type arguments instead // This is achieved by passing in the mapper separately buildDisplayForTypeArgumentsAndDelimiters(signature.target.typeParameters, signature.mapper, writer, enclosingDeclaration); } else { - buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, typeStack); + buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, symbolStack); } - buildDisplayForParametersAndDelimiters(signature.parameters, writer, enclosingDeclaration, flags, typeStack); - buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, typeStack); + buildDisplayForParametersAndDelimiters(signature.parameters, writer, enclosingDeclaration, flags, symbolStack); + buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack); } return _displayBuilder || (_displayBuilder = { @@ -2373,7 +2378,7 @@ module ts { // Variable has initializer that circularly references the variable itself type = anyType; if (compilerOptions.noImplicitAny) { - error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, + error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol)); } } @@ -3996,19 +4001,8 @@ module ts { } function instantiateAnonymousType(type: ObjectType, mapper: TypeMapper): ObjectType { - // If this type has already been instantiated using this mapper, returned the cached result. This guards against - // infinite instantiations of cyclic types, e.g. "var x: { a: T, b: typeof x };" - if (mapper.mappings) { - let cached = mapper.mappings[type.id]; - if (cached) { - return cached; - } - } - else { - mapper.mappings = {}; - } - // Instantiate the given type using the given mapper and cache the result - let result = createObjectType(TypeFlags.Anonymous, type.symbol); + // Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it + let result = createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); result.callSignatures = instantiateList(getSignaturesOfType(type, SignatureKind.Call), mapper, instantiateSignature); @@ -4017,7 +4011,6 @@ module ts { let numberIndexType = getIndexTypeOfType(type, IndexKind.Number); if (stringIndexType) result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); - mapper.mappings[type.id] = result; return result; } @@ -4432,12 +4425,13 @@ module ts { // 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 { - if (type.flags & TypeFlags.Reference && depth >= 10) { - let target = (type).target; + // 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 && (t).target === target) { + if (t.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && t.symbol === symbol) { count++; if (count >= 10) return true; } @@ -7657,6 +7651,15 @@ module ts { } if (node.body) { + if (!node.type) { + // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors + // we need. An example is the noImplicitAny errors resulting from widening the return expression + // of a function. Because checking of function expression bodies is deferred, there was never an + // appropriate time to do this during the main walk of the file (see the comment at the top of + // checkFunctionExpressionBodies). So it must be done now. + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } + if (node.body.kind === SyntaxKind.Block) { checkSourceElement(node.body); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index be507f626d4..61739fcecac 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -349,7 +349,7 @@ module ts { return { options: getCompilerOptions(), - fileNames: getFiles(), + fileNames: getFileNames(), errors }; @@ -395,23 +395,24 @@ module ts { return options; } - function getFiles(): string[] { - var files: string[] = []; + function getFileNames(): string[] { + var fileNames: string[] = []; if (hasProperty(json, "files")) { if (json["files"] instanceof Array) { - var files = map(json["files"], s => combinePaths(basePath, s)); + fileNames = map(json["files"], s => combinePaths(basePath, s)); } } else { - var sysFiles = host.readDirectory(basePath, ".ts"); + var exclude = json["exclude"] instanceof Array ? map(json["exclude"], normalizeSlashes) : undefined; + var sysFiles = host.readDirectory(basePath, ".ts", exclude); for (var i = 0; i < sysFiles.length; i++) { var name = sysFiles[i]; if (!fileExtensionIs(name, ".d.ts") || !contains(sysFiles, name.substr(0, name.length - 5) + ".ts")) { - files.push(name); + fileNames.push(name); } } } - return files; + return fileNames; } } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index e327a516311..78f44191278 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -530,7 +530,7 @@ module ts { Object_literal_s_property_0_implicitly_has_an_1_type: { code: 7018, category: DiagnosticCategory.Error, key: "Object literal's property '{0}' implicitly has an '{1}' type." }, Rest_parameter_0_implicitly_has_an_any_type: { code: 7019, category: DiagnosticCategory.Error, key: "Rest parameter '{0}' implicitly has an 'any[]' type." }, Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: { code: 7020, category: DiagnosticCategory.Error, key: "Call signature, which lacks return-type annotation, implicitly has an 'any' return type." }, - _0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." }, + _0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer." }, _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 871fb2d9ea8..57b4eb9bb67 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2110,7 +2110,7 @@ "category": "Error", "code": 7020 }, - "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer.": { + "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.": { "category": "Error", "code": 7022 }, diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 1a7d9de47a1..75e8af357bb 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -15,7 +15,7 @@ module ts { createDirectory(path: string): void; getExecutingFilePath(): string; getCurrentDirectory(): string; - readDirectory(path: string, extension?: string): string[]; + readDirectory(path: string, extension?: string, exclude?: string[]): string[]; getMemoryUsage?(): number; exit(exitCode?: number): void; } @@ -109,7 +109,11 @@ module ts { } } - function getNames(collection: any): string[] { + function getCanonicalPath(path: string): string { + return path.toLowerCase(); + } + + function getNames(collection: any): string[]{ var result: string[] = []; for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) { result.push(e.item().Name); @@ -117,21 +121,26 @@ module ts { return result.sort(); } - function readDirectory(path: string, extension?: string): string[] { + function readDirectory(path: string, extension?: string, exclude?: string[]): string[] { var result: string[] = []; + exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s))); visitDirectory(path); return result; function visitDirectory(path: string) { var folder = fso.GetFolder(path || "."); var files = getNames(folder.files); - for (let name of files) { - if (!extension || fileExtensionIs(name, extension)) { - result.push(combinePaths(path, name)); + for (let current of files) { + let name = combinePaths(path, current); + if ((!extension || fileExtensionIs(name, extension)) && !contains(exclude, getCanonicalPath(name))) { + result.push(name); } } var subfolders = getNames(folder.subfolders); for (let current of subfolders) { - visitDirectory(combinePaths(path, current)); + let name = combinePaths(path, current); + if (!contains(exclude, getCanonicalPath(name))) { + visitDirectory(name); + } } } } @@ -222,8 +231,13 @@ module ts { _fs.writeFileSync(fileName, data, "utf8"); } - function readDirectory(path: string, extension?: string): string[] { + function getCanonicalPath(path: string): string { + return useCaseSensitiveFileNames ? path.toLowerCase() : path; + } + + function readDirectory(path: string, extension?: string, exclude?: string[]): string[] { var result: string[] = []; + exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s))); visitDirectory(path); return result; function visitDirectory(path: string) { @@ -231,14 +245,16 @@ module ts { var directories: string[] = []; for (let current of files) { var name = combinePaths(path, current); - var stat = _fs.statSync(name); - if (stat.isFile()) { - if (!extension || fileExtensionIs(name, extension)) { - result.push(name); + if (!contains(exclude, getCanonicalPath(name))) { + var stat = _fs.statSync(name); + if (stat.isFile()) { + if (!extension || fileExtensionIs(name, extension)) { + result.push(name); + } + } + else if (stat.isDirectory()) { + directories.push(name); } - } - else if (stat.isDirectory()) { - directories.push(name); } } for (let current of directories) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 393daff451e..ec09d224b38 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1168,7 +1168,7 @@ module ts { } export interface ParseConfigHost { - readDirectory(rootDir: string, extension: string): string[]; + readDirectory(rootDir: string, extension: string, exclude: string[]): string[]; } export interface WriteFileCallback { @@ -1582,14 +1582,15 @@ module ts { Tuple = 0x00002000, // Tuple Union = 0x00004000, // Union Anonymous = 0x00008000, // Anonymous + Instantiated = 0x00010000, // Instantiated anonymous type /* @internal */ - FromSignature = 0x00010000, // Created for signature assignment check - ObjectLiteral = 0x00020000, // Originates in an object literal + FromSignature = 0x00020000, // Created for signature assignment check + ObjectLiteral = 0x00040000, // Originates in an object literal /* @internal */ - ContainsUndefinedOrNull = 0x00040000, // Type is or contains Undefined or Null type + ContainsUndefinedOrNull = 0x00080000, // Type is or contains Undefined or Null type /* @internal */ - ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type - ESSymbol = 0x00100000, // Type of symbol primitive introduced in ES6 + ContainsObjectLiteral = 0x00100000, // Type is or contains object literal type + ESSymbol = 0x00200000, // Type of symbol primitive introduced in ES6 /* @internal */ Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null, @@ -1674,8 +1675,8 @@ module ts { properties: Symbol[]; // Properties callSignatures: Signature[]; // Call signatures of type constructSignatures: Signature[]; // Construct signatures of type - stringIndexType: Type; // String index type - numberIndexType: Type; // Numeric index type + stringIndexType?: Type; // String index type + numberIndexType?: Type; // Numeric index type } // Just a place to cache element types of iterables and iterators @@ -1731,7 +1732,6 @@ module ts { /* @internal */ export interface TypeMapper { (t: TypeParameter): Type; - mappings?: Map; // Type mapping cache } /* @internal */ diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiation.js b/tests/baselines/reference/cyclicGenericTypeInstantiation.js new file mode 100644 index 00000000000..10f52e10d89 --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiation.js @@ -0,0 +1,37 @@ +//// [cyclicGenericTypeInstantiation.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(); +a = b; + + +//// [cyclicGenericTypeInstantiation.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(); +a = b; diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiation.symbols b/tests/baselines/reference/cyclicGenericTypeInstantiation.symbols new file mode 100644 index 00000000000..a6566b86839 --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiation.symbols @@ -0,0 +1,55 @@ +=== tests/cases/compiler/cyclicGenericTypeInstantiation.ts === +function foo() { +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiation.ts, 0, 0)) +>T : Symbol(T, Decl(cyclicGenericTypeInstantiation.ts, 0, 13)) + + var z = foo(); +>z : Symbol(z, Decl(cyclicGenericTypeInstantiation.ts, 1, 7)) +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiation.ts, 0, 0)) +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 2, 7)) + + var y: { +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 2, 7)) + + y2: typeof z +>y2 : Symbol(y2, Decl(cyclicGenericTypeInstantiation.ts, 2, 12)) +>z : Symbol(z, Decl(cyclicGenericTypeInstantiation.ts, 1, 7)) + + }; + return y; +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 2, 7)) +} + + +function bar() { +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiation.ts, 6, 1)) +>T : Symbol(T, Decl(cyclicGenericTypeInstantiation.ts, 9, 13)) + + var z = bar(); +>z : Symbol(z, Decl(cyclicGenericTypeInstantiation.ts, 10, 7)) +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiation.ts, 6, 1)) +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 11, 7)) + + var y: { +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 11, 7)) + + y2: typeof z; +>y2 : Symbol(y2, Decl(cyclicGenericTypeInstantiation.ts, 11, 12)) +>z : Symbol(z, Decl(cyclicGenericTypeInstantiation.ts, 10, 7)) + } + return y; +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 11, 7)) +} + +var a = foo(); +>a : Symbol(a, Decl(cyclicGenericTypeInstantiation.ts, 17, 3)) +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiation.ts, 0, 0)) + +var b = bar(); +>b : Symbol(b, Decl(cyclicGenericTypeInstantiation.ts, 18, 3)) +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiation.ts, 6, 1)) + +a = b; +>a : Symbol(a, Decl(cyclicGenericTypeInstantiation.ts, 17, 3)) +>b : Symbol(b, Decl(cyclicGenericTypeInstantiation.ts, 18, 3)) + diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiation.types b/tests/baselines/reference/cyclicGenericTypeInstantiation.types new file mode 100644 index 00000000000..69b0955b22f --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiation.types @@ -0,0 +1,60 @@ +=== tests/cases/compiler/cyclicGenericTypeInstantiation.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; } + +a = b; +>a = b : { y2: any; } +>a : { y2: any; } +>b : { y2: any; } + diff --git a/tests/baselines/reference/for-of32.errors.txt b/tests/baselines/reference/for-of32.errors.txt index 4b139d386c0..f382ea40984 100644 --- a/tests/baselines/reference/for-of32.errors.txt +++ b/tests/baselines/reference/for-of32.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/es6/for-ofStatements/for-of32.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/es6/for-ofStatements/for-of32.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. ==== tests/cases/conformance/es6/for-ofStatements/for-of32.ts (1 errors) ==== for (var v of v) { } ~ -!!! error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. \ No newline at end of file +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. \ No newline at end of file diff --git a/tests/baselines/reference/for-of33.errors.txt b/tests/baselines/reference/for-of33.errors.txt index cd2d48566ab..ff1feacd7b3 100644 --- a/tests/baselines/reference/for-of33.errors.txt +++ b/tests/baselines/reference/for-of33.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/for-ofStatements/for-of33.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/es6/for-ofStatements/for-of33.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/conformance/es6/for-ofStatements/for-of33.ts(4,5): error TS7023: '[Symbol.iterator]' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. ==== tests/cases/conformance/es6/for-ofStatements/for-of33.ts (2 errors) ==== for (var v of new StringIterator) { } ~ -!!! error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. class StringIterator { [Symbol.iterator]() { diff --git a/tests/baselines/reference/for-of34.errors.txt b/tests/baselines/reference/for-of34.errors.txt index a4f55ed29ba..c378a8f5bb8 100644 --- a/tests/baselines/reference/for-of34.errors.txt +++ b/tests/baselines/reference/for-of34.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/for-ofStatements/for-of34.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/es6/for-ofStatements/for-of34.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/conformance/es6/for-ofStatements/for-of34.ts(4,5): error TS7023: 'next' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. ==== tests/cases/conformance/es6/for-ofStatements/for-of34.ts (2 errors) ==== for (var v of new StringIterator) { } ~ -!!! error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. class StringIterator { next() { diff --git a/tests/baselines/reference/for-of35.errors.txt b/tests/baselines/reference/for-of35.errors.txt index 65529752b9b..58fb5056fd7 100644 --- a/tests/baselines/reference/for-of35.errors.txt +++ b/tests/baselines/reference/for-of35.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/for-ofStatements/for-of35.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/es6/for-ofStatements/for-of35.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/conformance/es6/for-ofStatements/for-of35.ts(4,5): error TS7023: 'next' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. ==== tests/cases/conformance/es6/for-ofStatements/for-of35.ts (2 errors) ==== for (var v of new StringIterator) { } ~ -!!! error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. class StringIterator { next() { diff --git a/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt b/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt index 8d0aaf04c03..36538aef4f3 100644 --- a/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt +++ b/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt @@ -7,7 +7,7 @@ tests/cases/compiler/implicitAnyFromCircularInference.ts(18,10): error TS7024: F tests/cases/compiler/implicitAnyFromCircularInference.ts(23,10): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. tests/cases/compiler/implicitAnyFromCircularInference.ts(26,10): error TS7023: 'h' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. tests/cases/compiler/implicitAnyFromCircularInference.ts(28,14): error TS7023: 'foo' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -tests/cases/compiler/implicitAnyFromCircularInference.ts(41,5): error TS7022: 's' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/compiler/implicitAnyFromCircularInference.ts(41,5): error TS7022: 's' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/compiler/implicitAnyFromCircularInference.ts(46,5): error TS7023: 'x' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. @@ -72,7 +72,7 @@ tests/cases/compiler/implicitAnyFromCircularInference.ts(46,5): error TS7023: 'x // Error expected s = foo(this); ~~~~~~~~~~~~~~ -!!! error TS7022: 's' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +!!! error TS7022: 's' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. } class D { diff --git a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt index 14b7769d22f..abf11dc9dba 100644 --- a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt +++ b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt @@ -1,12 +1,15 @@ tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,1): error TS1108: A 'return' statement can only be used within a function body. +tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,18): error TS2304: Cannot find name 'role'. tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(2,18): error TS2304: Cannot find name 'Role'. tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(4,26): error TS2503: Cannot find namespace 'ng'. -==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (3 errors) ==== +==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (4 errors) ==== return this.edit(role) ~~~~~~ !!! error TS1108: A 'return' statement can only be used within a function body. + ~~~~ +!!! error TS2304: Cannot find name 'role'. .then((role: Role) => ~~~~ !!! error TS2304: Cannot find name 'Role'. diff --git a/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt new file mode 100644 index 00000000000..7db4c2506cc --- /dev/null +++ b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts(1,13): error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts (1 errors) ==== + var foo = { bar() { return undefined } }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/baselines/reference/typeCheckObjectLiteralMethodBody.js b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.js new file mode 100644 index 00000000000..1339315e93c --- /dev/null +++ b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.js @@ -0,0 +1,5 @@ +//// [typeCheckObjectLiteralMethodBody.ts] +var foo = { bar() { return undefined } }; + +//// [typeCheckObjectLiteralMethodBody.js] +var foo = { bar: function () { return undefined; } }; diff --git a/tests/baselines/reference/typeCheckReturnExpression.errors.txt b/tests/baselines/reference/typeCheckReturnExpression.errors.txt new file mode 100644 index 00000000000..c648c57799d --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpression.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/typeCheckReturnExpression.ts(1,11): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/compiler/typeCheckReturnExpression.ts (1 errors) ==== + var foo = () => undefined; + ~~~~~~~~~~~~~~~ +!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/baselines/reference/typeCheckReturnExpression.js b/tests/baselines/reference/typeCheckReturnExpression.js new file mode 100644 index 00000000000..ba71780b48d --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpression.js @@ -0,0 +1,5 @@ +//// [typeCheckReturnExpression.ts] +var foo = () => undefined; + +//// [typeCheckReturnExpression.js] +var foo = function () { return undefined; }; diff --git a/tests/cases/compiler/cyclicGenericTypeInstantiation.ts b/tests/cases/compiler/cyclicGenericTypeInstantiation.ts new file mode 100644 index 00000000000..070cc44a63a --- /dev/null +++ b/tests/cases/compiler/cyclicGenericTypeInstantiation.ts @@ -0,0 +1,20 @@ +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(); +a = b; diff --git a/tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts b/tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts new file mode 100644 index 00000000000..316572466df --- /dev/null +++ b/tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts @@ -0,0 +1,2 @@ +//@noImplicitAny: true +var foo = { bar() { return undefined } }; \ No newline at end of file diff --git a/tests/cases/compiler/typeCheckReturnExpression.ts b/tests/cases/compiler/typeCheckReturnExpression.ts new file mode 100644 index 00000000000..00f75912bd1 --- /dev/null +++ b/tests/cases/compiler/typeCheckReturnExpression.ts @@ -0,0 +1,2 @@ +//@noImplicitAny: true +var foo = () => undefined; \ No newline at end of file