diff --git a/Jakefile.js b/Jakefile.js index ea13cce6685..3ac2e8fad13 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -588,9 +588,10 @@ function deleteTemporaryProjectOutput() { } var testTimeout = 20000; -desc("Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|]'."); +desc("Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|]', debug=true."); task("runtests", ["tests", builtLocalDirectory], function() { cleanTestDirs(); + var debug = process.env.debug || process.env.d; host = "mocha" tests = process.env.test || process.env.tests || process.env.t; var light = process.env.light || false; @@ -613,7 +614,7 @@ task("runtests", ["tests", builtLocalDirectory], function() { reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter'; // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer - var cmd = host + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; + var cmd = host + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; console.log(cmd); exec(cmd, deleteTemporaryProjectOutput); }, {async: true}); diff --git a/lib/tsc.js b/lib/tsc.js index 0ccb839c2ef..591a22bceb9 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -1573,6 +1573,7 @@ var ts; Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, + Suppress_excess_property_checks_for_object_literals: { code: 6072, category: ts.DiagnosticCategory.Message, key: "Suppress excess property checks for object literals." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -12680,7 +12681,7 @@ var ts; return members; } function resolveTupleTypeMembers(type) { - var arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes))); + var arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes, true))); var members = createTupleTypeMemberSymbols(type.elementTypes); addInheritedMembers(members, arrayType.properties); setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexType, arrayType.numberIndexType); @@ -12972,25 +12973,6 @@ var ts; } return undefined; } - function isKnownProperty(type, name) { - if (type.flags & 80896 && type !== globalObjectType) { - var resolved = resolveStructuredTypeMembers(type); - return !!(resolved.properties.length === 0 || - resolved.stringIndexType || - resolved.numberIndexType || - getPropertyOfType(type, name)); - } - if (type.flags & 49152) { - for (var _i = 0, _a = type.types; _i < _a.length; _i++) { - var t = _a[_i]; - if (isKnownProperty(t, name)) { - return true; - } - } - return false; - } - return true; - } function getSignaturesOfStructuredType(type, kind) { if (type.flags & 130048) { var resolved = resolveStructuredTypeMembers(type); @@ -13446,7 +13428,7 @@ var ts; } function createTypedPropertyDescriptorType(propertyType) { var globalTypedPropertyDescriptorType = getGlobalTypedPropertyDescriptorType(); - return globalTypedPropertyDescriptorType !== emptyObjectType + return globalTypedPropertyDescriptorType !== emptyGenericType ? createTypeReference(globalTypedPropertyDescriptorType, [propertyType]) : emptyObjectType; } @@ -13499,68 +13481,19 @@ var ts; addTypeToSet(typeSet, type, typeSetKind); } } - function isObjectLiteralTypeDuplicateOf(source, target) { - var sourceProperties = getPropertiesOfObjectType(source); - var targetProperties = getPropertiesOfObjectType(target); - if (sourceProperties.length !== targetProperties.length) { - return false; - } - for (var _i = 0; _i < sourceProperties.length; _i++) { - var sourceProp = sourceProperties[_i]; - var targetProp = getPropertyOfObjectType(target, sourceProp.name); - if (!targetProp || - getDeclarationFlagsFromSymbol(targetProp) & (32 | 64) || - !isTypeDuplicateOf(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp))) { - return false; - } - } - return true; - } - function isTupleTypeDuplicateOf(source, target) { - var sourceTypes = source.elementTypes; - var targetTypes = target.elementTypes; - if (sourceTypes.length !== targetTypes.length) { - return false; - } - for (var i = 0; i < sourceTypes.length; i++) { - if (!isTypeDuplicateOf(sourceTypes[i], targetTypes[i])) { - return false; - } - } - return true; - } - function isTypeDuplicateOf(source, target) { - if (source === target) { - return true; - } - if (source.flags & 32 || source.flags & 64 && !(target.flags & 32)) { - return true; - } - if (source.flags & 524288 && target.flags & 80896) { - return isObjectLiteralTypeDuplicateOf(source, target); - } - if (isArrayType(source) && isArrayType(target)) { - return isTypeDuplicateOf(source.typeArguments[0], target.typeArguments[0]); - } - if (isTupleType(source) && isTupleType(target)) { - return isTupleTypeDuplicateOf(source, target); - } - return isTypeIdenticalTo(source, target); - } - function isTypeDuplicateOfSomeType(candidate, types) { - for (var _i = 0; _i < types.length; _i++) { - var type = types[_i]; - if (candidate !== type && isTypeDuplicateOf(candidate, type)) { + function isSubtypeOfAny(candidate, types) { + for (var i = 0, len = types.length; i < len; i++) { + if (candidate !== types[i] && isTypeSubtypeOf(candidate, types[i])) { return true; } } return false; } - function removeDuplicateTypes(types) { + function removeSubtypes(types) { var i = types.length; while (i > 0) { i--; - if (isTypeDuplicateOfSomeType(types[i], types)) { + if (isSubtypeOfAny(types[i], types)) { types.splice(i, 1); } } @@ -13583,7 +13516,7 @@ var ts; } } } - function getUnionType(types, noDeduplication) { + function getUnionType(types, noSubtypeReduction) { if (types.length === 0) { return emptyObjectType; } @@ -13592,12 +13525,12 @@ var ts; if (containsTypeAny(typeSet)) { return anyType; } - if (noDeduplication) { + if (noSubtypeReduction) { removeAllButLast(typeSet, undefinedType); removeAllButLast(typeSet, nullType); } else { - removeDuplicateTypes(typeSet); + removeSubtypes(typeSet); } if (typeSet.length === 1) { return typeSet[0]; @@ -14091,6 +14024,26 @@ var ts; } return 0; } + function isKnownProperty(type, name) { + if (type.flags & 80896) { + var resolved = resolveStructuredTypeMembers(type); + if (relation === assignableRelation && (type === globalObjectType || resolved.properties.length === 0) || + resolved.stringIndexType || resolved.numberIndexType || getPropertyOfType(type, name)) { + return true; + } + return false; + } + if (type.flags & 49152) { + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isKnownProperty(t, name)) { + return true; + } + } + return false; + } + return true; + } function hasExcessProperties(source, target, reportErrors) { for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) { var prop = _a[_i]; @@ -14763,7 +14716,7 @@ var ts; return getWidenedTypeOfObjectLiteral(type); } if (type.flags & 16384) { - return getUnionType(ts.map(type.types, getWidenedType)); + return getUnionType(ts.map(type.types, getWidenedType), true); } if (isArrayType(type)) { return createArrayType(getWidenedType(type.typeArguments[0])); @@ -15973,7 +15926,7 @@ var ts; var propertiesTable = {}; var propertiesArray = []; var contextualType = getContextualType(node); - var typeFlags; + var typeFlags = 0; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var memberDecl = _a[_i]; var member = memberDecl.symbol; @@ -16014,7 +15967,8 @@ var ts; var stringIndexType = getIndexType(0); var numberIndexType = getIndexType(1); var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= 524288 | 1048576 | 4194304 | (typeFlags & 14680064); + var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576; + result.flags |= 524288 | 4194304 | freshObjectLiteralFlag | (typeFlags & 14680064); return result; function getIndexType(kind) { if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) { @@ -17260,7 +17214,7 @@ var ts; } function createPromiseType(promisedType) { var globalPromiseType = getGlobalPromiseType(); - if (globalPromiseType !== emptyObjectType) { + if (globalPromiseType !== emptyGenericType) { promisedType = getAwaitedType(promisedType); return createTypeReference(globalPromiseType, [promisedType]); } @@ -19714,6 +19668,7 @@ var ts; if (baseTypes.length && produceDiagnostics) { var baseType = baseTypes[0]; var staticBaseType = getBaseConstructorTypeOfClass(type); + checkSourceElement(baseTypeNode.expression); if (baseTypeNode.typeArguments) { ts.forEach(baseTypeNode.typeArguments, checkSourceElement); for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments); _i < _a.length; _i++) { @@ -20613,6 +20568,8 @@ var ts; case 209: case 210: case 212: + case 241: + case 186: case 215: case 245: case 225: @@ -21338,7 +21295,7 @@ var ts; } function createInstantiatedPromiseLikeType() { var promiseLikeType = getGlobalPromiseLikeType(); - if (promiseLikeType !== emptyObjectType) { + if (promiseLikeType !== emptyGenericType) { return createTypeReference(promiseLikeType, [anyType]); } return emptyObjectType; @@ -24454,8 +24411,12 @@ var ts; } } function emitJsxElement(openingNode, children) { + var syntheticReactRef = ts.createSynthesizedNode(67); + syntheticReactRef.text = 'React'; + syntheticReactRef.parent = openingNode; emitLeadingComments(openingNode); - write("React.createElement("); + emitExpressionIdentifier(syntheticReactRef); + write(".createElement("); emitTagName(openingNode.tagName); write(", "); if (openingNode.attributes.length === 0) { @@ -24464,7 +24425,8 @@ var ts; else { var attrs = openingNode.attributes; if (ts.forEach(attrs, function (attr) { return attr.kind === 237; })) { - write("React.__spread("); + emitExpressionIdentifier(syntheticReactRef); + write(".__spread("); var haveOpenedObjectLiteral = false; for (var i_1 = 0; i_1 < attrs.length; i_1++) { if (attrs[i_1].kind === 237) { @@ -30376,6 +30338,12 @@ var ts; description: ts.Diagnostics.Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, paramType: ts.Diagnostics.LOCATION }, + { + name: "suppressExcessPropertyErrors", + type: "boolean", + description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals, + experimental: true + }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", @@ -30450,7 +30418,7 @@ var ts; return optionNameMapCache; } ts.getOptionNameMap = getOptionNameMap; - function parseCommandLine(commandLine) { + function parseCommandLine(commandLine, readFile) { var options = {}; var fileNames = []; var errors = []; @@ -30509,7 +30477,7 @@ var ts; } } function parseResponseFile(fileName) { - var text = ts.sys.readFile(fileName); + var text = readFile ? readFile(fileName) : ts.sys.readFile(fileName); if (!text) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, fileName)); return; diff --git a/lib/tsserver.js b/lib/tsserver.js index 3c339e6d661..78836160678 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -1573,6 +1573,7 @@ var ts; Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, + Suppress_excess_property_checks_for_object_literals: { code: 6072, category: ts.DiagnosticCategory.Message, key: "Suppress excess property checks for object literals." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -3163,6 +3164,12 @@ var ts; description: ts.Diagnostics.Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, paramType: ts.Diagnostics.LOCATION }, + { + name: "suppressExcessPropertyErrors", + type: "boolean", + description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals, + experimental: true + }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", @@ -3237,7 +3244,7 @@ var ts; return optionNameMapCache; } ts.getOptionNameMap = getOptionNameMap; - function parseCommandLine(commandLine) { + function parseCommandLine(commandLine, readFile) { var options = {}; var fileNames = []; var errors = []; @@ -3296,7 +3303,7 @@ var ts; } } function parseResponseFile(fileName) { - var text = ts.sys.readFile(fileName); + var text = readFile ? readFile(fileName) : ts.sys.readFile(fileName); if (!text) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, fileName)); return; @@ -13136,7 +13143,7 @@ var ts; return members; } function resolveTupleTypeMembers(type) { - var arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes))); + var arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes, true))); var members = createTupleTypeMemberSymbols(type.elementTypes); addInheritedMembers(members, arrayType.properties); setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexType, arrayType.numberIndexType); @@ -13428,25 +13435,6 @@ var ts; } return undefined; } - function isKnownProperty(type, name) { - if (type.flags & 80896 && type !== globalObjectType) { - var resolved = resolveStructuredTypeMembers(type); - return !!(resolved.properties.length === 0 || - resolved.stringIndexType || - resolved.numberIndexType || - getPropertyOfType(type, name)); - } - if (type.flags & 49152) { - for (var _i = 0, _a = type.types; _i < _a.length; _i++) { - var t = _a[_i]; - if (isKnownProperty(t, name)) { - return true; - } - } - return false; - } - return true; - } function getSignaturesOfStructuredType(type, kind) { if (type.flags & 130048) { var resolved = resolveStructuredTypeMembers(type); @@ -13902,7 +13890,7 @@ var ts; } function createTypedPropertyDescriptorType(propertyType) { var globalTypedPropertyDescriptorType = getGlobalTypedPropertyDescriptorType(); - return globalTypedPropertyDescriptorType !== emptyObjectType + return globalTypedPropertyDescriptorType !== emptyGenericType ? createTypeReference(globalTypedPropertyDescriptorType, [propertyType]) : emptyObjectType; } @@ -13955,68 +13943,19 @@ var ts; addTypeToSet(typeSet, type, typeSetKind); } } - function isObjectLiteralTypeDuplicateOf(source, target) { - var sourceProperties = getPropertiesOfObjectType(source); - var targetProperties = getPropertiesOfObjectType(target); - if (sourceProperties.length !== targetProperties.length) { - return false; - } - for (var _i = 0; _i < sourceProperties.length; _i++) { - var sourceProp = sourceProperties[_i]; - var targetProp = getPropertyOfObjectType(target, sourceProp.name); - if (!targetProp || - getDeclarationFlagsFromSymbol(targetProp) & (32 | 64) || - !isTypeDuplicateOf(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp))) { - return false; - } - } - return true; - } - function isTupleTypeDuplicateOf(source, target) { - var sourceTypes = source.elementTypes; - var targetTypes = target.elementTypes; - if (sourceTypes.length !== targetTypes.length) { - return false; - } - for (var i = 0; i < sourceTypes.length; i++) { - if (!isTypeDuplicateOf(sourceTypes[i], targetTypes[i])) { - return false; - } - } - return true; - } - function isTypeDuplicateOf(source, target) { - if (source === target) { - return true; - } - if (source.flags & 32 || source.flags & 64 && !(target.flags & 32)) { - return true; - } - if (source.flags & 524288 && target.flags & 80896) { - return isObjectLiteralTypeDuplicateOf(source, target); - } - if (isArrayType(source) && isArrayType(target)) { - return isTypeDuplicateOf(source.typeArguments[0], target.typeArguments[0]); - } - if (isTupleType(source) && isTupleType(target)) { - return isTupleTypeDuplicateOf(source, target); - } - return isTypeIdenticalTo(source, target); - } - function isTypeDuplicateOfSomeType(candidate, types) { - for (var _i = 0; _i < types.length; _i++) { - var type = types[_i]; - if (candidate !== type && isTypeDuplicateOf(candidate, type)) { + function isSubtypeOfAny(candidate, types) { + for (var i = 0, len = types.length; i < len; i++) { + if (candidate !== types[i] && isTypeSubtypeOf(candidate, types[i])) { return true; } } return false; } - function removeDuplicateTypes(types) { + function removeSubtypes(types) { var i = types.length; while (i > 0) { i--; - if (isTypeDuplicateOfSomeType(types[i], types)) { + if (isSubtypeOfAny(types[i], types)) { types.splice(i, 1); } } @@ -14039,7 +13978,7 @@ var ts; } } } - function getUnionType(types, noDeduplication) { + function getUnionType(types, noSubtypeReduction) { if (types.length === 0) { return emptyObjectType; } @@ -14048,12 +13987,12 @@ var ts; if (containsTypeAny(typeSet)) { return anyType; } - if (noDeduplication) { + if (noSubtypeReduction) { removeAllButLast(typeSet, undefinedType); removeAllButLast(typeSet, nullType); } else { - removeDuplicateTypes(typeSet); + removeSubtypes(typeSet); } if (typeSet.length === 1) { return typeSet[0]; @@ -14547,6 +14486,26 @@ var ts; } return 0; } + function isKnownProperty(type, name) { + if (type.flags & 80896) { + var resolved = resolveStructuredTypeMembers(type); + if (relation === assignableRelation && (type === globalObjectType || resolved.properties.length === 0) || + resolved.stringIndexType || resolved.numberIndexType || getPropertyOfType(type, name)) { + return true; + } + return false; + } + if (type.flags & 49152) { + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isKnownProperty(t, name)) { + return true; + } + } + return false; + } + return true; + } function hasExcessProperties(source, target, reportErrors) { for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) { var prop = _a[_i]; @@ -15219,7 +15178,7 @@ var ts; return getWidenedTypeOfObjectLiteral(type); } if (type.flags & 16384) { - return getUnionType(ts.map(type.types, getWidenedType)); + return getUnionType(ts.map(type.types, getWidenedType), true); } if (isArrayType(type)) { return createArrayType(getWidenedType(type.typeArguments[0])); @@ -16429,7 +16388,7 @@ var ts; var propertiesTable = {}; var propertiesArray = []; var contextualType = getContextualType(node); - var typeFlags; + var typeFlags = 0; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var memberDecl = _a[_i]; var member = memberDecl.symbol; @@ -16470,7 +16429,8 @@ var ts; var stringIndexType = getIndexType(0); var numberIndexType = getIndexType(1); var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= 524288 | 1048576 | 4194304 | (typeFlags & 14680064); + var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576; + result.flags |= 524288 | 4194304 | freshObjectLiteralFlag | (typeFlags & 14680064); return result; function getIndexType(kind) { if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) { @@ -17716,7 +17676,7 @@ var ts; } function createPromiseType(promisedType) { var globalPromiseType = getGlobalPromiseType(); - if (globalPromiseType !== emptyObjectType) { + if (globalPromiseType !== emptyGenericType) { promisedType = getAwaitedType(promisedType); return createTypeReference(globalPromiseType, [promisedType]); } @@ -20170,6 +20130,7 @@ var ts; if (baseTypes.length && produceDiagnostics) { var baseType = baseTypes[0]; var staticBaseType = getBaseConstructorTypeOfClass(type); + checkSourceElement(baseTypeNode.expression); if (baseTypeNode.typeArguments) { ts.forEach(baseTypeNode.typeArguments, checkSourceElement); for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments); _i < _a.length; _i++) { @@ -21069,6 +21030,8 @@ var ts; case 209: case 210: case 212: + case 241: + case 186: case 215: case 245: case 225: @@ -21794,7 +21757,7 @@ var ts; } function createInstantiatedPromiseLikeType() { var promiseLikeType = getGlobalPromiseLikeType(); - if (promiseLikeType !== emptyObjectType) { + if (promiseLikeType !== emptyGenericType) { return createTypeReference(promiseLikeType, [anyType]); } return emptyObjectType; @@ -24910,8 +24873,12 @@ var ts; } } function emitJsxElement(openingNode, children) { + var syntheticReactRef = ts.createSynthesizedNode(67); + syntheticReactRef.text = 'React'; + syntheticReactRef.parent = openingNode; emitLeadingComments(openingNode); - write("React.createElement("); + emitExpressionIdentifier(syntheticReactRef); + write(".createElement("); emitTagName(openingNode.tagName); write(", "); if (openingNode.attributes.length === 0) { @@ -24920,7 +24887,8 @@ var ts; else { var attrs = openingNode.attributes; if (ts.forEach(attrs, function (attr) { return attr.kind === 237; })) { - write("React.__spread("); + emitExpressionIdentifier(syntheticReactRef); + write(".__spread("); var haveOpenedObjectLiteral = false; for (var i_1 = 0; i_1 < attrs.length; i_1++) { if (attrs[i_1].kind === 237) { diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index f94d24269f1..bf0510cf1c8 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -1329,6 +1329,7 @@ declare module "typescript" { rootDir?: string; sourceMap?: boolean; sourceRoot?: string; + suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget; version?: boolean; @@ -1524,7 +1525,7 @@ declare module "typescript" { function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program; } declare module "typescript" { - function parseCommandLine(commandLine: string[]): ParsedCommandLine; + function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine; /** * Read tsconfig.json file * @param fileName The path to the config file diff --git a/lib/typescript.js b/lib/typescript.js index c1105bb262a..b4d21639d3b 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -2442,6 +2442,7 @@ var ts; Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, + Suppress_excess_property_checks_for_object_literals: { code: 6072, category: ts.DiagnosticCategory.Message, key: "Suppress excess property checks for object literals." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -15702,7 +15703,7 @@ var ts; return members; } function resolveTupleTypeMembers(type) { - var arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes))); + var arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes, /*noSubtypeReduction*/ true))); var members = createTupleTypeMemberSymbols(type.elementTypes); addInheritedMembers(members, arrayType.properties); setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexType, arrayType.numberIndexType); @@ -16023,29 +16024,6 @@ var ts; } return undefined; } - // Check if a property with the given name is known anywhere in the given type. In an object - // type, a property is considered known if the object type is empty, if it has any index - // signatures, or if the property is actually declared in the type. In a union or intersection - // type, a property is considered known if it is known in any constituent type. - function isKnownProperty(type, name) { - if (type.flags & 80896 /* ObjectType */ && type !== globalObjectType) { - var resolved = resolveStructuredTypeMembers(type); - return !!(resolved.properties.length === 0 || - resolved.stringIndexType || - resolved.numberIndexType || - getPropertyOfType(type, name)); - } - if (type.flags & 49152 /* UnionOrIntersection */) { - for (var _i = 0, _a = type.types; _i < _a.length; _i++) { - var t = _a[_i]; - if (isKnownProperty(t, name)) { - return true; - } - } - return false; - } - return true; - } function getSignaturesOfStructuredType(type, kind) { if (type.flags & 130048 /* StructuredType */) { var resolved = resolveStructuredTypeMembers(type); @@ -16559,7 +16537,7 @@ var ts; */ function createTypedPropertyDescriptorType(propertyType) { var globalTypedPropertyDescriptorType = getGlobalTypedPropertyDescriptorType(); - return globalTypedPropertyDescriptorType !== emptyObjectType + return globalTypedPropertyDescriptorType !== emptyGenericType ? createTypeReference(globalTypedPropertyDescriptorType, [propertyType]) : emptyObjectType; } @@ -16617,71 +16595,19 @@ var ts; addTypeToSet(typeSet, type, typeSetKind); } } - function isObjectLiteralTypeDuplicateOf(source, target) { - var sourceProperties = getPropertiesOfObjectType(source); - var targetProperties = getPropertiesOfObjectType(target); - if (sourceProperties.length !== targetProperties.length) { - return false; - } - for (var _i = 0; _i < sourceProperties.length; _i++) { - var sourceProp = sourceProperties[_i]; - var targetProp = getPropertyOfObjectType(target, sourceProp.name); - if (!targetProp || - getDeclarationFlagsFromSymbol(targetProp) & (32 /* Private */ | 64 /* Protected */) || - !isTypeDuplicateOf(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp))) { - return false; - } - } - return true; - } - function isTupleTypeDuplicateOf(source, target) { - var sourceTypes = source.elementTypes; - var targetTypes = target.elementTypes; - if (sourceTypes.length !== targetTypes.length) { - return false; - } - for (var i = 0; i < sourceTypes.length; i++) { - if (!isTypeDuplicateOf(sourceTypes[i], targetTypes[i])) { - return false; - } - } - return true; - } - // Returns true if the source type is a duplicate of the target type. A source type is a duplicate of - // a target type if the the two are identical, with the exception that the source type may have null or - // undefined in places where the target type doesn't. This is by design an asymmetric relationship. - function isTypeDuplicateOf(source, target) { - if (source === target) { - return true; - } - if (source.flags & 32 /* Undefined */ || source.flags & 64 /* Null */ && !(target.flags & 32 /* Undefined */)) { - return true; - } - if (source.flags & 524288 /* ObjectLiteral */ && target.flags & 80896 /* ObjectType */) { - return isObjectLiteralTypeDuplicateOf(source, target); - } - if (isArrayType(source) && isArrayType(target)) { - return isTypeDuplicateOf(source.typeArguments[0], target.typeArguments[0]); - } - if (isTupleType(source) && isTupleType(target)) { - return isTupleTypeDuplicateOf(source, target); - } - return isTypeIdenticalTo(source, target); - } - function isTypeDuplicateOfSomeType(candidate, types) { - for (var _i = 0; _i < types.length; _i++) { - var type = types[_i]; - if (candidate !== type && isTypeDuplicateOf(candidate, type)) { + function isSubtypeOfAny(candidate, types) { + for (var i = 0, len = types.length; i < len; i++) { + if (candidate !== types[i] && isTypeSubtypeOf(candidate, types[i])) { return true; } } return false; } - function removeDuplicateTypes(types) { + function removeSubtypes(types) { var i = types.length; while (i > 0) { i--; - if (isTypeDuplicateOfSomeType(types[i], types)) { + if (isSubtypeOfAny(types[i], types)) { types.splice(i, 1); } } @@ -16704,12 +16630,14 @@ var ts; } } } - // We always deduplicate the constituent type set based on object identity, but we'll also deduplicate - // based on the structure of the types unless the noDeduplication flag is true, which is the case when - // creating a union type from a type node and when instantiating a union type. In both of those cases, - // structural deduplication has to be deferred to properly support recursive union types. For example, - // a type of the form "type Item = string | (() => Item)" cannot be deduplicated during its declaration. - function getUnionType(types, noDeduplication) { + // We reduce the constituent type set to only include types that aren't subtypes of other types, unless + // the noSubtypeReduction flag is specified, in which case we perform a simple deduplication based on + // object identity. Subtype reduction is possible only when union types are known not to circularly + // reference themselves (as is the case with union types created by expression constructs such as array + // literals and the || and ?: operators). Named types can circularly reference themselves and therefore + // cannot be deduplicated during their declaration. For example, "type Item = string | (() => Item" is + // a named type that circularly references itself. + function getUnionType(types, noSubtypeReduction) { if (types.length === 0) { return emptyObjectType; } @@ -16718,12 +16646,12 @@ var ts; if (containsTypeAny(typeSet)) { return anyType; } - if (noDeduplication) { + if (noSubtypeReduction) { removeAllButLast(typeSet, undefinedType); removeAllButLast(typeSet, nullType); } else { - removeDuplicateTypes(typeSet); + removeSubtypes(typeSet); } if (typeSet.length === 1) { return typeSet[0]; @@ -16739,7 +16667,7 @@ var ts; function getTypeFromUnionTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), /*noDeduplication*/ true); + links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), /*noSubtypeReduction*/ true); } return links.resolvedType; } @@ -17010,7 +16938,7 @@ var ts; return createTupleType(instantiateList(type.elementTypes, mapper, instantiateType)); } if (type.flags & 16384 /* Union */) { - return getUnionType(instantiateList(type.types, mapper, instantiateType), /*noDeduplication*/ true); + return getUnionType(instantiateList(type.types, mapper, instantiateType), /*noSubtypeReduction*/ true); } if (type.flags & 32768 /* Intersection */) { return getIntersectionType(instantiateList(type.types, mapper, instantiateType)); @@ -17271,6 +17199,30 @@ var ts; } return 0 /* False */; } + // Check if a property with the given name is known anywhere in the given type. In an object type, a property + // is considered known if the object type is empty and the check is for assignability, if the object type has + // index signatures, or if the property is actually declared in the object type. In a union or intersection + // type, a property is considered known if it is known in any constituent type. + function isKnownProperty(type, name) { + if (type.flags & 80896 /* ObjectType */) { + var resolved = resolveStructuredTypeMembers(type); + if (relation === assignableRelation && (type === globalObjectType || resolved.properties.length === 0) || + resolved.stringIndexType || resolved.numberIndexType || getPropertyOfType(type, name)) { + return true; + } + return false; + } + if (type.flags & 49152 /* UnionOrIntersection */) { + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isKnownProperty(t, name)) { + return true; + } + } + return false; + } + return true; + } function hasExcessProperties(source, target, reportErrors) { for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) { var prop = _a[_i]; @@ -17999,7 +17951,7 @@ var ts; return getWidenedTypeOfObjectLiteral(type); } if (type.flags & 16384 /* Union */) { - return getUnionType(ts.map(type.types, getWidenedType)); + return getUnionType(ts.map(type.types, getWidenedType), /*noSubtypeReduction*/ true); } if (isArrayType(type)) { return createArrayType(getWidenedType(type.typeArguments[0])); @@ -19438,7 +19390,7 @@ var ts; var propertiesTable = {}; var propertiesArray = []; var contextualType = getContextualType(node); - var typeFlags; + var typeFlags = 0; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var memberDecl = _a[_i]; var member = memberDecl.symbol; @@ -19484,7 +19436,8 @@ var ts; var stringIndexType = getIndexType(0 /* String */); var numberIndexType = getIndexType(1 /* Number */); var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= 524288 /* ObjectLiteral */ | 1048576 /* FreshObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | (typeFlags & 14680064 /* PropagatingFlags */); + var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576 /* FreshObjectLiteral */; + result.flags |= 524288 /* ObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */); return result; function getIndexType(kind) { if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) { @@ -21216,7 +21169,7 @@ var ts; function createPromiseType(promisedType) { // creates a `Promise` type where `T` is the promisedType argument var globalPromiseType = getGlobalPromiseType(); - if (globalPromiseType !== emptyObjectType) { + if (globalPromiseType !== emptyGenericType) { // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type promisedType = getAwaitedType(promisedType); return createTypeReference(globalPromiseType, [promisedType]); @@ -24248,6 +24201,7 @@ var ts; if (baseTypes.length && produceDiagnostics) { var baseType = baseTypes[0]; var staticBaseType = getBaseConstructorTypeOfClass(type); + checkSourceElement(baseTypeNode.expression); if (baseTypeNode.typeArguments) { ts.forEach(baseTypeNode.typeArguments, checkSourceElement); for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments); _i < _a.length; _i++) { @@ -25227,6 +25181,8 @@ var ts; case 209 /* VariableDeclaration */: case 210 /* VariableDeclarationList */: case 212 /* ClassDeclaration */: + case 241 /* HeritageClause */: + case 186 /* ExpressionWithTypeArguments */: case 215 /* EnumDeclaration */: case 245 /* EnumMember */: case 225 /* ExportAssignment */: @@ -26049,7 +26005,7 @@ var ts; } function createInstantiatedPromiseLikeType() { var promiseLikeType = getGlobalPromiseLikeType(); - if (promiseLikeType !== emptyObjectType) { + if (promiseLikeType !== emptyGenericType) { return createTypeReference(promiseLikeType, [anyType]); } return emptyObjectType; @@ -29500,9 +29456,13 @@ var ts; } } function emitJsxElement(openingNode, children) { + var syntheticReactRef = ts.createSynthesizedNode(67 /* Identifier */); + syntheticReactRef.text = 'React'; + syntheticReactRef.parent = openingNode; // Call React.createElement(tag, ... emitLeadingComments(openingNode); - write("React.createElement("); + emitExpressionIdentifier(syntheticReactRef); + write(".createElement("); emitTagName(openingNode.tagName); write(", "); // Attribute list @@ -29515,7 +29475,8 @@ var ts; // a call to React.__spread var attrs = openingNode.attributes; if (ts.forEach(attrs, function (attr) { return attr.kind === 237 /* JsxSpreadAttribute */; })) { - write("React.__spread("); + emitExpressionIdentifier(syntheticReactRef); + write(".__spread("); var haveOpenedObjectLiteral = false; for (var i_1 = 0; i_1 < attrs.length; i_1++) { if (attrs[i_1].kind === 237 /* JsxSpreadAttribute */) { @@ -36231,6 +36192,12 @@ var ts; description: ts.Diagnostics.Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, paramType: ts.Diagnostics.LOCATION }, + { + name: "suppressExcessPropertyErrors", + type: "boolean", + description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals, + experimental: true + }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", @@ -36306,7 +36273,7 @@ var ts; return optionNameMapCache; } ts.getOptionNameMap = getOptionNameMap; - function parseCommandLine(commandLine) { + function parseCommandLine(commandLine, readFile) { var options = {}; var fileNames = []; var errors = []; @@ -36368,7 +36335,7 @@ var ts; } } function parseResponseFile(fileName) { - var text = ts.sys.readFile(fileName); + var text = readFile ? readFile(fileName) : ts.sys.readFile(fileName); if (!text) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, fileName)); return; diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 812305c8a68..3d4418a9750 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -1329,6 +1329,7 @@ declare namespace ts { rootDir?: string; sourceMap?: boolean; sourceRoot?: string; + suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget; version?: boolean; @@ -1524,7 +1525,7 @@ declare namespace ts { function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program; } declare namespace ts { - function parseCommandLine(commandLine: string[]): ParsedCommandLine; + function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine; /** * Read tsconfig.json file * @param fileName The path to the config file diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index c1105bb262a..b4d21639d3b 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -2442,6 +2442,7 @@ var ts; Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes a TypeScript project and creates a tsconfig.json file." }, Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully created a tsconfig.json file." }, + Suppress_excess_property_checks_for_object_literals: { code: 6072, category: ts.DiagnosticCategory.Message, key: "Suppress excess property checks for object literals." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -15702,7 +15703,7 @@ var ts; return members; } function resolveTupleTypeMembers(type) { - var arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes))); + var arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes, /*noSubtypeReduction*/ true))); var members = createTupleTypeMemberSymbols(type.elementTypes); addInheritedMembers(members, arrayType.properties); setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexType, arrayType.numberIndexType); @@ -16023,29 +16024,6 @@ var ts; } return undefined; } - // Check if a property with the given name is known anywhere in the given type. In an object - // type, a property is considered known if the object type is empty, if it has any index - // signatures, or if the property is actually declared in the type. In a union or intersection - // type, a property is considered known if it is known in any constituent type. - function isKnownProperty(type, name) { - if (type.flags & 80896 /* ObjectType */ && type !== globalObjectType) { - var resolved = resolveStructuredTypeMembers(type); - return !!(resolved.properties.length === 0 || - resolved.stringIndexType || - resolved.numberIndexType || - getPropertyOfType(type, name)); - } - if (type.flags & 49152 /* UnionOrIntersection */) { - for (var _i = 0, _a = type.types; _i < _a.length; _i++) { - var t = _a[_i]; - if (isKnownProperty(t, name)) { - return true; - } - } - return false; - } - return true; - } function getSignaturesOfStructuredType(type, kind) { if (type.flags & 130048 /* StructuredType */) { var resolved = resolveStructuredTypeMembers(type); @@ -16559,7 +16537,7 @@ var ts; */ function createTypedPropertyDescriptorType(propertyType) { var globalTypedPropertyDescriptorType = getGlobalTypedPropertyDescriptorType(); - return globalTypedPropertyDescriptorType !== emptyObjectType + return globalTypedPropertyDescriptorType !== emptyGenericType ? createTypeReference(globalTypedPropertyDescriptorType, [propertyType]) : emptyObjectType; } @@ -16617,71 +16595,19 @@ var ts; addTypeToSet(typeSet, type, typeSetKind); } } - function isObjectLiteralTypeDuplicateOf(source, target) { - var sourceProperties = getPropertiesOfObjectType(source); - var targetProperties = getPropertiesOfObjectType(target); - if (sourceProperties.length !== targetProperties.length) { - return false; - } - for (var _i = 0; _i < sourceProperties.length; _i++) { - var sourceProp = sourceProperties[_i]; - var targetProp = getPropertyOfObjectType(target, sourceProp.name); - if (!targetProp || - getDeclarationFlagsFromSymbol(targetProp) & (32 /* Private */ | 64 /* Protected */) || - !isTypeDuplicateOf(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp))) { - return false; - } - } - return true; - } - function isTupleTypeDuplicateOf(source, target) { - var sourceTypes = source.elementTypes; - var targetTypes = target.elementTypes; - if (sourceTypes.length !== targetTypes.length) { - return false; - } - for (var i = 0; i < sourceTypes.length; i++) { - if (!isTypeDuplicateOf(sourceTypes[i], targetTypes[i])) { - return false; - } - } - return true; - } - // Returns true if the source type is a duplicate of the target type. A source type is a duplicate of - // a target type if the the two are identical, with the exception that the source type may have null or - // undefined in places where the target type doesn't. This is by design an asymmetric relationship. - function isTypeDuplicateOf(source, target) { - if (source === target) { - return true; - } - if (source.flags & 32 /* Undefined */ || source.flags & 64 /* Null */ && !(target.flags & 32 /* Undefined */)) { - return true; - } - if (source.flags & 524288 /* ObjectLiteral */ && target.flags & 80896 /* ObjectType */) { - return isObjectLiteralTypeDuplicateOf(source, target); - } - if (isArrayType(source) && isArrayType(target)) { - return isTypeDuplicateOf(source.typeArguments[0], target.typeArguments[0]); - } - if (isTupleType(source) && isTupleType(target)) { - return isTupleTypeDuplicateOf(source, target); - } - return isTypeIdenticalTo(source, target); - } - function isTypeDuplicateOfSomeType(candidate, types) { - for (var _i = 0; _i < types.length; _i++) { - var type = types[_i]; - if (candidate !== type && isTypeDuplicateOf(candidate, type)) { + function isSubtypeOfAny(candidate, types) { + for (var i = 0, len = types.length; i < len; i++) { + if (candidate !== types[i] && isTypeSubtypeOf(candidate, types[i])) { return true; } } return false; } - function removeDuplicateTypes(types) { + function removeSubtypes(types) { var i = types.length; while (i > 0) { i--; - if (isTypeDuplicateOfSomeType(types[i], types)) { + if (isSubtypeOfAny(types[i], types)) { types.splice(i, 1); } } @@ -16704,12 +16630,14 @@ var ts; } } } - // We always deduplicate the constituent type set based on object identity, but we'll also deduplicate - // based on the structure of the types unless the noDeduplication flag is true, which is the case when - // creating a union type from a type node and when instantiating a union type. In both of those cases, - // structural deduplication has to be deferred to properly support recursive union types. For example, - // a type of the form "type Item = string | (() => Item)" cannot be deduplicated during its declaration. - function getUnionType(types, noDeduplication) { + // We reduce the constituent type set to only include types that aren't subtypes of other types, unless + // the noSubtypeReduction flag is specified, in which case we perform a simple deduplication based on + // object identity. Subtype reduction is possible only when union types are known not to circularly + // reference themselves (as is the case with union types created by expression constructs such as array + // literals and the || and ?: operators). Named types can circularly reference themselves and therefore + // cannot be deduplicated during their declaration. For example, "type Item = string | (() => Item" is + // a named type that circularly references itself. + function getUnionType(types, noSubtypeReduction) { if (types.length === 0) { return emptyObjectType; } @@ -16718,12 +16646,12 @@ var ts; if (containsTypeAny(typeSet)) { return anyType; } - if (noDeduplication) { + if (noSubtypeReduction) { removeAllButLast(typeSet, undefinedType); removeAllButLast(typeSet, nullType); } else { - removeDuplicateTypes(typeSet); + removeSubtypes(typeSet); } if (typeSet.length === 1) { return typeSet[0]; @@ -16739,7 +16667,7 @@ var ts; function getTypeFromUnionTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), /*noDeduplication*/ true); + links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), /*noSubtypeReduction*/ true); } return links.resolvedType; } @@ -17010,7 +16938,7 @@ var ts; return createTupleType(instantiateList(type.elementTypes, mapper, instantiateType)); } if (type.flags & 16384 /* Union */) { - return getUnionType(instantiateList(type.types, mapper, instantiateType), /*noDeduplication*/ true); + return getUnionType(instantiateList(type.types, mapper, instantiateType), /*noSubtypeReduction*/ true); } if (type.flags & 32768 /* Intersection */) { return getIntersectionType(instantiateList(type.types, mapper, instantiateType)); @@ -17271,6 +17199,30 @@ var ts; } return 0 /* False */; } + // Check if a property with the given name is known anywhere in the given type. In an object type, a property + // is considered known if the object type is empty and the check is for assignability, if the object type has + // index signatures, or if the property is actually declared in the object type. In a union or intersection + // type, a property is considered known if it is known in any constituent type. + function isKnownProperty(type, name) { + if (type.flags & 80896 /* ObjectType */) { + var resolved = resolveStructuredTypeMembers(type); + if (relation === assignableRelation && (type === globalObjectType || resolved.properties.length === 0) || + resolved.stringIndexType || resolved.numberIndexType || getPropertyOfType(type, name)) { + return true; + } + return false; + } + if (type.flags & 49152 /* UnionOrIntersection */) { + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isKnownProperty(t, name)) { + return true; + } + } + return false; + } + return true; + } function hasExcessProperties(source, target, reportErrors) { for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) { var prop = _a[_i]; @@ -17999,7 +17951,7 @@ var ts; return getWidenedTypeOfObjectLiteral(type); } if (type.flags & 16384 /* Union */) { - return getUnionType(ts.map(type.types, getWidenedType)); + return getUnionType(ts.map(type.types, getWidenedType), /*noSubtypeReduction*/ true); } if (isArrayType(type)) { return createArrayType(getWidenedType(type.typeArguments[0])); @@ -19438,7 +19390,7 @@ var ts; var propertiesTable = {}; var propertiesArray = []; var contextualType = getContextualType(node); - var typeFlags; + var typeFlags = 0; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var memberDecl = _a[_i]; var member = memberDecl.symbol; @@ -19484,7 +19436,8 @@ var ts; var stringIndexType = getIndexType(0 /* String */); var numberIndexType = getIndexType(1 /* Number */); var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= 524288 /* ObjectLiteral */ | 1048576 /* FreshObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | (typeFlags & 14680064 /* PropagatingFlags */); + var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576 /* FreshObjectLiteral */; + result.flags |= 524288 /* ObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */); return result; function getIndexType(kind) { if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) { @@ -21216,7 +21169,7 @@ var ts; function createPromiseType(promisedType) { // creates a `Promise` type where `T` is the promisedType argument var globalPromiseType = getGlobalPromiseType(); - if (globalPromiseType !== emptyObjectType) { + if (globalPromiseType !== emptyGenericType) { // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type promisedType = getAwaitedType(promisedType); return createTypeReference(globalPromiseType, [promisedType]); @@ -24248,6 +24201,7 @@ var ts; if (baseTypes.length && produceDiagnostics) { var baseType = baseTypes[0]; var staticBaseType = getBaseConstructorTypeOfClass(type); + checkSourceElement(baseTypeNode.expression); if (baseTypeNode.typeArguments) { ts.forEach(baseTypeNode.typeArguments, checkSourceElement); for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments); _i < _a.length; _i++) { @@ -25227,6 +25181,8 @@ var ts; case 209 /* VariableDeclaration */: case 210 /* VariableDeclarationList */: case 212 /* ClassDeclaration */: + case 241 /* HeritageClause */: + case 186 /* ExpressionWithTypeArguments */: case 215 /* EnumDeclaration */: case 245 /* EnumMember */: case 225 /* ExportAssignment */: @@ -26049,7 +26005,7 @@ var ts; } function createInstantiatedPromiseLikeType() { var promiseLikeType = getGlobalPromiseLikeType(); - if (promiseLikeType !== emptyObjectType) { + if (promiseLikeType !== emptyGenericType) { return createTypeReference(promiseLikeType, [anyType]); } return emptyObjectType; @@ -29500,9 +29456,13 @@ var ts; } } function emitJsxElement(openingNode, children) { + var syntheticReactRef = ts.createSynthesizedNode(67 /* Identifier */); + syntheticReactRef.text = 'React'; + syntheticReactRef.parent = openingNode; // Call React.createElement(tag, ... emitLeadingComments(openingNode); - write("React.createElement("); + emitExpressionIdentifier(syntheticReactRef); + write(".createElement("); emitTagName(openingNode.tagName); write(", "); // Attribute list @@ -29515,7 +29475,8 @@ var ts; // a call to React.__spread var attrs = openingNode.attributes; if (ts.forEach(attrs, function (attr) { return attr.kind === 237 /* JsxSpreadAttribute */; })) { - write("React.__spread("); + emitExpressionIdentifier(syntheticReactRef); + write(".__spread("); var haveOpenedObjectLiteral = false; for (var i_1 = 0; i_1 < attrs.length; i_1++) { if (attrs[i_1].kind === 237 /* JsxSpreadAttribute */) { @@ -36231,6 +36192,12 @@ var ts; description: ts.Diagnostics.Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, paramType: ts.Diagnostics.LOCATION }, + { + name: "suppressExcessPropertyErrors", + type: "boolean", + description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals, + experimental: true + }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", @@ -36306,7 +36273,7 @@ var ts; return optionNameMapCache; } ts.getOptionNameMap = getOptionNameMap; - function parseCommandLine(commandLine) { + function parseCommandLine(commandLine, readFile) { var options = {}; var fileNames = []; var errors = []; @@ -36368,7 +36335,7 @@ var ts; } } function parseResponseFile(fileName) { - var text = ts.sys.readFile(fileName); + var text = readFile ? readFile(fileName) : ts.sys.readFile(fileName); if (!text) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, fileName)); return; diff --git a/package.json b/package.json index b743b04838d..abd81e12f47 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "1.7.0", + "version": "1.6.0", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f71009c7b65..739f5341a3c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4013,7 +4013,7 @@ namespace ts { */ function createTypedPropertyDescriptorType(propertyType: Type): Type { let globalTypedPropertyDescriptorType = getGlobalTypedPropertyDescriptorType(); - return globalTypedPropertyDescriptorType !== emptyObjectType + return globalTypedPropertyDescriptorType !== emptyGenericType ? createTypeReference(globalTypedPropertyDescriptorType, [propertyType]) : emptyObjectType; } @@ -9132,7 +9132,7 @@ namespace ts { function createPromiseType(promisedType: Type): Type { // creates a `Promise` type where `T` is the promisedType argument let globalPromiseType = getGlobalPromiseType(); - if (globalPromiseType !== emptyObjectType) { + if (globalPromiseType !== emptyGenericType) { // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type promisedType = getAwaitedType(promisedType); return createTypeReference(globalPromiseType, [promisedType]); @@ -14589,7 +14589,7 @@ namespace ts { function createInstantiatedPromiseLikeType(): ObjectType { let promiseLikeType = getGlobalPromiseLikeType(); - if (promiseLikeType !== emptyObjectType) { + if (promiseLikeType !== emptyGenericType) { return createTypeReference(promiseLikeType, [anyType]); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c56a18b3ab2..d22bc986688 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -379,10 +379,10 @@ namespace ts { * Read tsconfig.json file * @param fileName The path to the config file */ - export function readConfigFile(fileName: string): { config?: any; error?: Diagnostic } { + export function readConfigFile(fileName: string, readFile: (path: string) => string): { config?: any; error?: Diagnostic } { let text = ""; try { - text = sys.readFile(fileName); + text = readFile(fileName); } catch (e) { return { error: createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message) }; diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index f7351bf6912..7935540356e 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -244,7 +244,7 @@ namespace ts { Property_0_does_not_exist_on_type_1: { code: 2339, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on type '{1}'." }, Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: { code: 2340, category: DiagnosticCategory.Error, key: "Only public and protected methods of the base class are accessible via the 'super' keyword." }, Property_0_is_private_and_only_accessible_within_class_1: { code: 2341, category: DiagnosticCategory.Error, key: "Property '{0}' is private and only accessible within class '{1}'." }, - An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: { code: 2342, category: DiagnosticCategory.Error, key: "An index expression argument must be of type 'string', 'number', 'symbol, or 'any'." }, + An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: { code: 2342, category: DiagnosticCategory.Error, key: "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'." }, Type_0_does_not_satisfy_the_constraint_1: { code: 2344, category: DiagnosticCategory.Error, key: "Type '{0}' does not satisfy the constraint '{1}'." }, Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: { code: 2345, category: DiagnosticCategory.Error, key: "Argument of type '{0}' is not assignable to parameter of type '{1}'." }, Supplied_parameters_do_not_match_any_signature_of_call_target: { code: 2346, category: DiagnosticCategory.Error, key: "Supplied parameters do not match any signature of call target." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9fd08ef9bca..0b4c0fdf974 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -965,7 +965,7 @@ "category": "Error", "code": 2341 }, - "An index expression argument must be of type 'string', 'number', 'symbol, or 'any'.": { + "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.": { "category": "Error", "code": 2342 }, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index eeaab6d2123..d84b7b70ada 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4939,63 +4939,61 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function emitSerializedTypeNode(node: TypeNode) { - if (!node) { - return; + if (node) { + + switch (node.kind) { + case SyntaxKind.VoidKeyword: + write("void 0"); + return; + + case SyntaxKind.ParenthesizedType: + emitSerializedTypeNode((node).type); + return; + + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + write("Function"); + return; + + case SyntaxKind.ArrayType: + case SyntaxKind.TupleType: + write("Array"); + return; + + case SyntaxKind.TypePredicate: + case SyntaxKind.BooleanKeyword: + write("Boolean"); + return; + + case SyntaxKind.StringKeyword: + case SyntaxKind.StringLiteral: + write("String"); + return; + + case SyntaxKind.NumberKeyword: + write("Number"); + return; + + case SyntaxKind.SymbolKeyword: + write("Symbol"); + return; + + case SyntaxKind.TypeReference: + emitSerializedTypeReferenceNode(node); + return; + + case SyntaxKind.TypeQuery: + case SyntaxKind.TypeLiteral: + case SyntaxKind.UnionType: + case SyntaxKind.IntersectionType: + case SyntaxKind.AnyKeyword: + break; + + default: + Debug.fail("Cannot serialize unexpected type node."); + break; + } } - - switch (node.kind) { - case SyntaxKind.VoidKeyword: - write("void 0"); - return; - - case SyntaxKind.ParenthesizedType: - emitSerializedTypeNode((node).type); - return; - - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - write("Function"); - return; - - case SyntaxKind.ArrayType: - case SyntaxKind.TupleType: - write("Array"); - return; - - case SyntaxKind.TypePredicate: - case SyntaxKind.BooleanKeyword: - write("Boolean"); - return; - - case SyntaxKind.StringKeyword: - case SyntaxKind.StringLiteral: - write("String"); - return; - - case SyntaxKind.NumberKeyword: - write("Number"); - return; - - case SyntaxKind.SymbolKeyword: - write("Symbol"); - return; - - case SyntaxKind.TypeReference: - emitSerializedTypeReferenceNode(node); - return; - - case SyntaxKind.TypeQuery: - case SyntaxKind.TypeLiteral: - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - case SyntaxKind.AnyKeyword: - break; - - default: - Debug.fail("Cannot serialize unexpected type node."); - break; - } - write("Object"); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 402b413dd9c..a1861f6b462 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -12,7 +12,7 @@ namespace ts { let emptyArray: any[] = []; - export const version = "1.7.0"; + export const version = "1.6.0"; export function findConfigFile(searchPath: string): string { let fileName = "tsconfig.json"; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 8c0a6d4e8c4..96759b68250 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -216,7 +216,7 @@ namespace ts { if (!cachedProgram) { if (configFileName) { - let result = readConfigFile(configFileName); + let result = readConfigFile(configFileName, sys.readFile); if (result.error) { reportDiagnostic(result.error); return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped); diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index a3b32099cca..73ba80ca046 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -32,7 +32,7 @@ namespace ts.formatting { */ interface DynamicIndentation { getIndentationForToken(tokenLine: number, tokenKind: SyntaxKind): number; - getIndentationForComment(owningToken: SyntaxKind): number; + getIndentationForComment(owningToken: SyntaxKind, tokenIndentation: number): number; /** * Indentation for open and close tokens of the node if it is block or another node that needs special indentation * ... { @@ -461,7 +461,7 @@ namespace ts.formatting { function getDynamicIndentation(node: Node, nodeStartLine: number, indentation: number, delta: number): DynamicIndentation { return { - getIndentationForComment: kind => { + getIndentationForComment: (kind, tokenIndentation) => { switch (kind) { // preceding comment to the token that closes the indentation scope inherits the indentation from the scope // .. { @@ -469,9 +469,10 @@ namespace ts.formatting { // } case SyntaxKind.CloseBraceToken: case SyntaxKind.CloseBracketToken: + case SyntaxKind.CloseParenToken: return indentation + delta; } - return indentation; + return tokenIndentation !== Constants.Unknown ? tokenIndentation : indentation; }, getIndentationForToken: (line, kind) => { if (nodeStartLine !== line && node.decorators) { @@ -722,8 +723,14 @@ namespace ts.formatting { } if (indentToken) { - let indentNextTokenOrTrivia = true; + let tokenIndentation = (isTokenInRange && !rangeContainsError(currentTokenInfo.token)) ? + dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind) : + Constants.Unknown; + if (currentTokenInfo.leadingTrivia) { + let commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation); + let indentNextTokenOrTrivia = true; + for (let triviaItem of currentTokenInfo.leadingTrivia) { if (!rangeContainsRange(originalRange, triviaItem)) { continue; @@ -731,13 +738,11 @@ namespace ts.formatting { switch (triviaItem.kind) { case SyntaxKind.MultiLineCommentTrivia: - let commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind); indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia); indentNextTokenOrTrivia = false; break; case SyntaxKind.SingleLineCommentTrivia: if (indentNextTokenOrTrivia) { - let commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind); insertIndentation(triviaItem.pos, commentIndentation, /*lineAdded*/ false); indentNextTokenOrTrivia = false; } @@ -750,8 +755,7 @@ namespace ts.formatting { } // indent token only if is it is in target range and does not overlap with any error ranges - if (isTokenInRange && !rangeContainsError(currentTokenInfo.token)) { - let tokenIndentation = dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind); + if (tokenIndentation !== Constants.Unknown) { insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAdded); lastIndentedLine = tokenStart.line; diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 7e77878051c..6f6167d6ba9 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -17,7 +17,8 @@ namespace ts.formatting { Scan, RescanGreaterThanToken, RescanSlashToken, - RescanTemplateToken + RescanTemplateToken, + RescanJsxIdentifier } export function getFormattingScanner(sourceFile: SourceFile, startPos: number, endPos: number): FormattingScanner { @@ -108,6 +109,20 @@ namespace ts.formatting { return false; } + + function shouldRescanJsxIdentifier(node: Node): boolean { + if (node.parent) { + switch(node.parent.kind) { + case SyntaxKind.JsxAttribute: + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxClosingElement: + case SyntaxKind.JsxSelfClosingElement: + return node.kind === SyntaxKind.Identifier; + } + } + + return false; + } function shouldRescanSlashToken(container: Node): boolean { return container.kind === SyntaxKind.RegularExpressionLiteral; @@ -141,7 +156,9 @@ namespace ts.formatting { ? ScanAction.RescanSlashToken : shouldRescanTemplateToken(n) ? ScanAction.RescanTemplateToken - : ScanAction.Scan + : shouldRescanJsxIdentifier(n) + ? ScanAction.RescanJsxIdentifier + : ScanAction.Scan if (lastTokenInfo && expectedScanAction === lastScanAction) { // readTokenInfo was called before with the same expected scan action. @@ -176,6 +193,10 @@ namespace ts.formatting { currentToken = scanner.reScanTemplateToken(); lastScanAction = ScanAction.RescanTemplateToken; } + else if (expectedScanAction === ScanAction.RescanJsxIdentifier && currentToken === SyntaxKind.Identifier) { + currentToken = scanner.scanJsxIdentifier(); + lastScanAction = ScanAction.RescanJsxIdentifier; + } else { lastScanAction = ScanAction.Scan; } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 5b3d93615f7..ff751ca00cc 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -430,9 +430,10 @@ namespace ts.formatting { case SyntaxKind.ConditionalExpression: case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.JsxElement: + case SyntaxKind.JsxElement: case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxExpression: + case SyntaxKind.JsxSelfClosingElement: + case SyntaxKind.JsxExpression: case SyntaxKind.MethodSignature: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: diff --git a/tests/baselines/reference/decoratorMetadataOnInferredType.js b/tests/baselines/reference/decoratorMetadataOnInferredType.js new file mode 100644 index 00000000000..8103dbbdafa --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataOnInferredType.js @@ -0,0 +1,39 @@ +//// [decoratorMetadataOnInferredType.ts] + +declare var console: { + log(msg: string): void; +}; + +class A { + constructor() { console.log('new A'); } +} + +function decorator(target: Object, propertyKey: string) { +} + +export class B { + @decorator + x = new A(); +} + + +//// [decoratorMetadataOnInferredType.js] +var A = (function () { + function A() { + console.log('new A'); + } + return A; +})(); +function decorator(target, propertyKey) { +} +var B = (function () { + function B() { + this.x = new A(); + } + __decorate([ + decorator, + __metadata('design:type', Object) + ], B.prototype, "x"); + return B; +})(); +exports.B = B; diff --git a/tests/baselines/reference/decoratorMetadataOnInferredType.symbols b/tests/baselines/reference/decoratorMetadataOnInferredType.symbols new file mode 100644 index 00000000000..e1507c75e94 --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataOnInferredType.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/decoratorMetadataOnInferredType.ts === + +declare var console: { +>console : Symbol(console, Decl(decoratorMetadataOnInferredType.ts, 1, 11)) + + log(msg: string): void; +>log : Symbol(log, Decl(decoratorMetadataOnInferredType.ts, 1, 22)) +>msg : Symbol(msg, Decl(decoratorMetadataOnInferredType.ts, 2, 8)) + +}; + +class A { +>A : Symbol(A, Decl(decoratorMetadataOnInferredType.ts, 3, 2)) + + constructor() { console.log('new A'); } +>console.log : Symbol(log, Decl(decoratorMetadataOnInferredType.ts, 1, 22)) +>console : Symbol(console, Decl(decoratorMetadataOnInferredType.ts, 1, 11)) +>log : Symbol(log, Decl(decoratorMetadataOnInferredType.ts, 1, 22)) +} + +function decorator(target: Object, propertyKey: string) { +>decorator : Symbol(decorator, Decl(decoratorMetadataOnInferredType.ts, 7, 1)) +>target : Symbol(target, Decl(decoratorMetadataOnInferredType.ts, 9, 19)) +>Object : Symbol(Object, Decl(lib.d.ts, 92, 1), Decl(lib.d.ts, 223, 11)) +>propertyKey : Symbol(propertyKey, Decl(decoratorMetadataOnInferredType.ts, 9, 34)) +} + +export class B { +>B : Symbol(B, Decl(decoratorMetadataOnInferredType.ts, 10, 1)) + + @decorator +>decorator : Symbol(decorator, Decl(decoratorMetadataOnInferredType.ts, 7, 1)) + + x = new A(); +>x : Symbol(x, Decl(decoratorMetadataOnInferredType.ts, 12, 16)) +>A : Symbol(A, Decl(decoratorMetadataOnInferredType.ts, 3, 2)) +} + diff --git a/tests/baselines/reference/decoratorMetadataOnInferredType.types b/tests/baselines/reference/decoratorMetadataOnInferredType.types new file mode 100644 index 00000000000..41c9334244f --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataOnInferredType.types @@ -0,0 +1,41 @@ +=== tests/cases/compiler/decoratorMetadataOnInferredType.ts === + +declare var console: { +>console : { log(msg: string): void; } + + log(msg: string): void; +>log : (msg: string) => void +>msg : string + +}; + +class A { +>A : A + + constructor() { console.log('new A'); } +>console.log('new A') : void +>console.log : (msg: string) => void +>console : { log(msg: string): void; } +>log : (msg: string) => void +>'new A' : string +} + +function decorator(target: Object, propertyKey: string) { +>decorator : (target: Object, propertyKey: string) => void +>target : Object +>Object : Object +>propertyKey : string +} + +export class B { +>B : B + + @decorator +>decorator : (target: Object, propertyKey: string) => void + + x = new A(); +>x : A +>new A() : A +>A : typeof A +} + diff --git a/tests/baselines/reference/indexTypeCheck.errors.txt b/tests/baselines/reference/indexTypeCheck.errors.txt index 9e003197e41..2ea5a2f413a 100644 --- a/tests/baselines/reference/indexTypeCheck.errors.txt +++ b/tests/baselines/reference/indexTypeCheck.errors.txt @@ -4,7 +4,7 @@ tests/cases/compiler/indexTypeCheck.ts(17,2): error TS2413: Numeric index type ' tests/cases/compiler/indexTypeCheck.ts(27,2): error TS2413: Numeric index type 'number' is not assignable to string index type 'string'. tests/cases/compiler/indexTypeCheck.ts(32,3): error TS1096: An index signature must have exactly one parameter. tests/cases/compiler/indexTypeCheck.ts(36,3): error TS1023: An index signature parameter type must be 'string' or 'number'. -tests/cases/compiler/indexTypeCheck.ts(51,1): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +tests/cases/compiler/indexTypeCheck.ts(51,1): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. ==== tests/cases/compiler/indexTypeCheck.ts (7 errors) ==== @@ -72,7 +72,7 @@ tests/cases/compiler/indexTypeCheck.ts(51,1): error TS2342: An index expression yellow[blue]; // error ~~~~~~~~~~~~ -!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. var x:number[]; x[0]; diff --git a/tests/baselines/reference/objectCreationOfElementAccessExpression.errors.txt b/tests/baselines/reference/objectCreationOfElementAccessExpression.errors.txt index b2f3bd9d824..ef50db9e4e5 100644 --- a/tests/baselines/reference/objectCreationOfElementAccessExpression.errors.txt +++ b/tests/baselines/reference/objectCreationOfElementAccessExpression.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/objectCreationOfElementAccessExpression.ts(53,17): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +tests/cases/compiler/objectCreationOfElementAccessExpression.ts(53,17): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. tests/cases/compiler/objectCreationOfElementAccessExpression.ts(53,63): error TS2348: Value of type 'typeof Cookie' is not callable. Did you mean to include 'new'? -tests/cases/compiler/objectCreationOfElementAccessExpression.ts(54,33): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +tests/cases/compiler/objectCreationOfElementAccessExpression.ts(54,33): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. tests/cases/compiler/objectCreationOfElementAccessExpression.ts(54,79): error TS2348: Value of type 'typeof Cookie' is not callable. Did you mean to include 'new'? @@ -59,12 +59,12 @@ tests/cases/compiler/objectCreationOfElementAccessExpression.ts(54,79): error TS // ElementAccessExpressions can only contain one expression. There should be a parse error here. var foods = new PetFood[new IceCream('Mint chocolate chip') , Cookie('Chocolate chip', false) , new Cookie('Peanut butter', true)]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2348: Value of type 'typeof Cookie' is not callable. Did you mean to include 'new'? var foods2: MonsterFood[] = new PetFood[new IceCream('Mint chocolate chip') , Cookie('Chocolate chip', false) , new Cookie('Peanut butter', true)]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2348: Value of type 'typeof Cookie' is not callable. Did you mean to include 'new'? \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccess.errors.txt b/tests/baselines/reference/propertyAccess.errors.txt index d9cd90a48fc..7d496f87751 100644 --- a/tests/baselines/reference/propertyAccess.errors.txt +++ b/tests/baselines/reference/propertyAccess.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(45,14): error TS2339: Property 'qqq' does not exist on type '{ 10: string; x: string; y: number; z: { n: string; m: number; o: () => boolean; }; 'literal property': number; }'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(80,10): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(117,10): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(140,12): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(80,10): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. +tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(117,10): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. +tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(140,12): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. ==== tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts (4 errors) ==== @@ -88,7 +88,7 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(140,12): er // Bracket notation property access using value of other type on type with numeric index signature and no string index signature var ll = numIndex[someObject]; // Error ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. // Bracket notation property access using string value on type with string index signature and no numeric index signature var mm = strIndex['N']; @@ -127,7 +127,7 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(140,12): er // Bracket notation property access using values of other types on type with no index signatures var uu = noIndex[someObject]; // Error ~~~~~~~~~~~~~~~~~~~ -!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. // Bracket notation property access using numeric value on type with numeric index signature and string index signature var vv = noIndex[32]; @@ -152,7 +152,7 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(140,12): er // Bracket notation property access using value of other type on type with numeric index signature and no string index signature and string index signature var zzzz = bothIndex[someObject]; // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. var x1 = numIndex[stringOrNumber]; var x1: any; diff --git a/tests/baselines/reference/superSymbolIndexedAccess3.errors.txt b/tests/baselines/reference/superSymbolIndexedAccess3.errors.txt index 7f25510e00b..1cac31dec40 100644 --- a/tests/baselines/reference/superSymbolIndexedAccess3.errors.txt +++ b/tests/baselines/reference/superSymbolIndexedAccess3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts(11,16): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts(11,16): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. ==== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts (1 errors) ==== @@ -14,6 +14,6 @@ tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess [symbol]() { return super[Bar](); ~~~~~~~~~~ -!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. } } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty53.errors.txt b/tests/baselines/reference/symbolProperty53.errors.txt index 7658744eb55..03002cd92b2 100644 --- a/tests/baselines/reference/symbolProperty53.errors.txt +++ b/tests/baselines/reference/symbolProperty53.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/Symbols/symbolProperty53.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. -tests/cases/conformance/es6/Symbols/symbolProperty53.ts(5,1): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. +tests/cases/conformance/es6/Symbols/symbolProperty53.ts(5,1): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. ==== tests/cases/conformance/es6/Symbols/symbolProperty53.ts (2 errors) ==== @@ -11,4 +11,4 @@ tests/cases/conformance/es6/Symbols/symbolProperty53.ts(5,1): error TS2342: An i obj[Symbol.for]; ~~~~~~~~~~~~~~~ -!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. \ No newline at end of file +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. \ No newline at end of file diff --git a/tests/cases/compiler/decoratorMetadataOnInferredType.ts b/tests/cases/compiler/decoratorMetadataOnInferredType.ts new file mode 100644 index 00000000000..170afe3b3e5 --- /dev/null +++ b/tests/cases/compiler/decoratorMetadataOnInferredType.ts @@ -0,0 +1,21 @@ +// @noemithelpers: true +// @experimentaldecorators: true +// @emitdecoratormetadata: true +// @target: es5 +// @module: commonjs + +declare var console: { + log(msg: string): void; +}; + +class A { + constructor() { console.log('new A'); } +} + +function decorator(target: Object, propertyKey: string) { +} + +export class B { + @decorator + x = new A(); +} diff --git a/tests/cases/fourslash/formatComments.ts b/tests/cases/fourslash/formatComments.ts new file mode 100644 index 00000000000..083ba6c078d --- /dev/null +++ b/tests/cases/fourslash/formatComments.ts @@ -0,0 +1,24 @@ +/// + +////_.chain() +////// wow/*callChain1*/ +//// .then() +////// waa/*callChain2*/ +//// .then(); +////wow( +//// 3, +////// uaa/*argument1*/ +//// 4 +////// wua/*argument2*/ +////); + +format.document(); + +goTo.marker("callChain1"); +verify.currentLineContentIs(" // wow"); +goTo.marker("callChain2"); +verify.currentLineContentIs(" // waa"); +goTo.marker("argument1"); +verify.currentLineContentIs(" // uaa"); +goTo.marker("argument2"); +verify.currentLineContentIs(" // wua"); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingJsxElements.ts b/tests/cases/fourslash/formattingJsxElements.ts index 3b98e7b5ca4..fbe4bb5d29e 100644 --- a/tests/cases/fourslash/formattingJsxElements.ts +++ b/tests/cases/fourslash/formattingJsxElements.ts @@ -1,16 +1,53 @@ /// //@Filename: file.tsx -////function () { +////function foo0() { //// return ( ////
////Hello, World!/*autoformat*/ /////*indent*/ -////
/*closingTagAutoformat*/ +//// +//// ) +////} +//// +////function foo1() { +//// return ( +////
+////Hello, World!/*autoformat1*/ +/////*indent1*/ +////
//// ) ////} //// -////function () { +////function foo2() { +//// return ( +////
/*2*/ +////Hello, World!/*autoformat2*/ +/////*indent2*/ +////
+//// ) +////} +////function foo3() { +//// return ( +//// /*4*/ +//// Hello, World!/*autoformat3*/ +//// /*indent3*/ +//// +//// ) +////} +////function foo4() { +//// return ( +//// /*6*/ +//// ) +////} +//// +////(function () { //// return
/*danglingBracketAutoformat*/ -////
-////} +//// /*closingTagAutoformat*/ +////}) //// ////let h5 =
/////*childJsxElementAutoformat*/ /////*childJsxElementIndent*/ /////*grandchildJsxElementAutoformat*/ /////*containedClosingTagAutoformat*/ -////
+//// format.document(); goTo.marker("autoformat"); verify.currentLineContentIs(' Hello, World!'); goTo.marker("indent"); verify.indentationIs(12); -goTo.marker("closingTagAutoformat"); -verify.currentLineContentIs(" "); + +goTo.marker("autoformat1"); +verify.currentLineContentIs(' Hello, World!'); +goTo.marker("indent1"); +verify.indentationIs(12); + +goTo.marker("1"); +verify.currentLineContentIs(' class1= {'); +goTo.marker("2"); +verify.currentLineContentIs(' }>'); + +goTo.marker("autoformat2"); +verify.currentLineContentIs(' Hello, World!'); +goTo.marker("indent2"); +verify.indentationIs(12); + +goTo.marker("3"); +verify.currentLineContentIs(' class2= {'); +goTo.marker("4"); +verify.currentLineContentIs(' }>'); + +goTo.marker("autoformat3"); +verify.currentLineContentIs(' Hello, World!'); +goTo.marker("indent3"); +verify.indentationIs(12); + +goTo.marker("5"); +verify.currentLineContentIs(' class3= {'); +goTo.marker("6"); +verify.currentLineContentIs(' }/>'); + goTo.marker("attrAutoformat"); verify.currentLineContentIs(' className=""'); @@ -46,11 +112,11 @@ verify.currentLineContentIs(' "abc" + "cde"'); goTo.marker("expressionIndent"); verify.indentationIs(12); - goTo.marker("danglingBracketAutoformat") // TODO: verify.currentLineContentIs(" >"); -verify.currentLineContentIs(" >"); - +verify.currentLineContentIs(" >"); +goTo.marker("closingTagAutoformat"); +verify.currentLineContentIs(" "); goTo.marker("childJsxElementAutoformat"); verify.currentLineContentIs(" ");