diff --git a/Jakefile.js b/Jakefile.js index b62cbed3279..7024ad2afdf 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -163,13 +163,13 @@ var harnessSources = harnessCoreSources.concat([ })); var librarySourceMap = [ - { target: "lib.core.d.ts", sources: ["core.d.ts"] }, + { target: "lib.core.d.ts", sources: ["header.d.ts", "core.d.ts"] }, { target: "lib.dom.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "dom.generated.d.ts"], }, { target: "lib.webworker.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "webworker.generated.d.ts"], }, { target: "lib.scriptHost.d.ts", sources: ["importcore.d.ts", "scriptHost.d.ts"], }, - { target: "lib.d.ts", sources: ["core.d.ts", "intl.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"], }, - { target: "lib.core.es6.d.ts", sources: ["core.d.ts", "es6.d.ts"]}, - { target: "lib.es6.d.ts", sources: ["es6.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] } + { target: "lib.d.ts", sources: ["header.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"], }, + { target: "lib.core.es6.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts"]}, + { target: "lib.es6.d.ts", sources: ["header.d.ts", "es6.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] } ]; var libraryTargets = librarySourceMap.map(function (f) { @@ -893,6 +893,7 @@ function getLinterOptions() { function lintFileContents(options, path, contents) { var ll = new Linter(path, contents, options); + console.log("Linting '" + path + "'.") return ll.lint(); } diff --git a/lib/typescript.js b/lib/typescript.js index 1e2f51f5aae..6608f585b61 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -5037,7 +5037,7 @@ var ts; * Given an super call\property node returns a closest node where either * - super call\property is legal in the node and not legal in the parent node the node. * i.e. super call is legal in constructor but not legal in the class body. - * - node is arrow function (so caller might need to call getSuperContainer in case if he needs to climb higher) + * - node is arrow function (so caller might need to call getSuperContainer in case it needs to climb higher) * - super call\property is definitely illegal in the node (but might be legal in some subnode) * i.e. super property access is illegal in function declaration but can be legal in the statement list */ diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 1e2f51f5aae..6608f585b61 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -5037,7 +5037,7 @@ var ts; * Given an super call\property node returns a closest node where either * - super call\property is legal in the node and not legal in the parent node the node. * i.e. super call is legal in constructor but not legal in the class body. - * - node is arrow function (so caller might need to call getSuperContainer in case if he needs to climb higher) + * - node is arrow function (so caller might need to call getSuperContainer in case it needs to climb higher) * - super call\property is definitely illegal in the node (but might be legal in some subnode) * i.e. super property access is illegal in function declaration but can be legal in the statement list */ diff --git a/package.json b/package.json index 261cdfa64b7..f0ba128a919 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "istanbul": "latest", "mocha-fivemat-progress-reporter": "latest", "tslint": "next", - "typescript": "next", + "typescript": "1.8.0-dev.20160113", "tsd": "latest" }, "scripts": { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f94afb3fc57..cb4bf19fabc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -83,6 +83,7 @@ namespace ts { getSymbolsInScope, getSymbolAtLocation, getShorthandAssignmentValueSymbol, + getExportSpecifierLocalTargetSymbol, getTypeAtLocation: getTypeOfNode, typeToString, getSymbolDisplayBuilder, @@ -8274,27 +8275,31 @@ namespace ts { // Get the element instance type (the result of newing or invoking this tag) const elemInstanceType = getJsxElementInstanceType(node); - // Is this is a stateless function component? See if its single signature is - // assignable to the JSX Element Type - const callSignature = getSingleCallSignature(getTypeOfSymbol(sym)); - const callReturnType = callSignature && getReturnTypeOfSignature(callSignature); - let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); - if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType) && (paramType.flags & TypeFlags.ObjectType)) { - // Intersect in JSX.IntrinsicAttributes if it exists - const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); - if (intrinsicAttributes !== unknownType) { - paramType = intersectTypes(intrinsicAttributes, paramType); + const elemClassType = getJsxGlobalElementClassType(); + + if (!elemClassType || !isTypeAssignableTo(elemInstanceType, elemClassType)) { + // Is this is a stateless function component? See if its single signature's return type is + // assignable to the JSX Element Type + const elemType = getTypeOfSymbol(sym); + const callSignatures = elemType && getSignaturesOfType(elemType, SignatureKind.Call); + const callSignature = callSignatures && callSignatures.length > 0 && callSignatures[0]; + const callReturnType = callSignature && getReturnTypeOfSignature(callSignature); + let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); + if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) { + // Intersect in JSX.IntrinsicAttributes if it exists + const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); + if (intrinsicAttributes !== unknownType) { + paramType = intersectTypes(intrinsicAttributes, paramType); + } + return links.resolvedJsxType = paramType; } - return paramType; } // Issue an error if this return type isn't assignable to JSX.ElementClass - const elemClassType = getJsxGlobalElementClassType(); if (elemClassType) { checkTypeRelatedTo(elemInstanceType, elemClassType, assignableRelation, node, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); } - if (isTypeAny(elemInstanceType)) { return links.resolvedJsxType = elemInstanceType; } @@ -11226,7 +11231,53 @@ namespace ts { return -1; } - function isInLegalParameterTypePredicatePosition(node: Node): boolean { + function checkTypePredicate(node: TypePredicateNode) { + const parent = getTypePredicateParent(node); + if (!parent) { + return; + } + const returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(parent)); + if (!returnType || !(returnType.flags & TypeFlags.PredicateType)) { + return; + } + const { parameterName } = node; + if (parameterName.kind === SyntaxKind.ThisType) { + getTypeFromThisTypeNode(parameterName as ThisTypeNode); + } + else { + const typePredicate = (returnType).predicate; + if (typePredicate.parameterIndex >= 0) { + if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) { + error(parameterName, + Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); + } + else { + checkTypeAssignableTo(typePredicate.type, + getTypeOfNode(parent.parameters[typePredicate.parameterIndex]), + node.type); + } + } + else if (parameterName) { + let hasReportedError = false; + for (const { name } of parent.parameters) { + if ((name.kind === SyntaxKind.ObjectBindingPattern || + name.kind === SyntaxKind.ArrayBindingPattern) && + checkIfTypePredicateVariableIsDeclaredInBindingPattern( + name, + parameterName, + typePredicate.parameterName)) { + hasReportedError = true; + break; + } + } + if (!hasReportedError) { + error(node.parameterName, Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName); + } + } + } + } + + function getTypePredicateParent(node: Node): SignatureDeclaration { switch (node.parent.kind) { case SyntaxKind.ArrowFunction: case SyntaxKind.CallSignature: @@ -11235,22 +11286,35 @@ namespace ts { case SyntaxKind.FunctionType: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - return node === (node.parent).type; + const parent = node.parent; + if (node === parent.type) { + return parent; + } } - return false; } - function isInLegalThisTypePredicatePosition(node: Node): boolean { - if (isInLegalParameterTypePredicatePosition(node)) { - return true; + function checkIfTypePredicateVariableIsDeclaredInBindingPattern( + pattern: BindingPattern, + predicateVariableNode: Node, + predicateVariableName: string) { + for (const { name } of pattern.elements) { + if (name.kind === SyntaxKind.Identifier && + (name).text === predicateVariableName) { + error(predicateVariableNode, + Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, + predicateVariableName); + return true; + } + else if (name.kind === SyntaxKind.ArrayBindingPattern || + name.kind === SyntaxKind.ObjectBindingPattern) { + if (checkIfTypePredicateVariableIsDeclaredInBindingPattern( + name, + predicateVariableNode, + predicateVariableName)) { + return true; + } + } } - switch (node.parent.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.GetAccessor: - return node === (node.parent as (PropertyDeclaration | GetAccessorDeclaration | PropertySignature)).type; - } - return false; } function checkSignatureDeclaration(node: SignatureDeclaration) { @@ -11269,68 +11333,8 @@ namespace ts { forEach(node.parameters, checkParameter); - if (node.type) { - if (node.type.kind === SyntaxKind.TypePredicate) { - const returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(node)); - if (!returnType || !(returnType.flags & TypeFlags.PredicateType)) { - return; - } - const typePredicate = (returnType as PredicateType).predicate; - const typePredicateNode = node.type as TypePredicateNode; - checkSourceElement(typePredicateNode); - if (isIdentifierTypePredicate(typePredicate)) { - if (typePredicate.parameterIndex >= 0) { - if (node.parameters[typePredicate.parameterIndex].dotDotDotToken) { - error(typePredicateNode.parameterName, - Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); - } - else { - checkTypeAssignableTo(typePredicate.type, - getTypeOfNode(node.parameters[typePredicate.parameterIndex]), - typePredicateNode.type); - } - } - else if (typePredicateNode.parameterName) { - let hasReportedError = false; - for (var param of node.parameters) { - if (hasReportedError) { - break; - } - if (param.name.kind === SyntaxKind.ObjectBindingPattern || - param.name.kind === SyntaxKind.ArrayBindingPattern) { + checkSourceElement(node.type); - (function checkBindingPattern(pattern: BindingPattern) { - for (const element of pattern.elements) { - if (element.name.kind === SyntaxKind.Identifier && - (element.name).text === typePredicate.parameterName) { - - error(typePredicateNode.parameterName, - Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, - typePredicate.parameterName); - hasReportedError = true; - break; - } - else if (element.name.kind === SyntaxKind.ArrayBindingPattern || - element.name.kind === SyntaxKind.ObjectBindingPattern) { - - checkBindingPattern(element.name); - } - } - })(param.name); - } - } - if (!hasReportedError) { - error(typePredicateNode.parameterName, - Diagnostics.Cannot_find_parameter_0, - typePredicate.parameterName); - } - } - } - } - else { - checkSourceElement(node.type); - } - } if (produceDiagnostics) { checkCollisionWithArgumentsInGeneratedCode(node); @@ -14602,20 +14606,6 @@ namespace ts { } } - function checkTypePredicate(node: TypePredicateNode) { - const { parameterName } = node; - if (parameterName.kind === SyntaxKind.Identifier && !isInLegalParameterTypePredicatePosition(node)) { - error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); - } - else if (parameterName.kind === SyntaxKind.ThisType) { - if (!isInLegalThisTypePredicatePosition(node)) { - error(node, Diagnostics.A_this_based_type_predicate_is_only_allowed_within_a_class_or_interface_s_members_get_accessors_or_return_type_positions_for_functions_and_methods); - } - else { - getTypeFromThisTypeNode(parameterName as ThisTypeNode); - } - } - } function checkSourceElement(node: Node): void { if (!node) { @@ -15219,11 +15209,18 @@ namespace ts { // This is necessary as an identifier in short-hand property assignment can contains two meaning: // property name and property value. if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) { - return resolveEntityName((location).name, SymbolFlags.Value); + return resolveEntityName((location).name, SymbolFlags.Value | SymbolFlags.Alias); } return undefined; } + /** Returns the target of an export specifier without following aliases */ + function getExportSpecifierLocalTargetSymbol(node: ExportSpecifier): Symbol { + return (node.parent.parent).moduleSpecifier ? + getExternalModuleMember(node.parent.parent, node) : + resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias); + } + function getTypeOfNode(node: Node): Type { if (isInsideWithStatementBody(node)) { // We cannot answer semantic questions within a with block, do not proceed any further diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2ffaccec7f0..d35258635ee 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -711,10 +711,6 @@ "category": "Error", "code": 1227 }, - "A type predicate is only allowed in return type position for functions and methods.": { - "category": "Error", - "code": 1228 - }, "A type predicate cannot reference a rest parameter.": { "category": "Error", "code": 1229 @@ -1655,10 +1651,6 @@ "category": "Error", "code": 2518 }, - "A 'this'-based type predicate is only allowed within a class or interface's members, get accessors, or return type positions for functions and methods.": { - "category": "Error", - "code": 2519 - }, "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": { "category": "Error", "code": 2520 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1491b887b95..e391408b419 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -896,17 +896,19 @@ namespace ts { return result; } - // Invokes the provided callback then unconditionally restores the parser to the state it - // was in immediately prior to invoking the callback. The result of invoking the callback - // is returned from this function. + /** Invokes the provided callback then unconditionally restores the parser to the state it + * was in immediately prior to invoking the callback. The result of invoking the callback + * is returned from this function. + */ function lookAhead(callback: () => T): T { return speculationHelper(callback, /*isLookAhead*/ true); } - // Invokes the provided callback. If the callback returns something falsy, then it restores - // the parser to the state it was in immediately prior to invoking the callback. If the - // callback returns something truthy, then the parser state is not rolled back. The result - // of invoking the callback is returned from this function. + /** Invokes the provided callback. If the callback returns something falsy, then it restores + * the parser to the state it was in immediately prior to invoking the callback. If the + * callback returns something truthy, then the parser state is not rolled back. The result + * of invoking the callback is returned from this function. + */ function tryParse(callback: () => T): T { return speculationHelper(callback, /*isLookAhead*/ false); } @@ -1948,11 +1950,8 @@ namespace ts { // TYPES - function parseTypeReferenceOrTypePredicate(): TypeReferenceNode | TypePredicateNode { + function parseTypeReference(): TypeReferenceNode { const typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected); - if (typeName.kind === SyntaxKind.Identifier && token === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { - return parseTypePredicate(typeName as Identifier); - } const node = createNode(SyntaxKind.TypeReference, typeName.pos); node.typeName = typeName; if (!scanner.hasPrecedingLineBreak() && token === SyntaxKind.LessThanToken) { @@ -2092,10 +2091,10 @@ namespace ts { if (returnTokenRequired) { parseExpected(returnToken); - signature.type = parseType(); + signature.type = parseTypeOrTypePredicate(); } else if (parseOptional(returnToken)) { - signature.type = parseType(); + signature.type = parseTypeOrTypePredicate(); } } @@ -2411,7 +2410,7 @@ namespace ts { case SyntaxKind.SymbolKeyword: // If these are followed by a dot, then parse these out as a dotted type reference instead. const node = tryParse(parseKeywordAndNoDot); - return node || parseTypeReferenceOrTypePredicate(); + return node || parseTypeReference(); case SyntaxKind.StringLiteral: return parseStringLiteralTypeNode(); case SyntaxKind.VoidKeyword: @@ -2434,7 +2433,7 @@ namespace ts { case SyntaxKind.OpenParenToken: return parseParenthesizedType(); default: - return parseTypeReferenceOrTypePredicate(); + return parseTypeReference(); } } @@ -2541,6 +2540,28 @@ namespace ts { return false; } + function parseTypeOrTypePredicate(): TypeNode { + const typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix); + const type = parseType(); + if (typePredicateVariable) { + const node = createNode(SyntaxKind.TypePredicate, typePredicateVariable.pos); + node.parameterName = typePredicateVariable; + node.type = type; + return finishNode(node); + } + else { + return type; + } + } + + function parseTypePredicatePrefix() { + const id = parseIdentifier(); + if (token === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { + nextToken(); + return id; + } + } + function parseType(): TypeNode { // The rules about 'yield' only apply to actual code/expression contexts. They don't // apply to 'type' contexts. So we disable these parameters here before moving on. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5e9e7a88dda..74c1af6ae52 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1728,6 +1728,7 @@ namespace ts { getSymbolAtLocation(node: Node): Symbol; getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; getShorthandAssignmentValueSymbol(location: Node): Symbol; + getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol; getTypeAtLocation(node: Node): Type; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c31a3f3248c..69941a6095d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -805,7 +805,7 @@ namespace ts { * Given an super call\property node returns a closest node where either * - super call\property is legal in the node and not legal in the parent node the node. * i.e. super call is legal in constructor but not legal in the class body. - * - node is arrow function (so caller might need to call getSuperContainer in case if he needs to climb higher) + * - node is arrow function (so caller might need to call getSuperContainer in case it needs to climb higher) * - super call\property is definitely illegal in the node (but might be legal in some subnode) * i.e. super property access is illegal in function declaration but can be legal in the statement list */ diff --git a/src/lib/core.d.ts b/src/lib/core.d.ts index 12df449931e..dbd4d37ef96 100644 --- a/src/lib/core.d.ts +++ b/src/lib/core.d.ts @@ -1,5 +1,3 @@ -/// - ///////////////////////////// /// ECMAScript APIs ///////////////////////////// diff --git a/src/lib/header.d.ts b/src/lib/header.d.ts new file mode 100644 index 00000000000..129e4739a83 --- /dev/null +++ b/src/lib/header.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/services/services.ts b/src/services/services.ts index c63b1534391..c91a3590ff7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5518,10 +5518,8 @@ namespace ts { }; } - function isImportOrExportSpecifierImportSymbol(symbol: Symbol) { - return (symbol.flags & SymbolFlags.Alias) && forEach(symbol.declarations, declaration => { - return declaration.kind === SyntaxKind.ImportSpecifier || declaration.kind === SyntaxKind.ExportSpecifier; - }); + function isImportSpecifierSymbol(symbol: Symbol) { + return (symbol.flags & SymbolFlags.Alias) && !!getDeclarationOfKind(symbol, SyntaxKind.ImportSpecifier); } function getInternedName(symbol: Symbol, location: Node, declarations: Declaration[]): string { @@ -5965,8 +5963,17 @@ namespace ts { let result = [symbol]; // If the symbol is an alias, add what it alaises to the list - if (isImportOrExportSpecifierImportSymbol(symbol)) { - result.push(typeChecker.getAliasedSymbol(symbol)); + if (isImportSpecifierSymbol(symbol)) { + result.push(typeChecker.getAliasedSymbol(symbol)); + } + + // For export specifiers, the exported name can be refering to a local symbol, e.g.: + // import {a} from "mod"; + // export {a as somethingElse} + // We want the *local* declaration of 'a' as declared in the import, + // *not* as declared within "mod" (or farther) + if (location.parent.kind === SyntaxKind.ExportSpecifier) { + result.push(typeChecker.getExportSpecifierLocalTargetSymbol(location.parent)); } // If the location is in a context sensitive location (i.e. in an object literal) try @@ -6012,14 +6019,38 @@ namespace ts { // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {}); } }); return result; } - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[]): void { + /** + * Find symbol of the given property-name and add the symbol to the given result array + * @param symbol a symbol to start searching for the given propertyName + * @param propertyName a name of property to serach for + * @param result an array of symbol of found property symbols + * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisitng of the same symbol. + * The value of previousIterationSymbol is undefined when the function is first called. + */ + function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], + previousIterationSymbolsCache: SymbolTable): void { + // If the current symbol is the same as the previous-iteration symbol, we can just return the symbol that has already been visited + // This is particularly important for the following cases, so that we do not infinitely visit the same symbol. + // For example: + // interface C extends C { + // /*findRef*/propName: string; + // } + // The first time getPropertySymbolsFromBaseTypes is called when finding-all-references at propName, + // the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined, + // the function will add any found symbol of the property-name, then its sub-routine will call + // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already + // visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol. + if (hasProperty(previousIterationSymbolsCache, symbol.name)) { + return; + } + if (symbol && symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { forEach(symbol.getDeclarations(), declaration => { if (declaration.kind === SyntaxKind.ClassDeclaration) { @@ -6043,7 +6074,8 @@ namespace ts { } // Visit the typeReference as well to see if it directly or indirectly use that property - getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result); + previousIterationSymbolsCache[symbol.name] = symbol; + getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache); } } } @@ -6056,13 +6088,24 @@ namespace ts { // If the reference symbol is an alias, check if what it is aliasing is one of the search // symbols. - if (isImportOrExportSpecifierImportSymbol(referenceSymbol)) { + if (isImportSpecifierSymbol(referenceSymbol)) { const aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); if (searchSymbols.indexOf(aliasedSymbol) >= 0) { return aliasedSymbol; } } + // For export specifiers, it can be a local symbol, e.g. + // import {a} from "mod"; + // export {a as somethingElse} + // We want the local target of the export (i.e. the import symbol) and not the final target (i.e. "mod".a) + if (referenceLocation.parent.kind === SyntaxKind.ExportSpecifier) { + const aliasedSymbol = typeChecker.getExportSpecifierLocalTargetSymbol(referenceLocation.parent); + if (searchSymbols.indexOf(aliasedSymbol) >= 0) { + return aliasedSymbol; + } + } + // If the reference location is in an object literal, try to get the contextual type for the // object literal, lookup the property symbol in the contextual type, and use this symbol to // compare to our searchSymbol @@ -6084,7 +6127,7 @@ namespace ts { // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { const result: Symbol[] = []; - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {}); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); } diff --git a/tests/baselines/reference/tsxElementResolution9.js b/tests/baselines/reference/tsxElementResolution9.js index bc65bb0bb02..5ad47730e4a 100644 --- a/tests/baselines/reference/tsxElementResolution9.js +++ b/tests/baselines/reference/tsxElementResolution9.js @@ -1,6 +1,6 @@ //// [file.tsx] declare module JSX { - interface Element { } + interface Element { something; } interface IntrinsicElements { } } diff --git a/tests/baselines/reference/tsxElementResolution9.symbols b/tests/baselines/reference/tsxElementResolution9.symbols index e38c64d0847..0aec19a8094 100644 --- a/tests/baselines/reference/tsxElementResolution9.symbols +++ b/tests/baselines/reference/tsxElementResolution9.symbols @@ -2,11 +2,12 @@ declare module JSX { >JSX : Symbol(JSX, Decl(file.tsx, 0, 0)) - interface Element { } + interface Element { something; } >Element : Symbol(Element, Decl(file.tsx, 0, 20)) +>something : Symbol(something, Decl(file.tsx, 1, 20)) interface IntrinsicElements { } ->IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 1, 22)) +>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 1, 33)) } interface Obj1 { diff --git a/tests/baselines/reference/tsxElementResolution9.types b/tests/baselines/reference/tsxElementResolution9.types index dd84e6f07b5..b138aa0509e 100644 --- a/tests/baselines/reference/tsxElementResolution9.types +++ b/tests/baselines/reference/tsxElementResolution9.types @@ -2,8 +2,9 @@ declare module JSX { >JSX : any - interface Element { } + interface Element { something; } >Element : Element +>something : any interface IntrinsicElements { } >IntrinsicElements : IntrinsicElements diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents3.js b/tests/baselines/reference/tsxStatelessFunctionComponents3.js new file mode 100644 index 00000000000..d58586dd1ee --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponents3.js @@ -0,0 +1,37 @@ +//// [file.tsx] + +import React = require('react'); + +const Foo = (props: any) =>
; +// Should be OK +const foo = ; + + +// Should be OK +var MainMenu: React.StatelessComponent<{}> = (props) => (
+

Main Menu

+
); + +var App: React.StatelessComponent<{ children }> = ({children}) => ( +
+ +
+); + +//// [file.jsx] +define(["require", "exports", 'react'], function (require, exports, React) { + "use strict"; + var Foo = function (props) { return
; }; + // Should be OK + var foo = ; + // Should be OK + var MainMenu = function (props) { return (
+

Main Menu

+
); }; + var App = function (_a) { + var children = _a.children; + return (
+ +
); + }; +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols b/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols new file mode 100644 index 00000000000..4ce502c6a6a --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +const Foo = (props: any) =>
; +>Foo : Symbol(Foo, Decl(file.tsx, 3, 5)) +>props : Symbol(props, Decl(file.tsx, 3, 13)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) + +// Should be OK +const foo = ; +>foo : Symbol(foo, Decl(file.tsx, 5, 5)) +>Foo : Symbol(Foo, Decl(file.tsx, 3, 5)) + + +// Should be OK +var MainMenu: React.StatelessComponent<{}> = (props) => (
+>MainMenu : Symbol(MainMenu, Decl(file.tsx, 9, 3)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 139, 5)) +>props : Symbol(props, Decl(file.tsx, 9, 46)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) + +

Main Menu

+>h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 939, 48)) +>h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 939, 48)) + +
); +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) + +var App: React.StatelessComponent<{ children }> = ({children}) => ( +>App : Symbol(App, Decl(file.tsx, 13, 3)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 139, 5)) +>children : Symbol(children, Decl(file.tsx, 13, 35)) +>children : Symbol(children, Decl(file.tsx, 13, 52)) + +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) + + +>MainMenu : Symbol(MainMenu, Decl(file.tsx, 9, 3)) + +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) + +); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents3.types b/tests/baselines/reference/tsxStatelessFunctionComponents3.types new file mode 100644 index 00000000000..6531ff737ba --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponents3.types @@ -0,0 +1,59 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +const Foo = (props: any) =>
; +>Foo : (props: any) => JSX.Element +>(props: any) =>
: (props: any) => JSX.Element +>props : any +>
: JSX.Element +>div : any + +// Should be OK +const foo = ; +>foo : JSX.Element +> : JSX.Element +>Foo : (props: any) => JSX.Element + + +// Should be OK +var MainMenu: React.StatelessComponent<{}> = (props) => (
+>MainMenu : React.StatelessComponent<{}> +>React : any +>StatelessComponent : React.StatelessComponent

+>(props) => (

Main Menu

) : (props: {}) => JSX.Element +>props : {} +>(

Main Menu

) : JSX.Element +>

Main Menu

: JSX.Element +>div : any + +

Main Menu

+>

Main Menu

: JSX.Element +>h3 : any +>h3 : any + +
); +>div : any + +var App: React.StatelessComponent<{ children }> = ({children}) => ( +>App : React.StatelessComponent<{ children: any; }> +>React : any +>StatelessComponent : React.StatelessComponent

+>children : any +>({children}) => (

) : ({children}: { children: any; }) => JSX.Element +>children : any +>(
) : JSX.Element + +
+>
: JSX.Element +>div : any + + +> : JSX.Element +>MainMenu : React.StatelessComponent<{}> + +
+>div : any + +); diff --git a/tests/baselines/reference/typeAssertions.errors.txt b/tests/baselines/reference/typeAssertions.errors.txt index a2ad28801c8..c7401e4fcf9 100644 --- a/tests/baselines/reference/typeAssertions.errors.txt +++ b/tests/baselines/reference/typeAssertions.errors.txt @@ -7,9 +7,23 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(37,13): err Property 'q' is missing in type 'SomeDerived'. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(38,13): error TS2352: Neither type 'SomeBase' nor type 'SomeOther' is assignable to the other. Property 'q' is missing in type 'SomeBase'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,5): error TS2304: Cannot find name 'numOrStr'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,14): error TS1005: '>' expected. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,14): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,17): error TS1005: ')' expected. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,17): error TS2304: Cannot find name 'string'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,48): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(45,2): error TS2322: Type 'number | string' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,32): error TS2304: Cannot find name 'numOrStr'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,41): error TS1005: ')' expected. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,41): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,44): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,44): error TS2304: Cannot find name 'string'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,50): error TS1005: ';' expected. -==== tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts (5 errors) ==== +==== tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts (18 errors) ==== // Function call whose argument is a 1 arg generic function call with explicit type arguments function fn1(t: T) { } function fn2(t: any) { } @@ -64,5 +78,41 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(38,13): err !!! error TS2352: Property 'q' is missing in type 'SomeBase'. someOther = someOther; + // Type assertion cannot be a type-predicate type + var numOrStr: number | string; + var str: string; + if((numOrStr === undefined)) { // Error + ~~~~~~~~ +!!! error TS2304: Cannot find name 'numOrStr'. + ~~ +!!! error TS1005: '>' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~~~~~~ +!!! error TS1005: ')' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'string'. + ~ +!!! error TS1005: ';' expected. + str = numOrStr; // Error, no narrowing occurred + ~~~ +!!! error TS2322: Type 'number | string' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + } + + if((numOrStr === undefined) as numOrStr is string) { // Error + ~~~~~~~~ +!!! error TS2304: Cannot find name 'numOrStr'. + ~~ +!!! error TS1005: ')' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~~~~~~ +!!! error TS1005: ';' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'string'. + ~ +!!! error TS1005: ';' expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/typeAssertions.js b/tests/baselines/reference/typeAssertions.js index b58a46c37f6..1d33fa927a7 100644 --- a/tests/baselines/reference/typeAssertions.js +++ b/tests/baselines/reference/typeAssertions.js @@ -39,6 +39,15 @@ someOther = someDerived; // Error someOther = someBase; // Error someOther = someOther; +// Type assertion cannot be a type-predicate type +var numOrStr: number | string; +var str: string; +if((numOrStr === undefined)) { // Error + str = numOrStr; // Error, no narrowing occurred +} + +if((numOrStr === undefined) as numOrStr is string) { // Error +} @@ -87,3 +96,16 @@ someDerived = someOther; // Error someOther = someDerived; // Error someOther = someBase; // Error someOther = someOther; +// Type assertion cannot be a type-predicate type +var numOrStr; +var str; +if (is) + string > (numOrStr === undefined); +{ + str = numOrStr; // Error, no narrowing occurred +} +if ((numOrStr === undefined)) + is; +string; +{ +} diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt index e1fdf303870..4756b83b300 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -1,15 +1,21 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(2,7): error TS2300: Duplicate identifier 'A'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS2322: Type 'string' is not assignable to type 'x is A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,55): error TS2304: Cannot find name 'x'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,57): error TS1144: '{' or ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,57): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,60): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,62): error TS1005: ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(22,33): error TS2304: Cannot find name 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(26,33): error TS1225: Cannot find parameter 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,10): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(31,5): error TS1131: Property or signature expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(31,5): error TS7027: Unreachable code detected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(32,1): error TS1128: Declaration or statement expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(34,38): error TS1225: Cannot find parameter 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(38,51): error TS2322: Type 'B' is not assignable to type 'A'. Property 'propA' is missing in type 'B'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(42,56): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(46,56): error TS2322: Type 'T[]' is not assignable to type 'string'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(50,1): error TS7027: Unreachable code detected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(60,7): error TS2339: Property 'propB' does not exist on type 'A'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(65,7): error TS2339: Property 'propB' does not exist on type 'A'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(70,7): error TS2339: Property 'propB' does not exist on type 'A'. @@ -23,27 +29,40 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(85,1): Type predicate 'p2 is A' is not assignable to 'p1 is A'. Parameter 'p2' is not in the same position as parameter 'p1'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(91,1): error TS2322: Type '(p1: any, p2: any, p3: any) => p1 is A' is not assignable to type '(p1: any, p2: any) => p1 is A'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,9): error TS1228: A type predicate is only allowed in return type position for functions and methods. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,16): error TS1228: A type predicate is only allowed in return type position for functions and methods. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,9): error TS2304: Cannot find name 'b'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,11): error TS1005: '=' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,11): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,14): error TS1005: ',' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,14): error TS2300: Duplicate identifier 'A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,16): error TS2304: Cannot find name 'b'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,18): error TS1005: '=' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,18): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,21): error TS1005: ',' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,20): error TS2304: Cannot find name 'b'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,22): error TS1144: '{' or ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,22): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,25): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,27): error TS1005: ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(105,16): error TS2322: Type 'boolean' is not assignable to type 'D'. Property 'm1' is missing in type 'Boolean'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(105,16): error TS2409: Return type of constructor signature must be assignable to the instance type of the class -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(107,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(110,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(111,16): error TS2408: Setters cannot return a value. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(116,18): error TS1228: A type predicate is only allowed in return type position for functions and methods. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,22): error TS1225: Cannot find parameter 'p1'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,22): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,22): error TS2304: Cannot find name 'p1'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,25): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,25): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,28): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(121,1): error TS1128: Declaration or statement expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(124,20): error TS1229: A type predicate cannot reference a rest parameter. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(129,34): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(133,34): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. -==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (33 errors) ==== +==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (50 errors) ==== class A { + ~ +!!! error TS2300: Duplicate identifier 'A'. propA: number; } @@ -62,6 +81,16 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 } function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { + ~ +!!! error TS2304: Cannot find name 'x'. + ~~ +!!! error TS1144: '{' or ';' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1005: ';' expected. return true; } @@ -83,6 +112,8 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 return true; ~~~~~~ !!! error TS1131: Property or signature expected. + ~~~~~~ +!!! error TS7027: Unreachable code detected. } ~ !!! error TS1128: Declaration or statement expected. @@ -113,8 +144,6 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 } let a: A; - ~~~ -!!! error TS7027: Unreachable code detected. let b: B; declare function isB(p1): p1 is B; @@ -181,14 +210,36 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 // Type predicates in non-return type positions var b1: b is A; - ~~~~~~ -!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + ~ +!!! error TS2304: Cannot find name 'b'. + ~~ +!!! error TS1005: '=' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2300: Duplicate identifier 'A'. function b2(a: b is A) {}; - ~~~~~~ -!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + ~ +!!! error TS2304: Cannot find name 'b'. + ~~ +!!! error TS1005: '=' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~ +!!! error TS1005: ',' expected. function b3(): A | b is A { - ~~~~~~ -!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + ~ +!!! error TS2304: Cannot find name 'b'. + ~~ +!!! error TS1144: '{' or ';' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1005: ';' expected. return true; }; @@ -203,13 +254,9 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 !!! error TS2409: Return type of constructor signature must be assignable to the instance type of the class } get m1(p1: A): p1 is C { - ~~~~~~~ -!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. return true; } set m2(p1: A): p1 is C { - ~~~~~~~ -!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. return true; ~~~~ !!! error TS2408: Setters cannot return a value. @@ -218,17 +265,21 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 interface I1 { new (p1: A): p1 is C; - ~~~~~~~ -!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. } interface I2 { [index: number]: p1 is C; ~~ -!!! error TS1225: Cannot find parameter 'p1'. - ~~~~~~~ -!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. +!!! error TS2304: Cannot find name 'p1'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~ +!!! error TS1005: ';' expected. } + ~ +!!! error TS1128: Declaration or statement expected. // Reference to rest parameter function b4(...a): a is A { diff --git a/tests/baselines/reference/typeGuardFunctionErrors.js b/tests/baselines/reference/typeGuardFunctionErrors.js index 5e69749e582..dcd8ffcb265 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.js +++ b/tests/baselines/reference/typeGuardFunctionErrors.js @@ -171,7 +171,9 @@ var C = (function (_super) { function hasANonBooleanReturnStatement(x) { return ''; } -function hasTypeGuardTypeInsideTypeGuardType(x) { +is; +A; +{ return true; } function hasMissingIsKeyword() { @@ -224,10 +226,14 @@ assign3 = function (p1, p2, p3) { return true; }; // Type predicates in non-return type positions -var b1; -function b2(a) { } +var b1 = is, A; +function b2(a, A) { + if (a === void 0) { a = is; } +} ; -function b3() { +is; +A; +{ return true; } ; @@ -252,6 +258,8 @@ var D = (function () { }); return D; }()); +is; +C; // Reference to rest parameter function b4() { var a = []; diff --git a/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt b/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt index 328e080fbaa..9dd9a8d41a1 100644 --- a/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt +++ b/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt @@ -1,4 +1,4 @@ -lib.d.ts(29,18): error TS2300: Duplicate identifier 'eval'. +lib.d.ts(28,18): error TS2300: Duplicate identifier 'eval'. tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS1100: Invalid use of 'eval' in strict mode. tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS2300: Duplicate identifier 'eval'. diff --git a/tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts b/tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts index 2acbbe53789..f30eafb3918 100644 --- a/tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts +++ b/tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts @@ -38,4 +38,13 @@ someOther = someDerived; // Error someOther = someBase; // Error someOther = someOther; +// Type assertion cannot be a type-predicate type +var numOrStr: number | string; +var str: string; +if((numOrStr === undefined)) { // Error + str = numOrStr; // Error, no narrowing occurred +} + +if((numOrStr === undefined) as numOrStr is string) { // Error +} diff --git a/tests/cases/conformance/jsx/tsxElementResolution9.tsx b/tests/cases/conformance/jsx/tsxElementResolution9.tsx index 7165f8277b3..4854484a225 100644 --- a/tests/cases/conformance/jsx/tsxElementResolution9.tsx +++ b/tests/cases/conformance/jsx/tsxElementResolution9.tsx @@ -1,7 +1,7 @@ //@filename: file.tsx //@jsx: preserve declare module JSX { - interface Element { } + interface Element { something; } interface IntrinsicElements { } } diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponents3.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponents3.tsx new file mode 100644 index 00000000000..48ce5fb5efb --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponents3.tsx @@ -0,0 +1,23 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const Foo = (props: any) =>
; +// Should be OK +const foo = ; + + +// Should be OK +var MainMenu: React.StatelessComponent<{}> = (props) => (
+

Main Menu

+
); + +var App: React.StatelessComponent<{ children }> = ({children}) => ( +
+ +
+); \ No newline at end of file diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts new file mode 100644 index 00000000000..23f6445a004 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts @@ -0,0 +1,13 @@ +/// + +// @Filename: file1.ts +//// interface interface1 extends interface1 { +//// /*1*/doStuff(): void; +//// /*2*/propName: string; +//// } + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); +} diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts new file mode 100644 index 00000000000..d4aadf96ed6 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts @@ -0,0 +1,13 @@ +/// + +// @Filename: file1.ts +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); +} \ No newline at end of file diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts new file mode 100644 index 00000000000..5e94bb387cd --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts @@ -0,0 +1,17 @@ +/// + +// @Filename: file1.ts +//// interface interface1 extends interface1 { +//// /*1*/doStuff(): void; +//// /*2*/propName: string; +//// } +//// +//// var v: interface1; +//// v./*3*/propName; +//// v./*4*/doStuff(); + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); +} diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts new file mode 100644 index 00000000000..50f459ebfdb --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts @@ -0,0 +1,17 @@ +/// + +// @Filename: file1.ts +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } +//// +//// var c: class1; +//// c./*3*/doStuff(); +//// c./*4*/propName; + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); +} diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts new file mode 100644 index 00000000000..b5f4cbb00a7 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts @@ -0,0 +1,30 @@ +/// + +// @Filename: file1.ts +//// interface C extends D { +//// /*0*/prop0: string; +//// /*1*/prop1: number; +//// } +//// +//// interface D extends C { +//// /*2*/prop0: string; +//// /*3*/prop1: number; +//// } +//// +//// var d: D; +//// d./*4*/prop1; + +goTo.marker("0"); +verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); + +goTo.marker("1"); +verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); + +goTo.marker("2"); +verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); + +goTo.marker("3"); +verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); + +goTo.marker("4"); +verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); \ No newline at end of file diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts new file mode 100644 index 00000000000..8f1089e567d --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts @@ -0,0 +1,30 @@ +/// + +// @Filename: file1.ts +//// class C extends D { +//// /*0*/prop0: string; +//// /*1*/prop1: string; +//// } +//// +//// class D extends C { +//// /*2*/prop0: string; +//// /*3*/prop1: string; +//// } +//// +//// var d: D; +//// d./*4*/prop1; + +goTo.marker("0"); +verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); + +goTo.marker("1"); +verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); + +goTo.marker("2"); +verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); + +goTo.marker("3"); +verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); + +goTo.marker("4"); +verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts new file mode 100644 index 00000000000..b2755923d37 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts @@ -0,0 +1,25 @@ +/// + +//// class class1 extends class1 { +//// [|doStuff|]() { } +//// [|propName|]: string; +//// } +//// +//// var v: class1; +//// v.[|doStuff|](); +//// v.[|propName|]; + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3] = ranges; +verifyReferences(r0, [r0, r2]); +verifyReferences(r1, [r1, r3]); +verifyReferences(r2, [r0, r2]); +verifyReferences(r3, [r1, r3]); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties2.ts b/tests/cases/fourslash/findAllRefsInheritedProperties2.ts new file mode 100644 index 00000000000..1ab92c251da --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties2.ts @@ -0,0 +1,25 @@ +/// + +//// interface interface1 extends interface1 { +//// [|doStuff|](): void; // r0 +//// [|propName|]: string; // r1 +//// } +//// +//// var v: interface1; +//// v.[|doStuff|](); // r2 +//// v.[|propName|]; // r3 + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3] = ranges; +verifyReferences(r0, [r0, r2]); +verifyReferences(r1, [r1, r3]); +verifyReferences(r2, [r0, r2]); +verifyReferences(r3, [r1, r3]); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts new file mode 100644 index 00000000000..9a46b08f357 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts @@ -0,0 +1,37 @@ +/// + +//// class class1 extends class1 { +//// [|doStuff|]() { } // r0 +//// [|propName|]: string; // r1 +//// } +//// interface interface1 extends interface1 { +//// [|doStuff|](): void; // r2 +//// [|propName|]: string; // r3 +//// } +//// class class2 extends class1 implements interface1 { +//// [|doStuff|]() { } // r4 +//// [|propName|]: string; // r5 +//// } +//// +//// var v: class2; +//// v.[|propName|]; // r6 +//// v.[|doStuff|](); // r7 + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3, r4, r5, r6, r7] = ranges; +verifyReferences(r0, [r0]); +verifyReferences(r1, [r1, r5, r6]); +verifyReferences(r2, [r2, r4, r7]); +verifyReferences(r3, [r3, r5, r6]); +verifyReferences(r4, [r2, r4, r7]); +verifyReferences(r5, [r1, r3, r5, r6]); +verifyReferences(r6, [r1, r3, r5, r6]); +verifyReferences(r7, [r2, r4, r7]); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties4.ts b/tests/cases/fourslash/findAllRefsInheritedProperties4.ts new file mode 100644 index 00000000000..bcd41331f73 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties4.ts @@ -0,0 +1,30 @@ +/// + +//// interface C extends D { +//// [|prop0|]: string; // r0 +//// [|prop1|]: number; // r1 +//// } +//// +//// interface D extends C { +//// [|prop0|]: string; // r2 +//// } +//// +//// var d: D; +//// d.[|prop0|]; // r3 +//// d.[|prop1|]; // r4 + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3, r4] = ranges; +verifyReferences(r0, [r0, r2, r3]); +verifyReferences(r1, [r1]); +verifyReferences(r2, [r0, r2, r3]); +verifyReferences(r3, [r0, r2, r3]); +verifyReferences(r4, []); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties5.ts b/tests/cases/fourslash/findAllRefsInheritedProperties5.ts new file mode 100644 index 00000000000..d4e02a36b09 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties5.ts @@ -0,0 +1,30 @@ +/// + +//// class C extends D { +//// [|prop0|]: string; // r0 +//// [|prop1|]: number; // r1 +//// } +//// +//// class D extends C { +//// [|prop0|]: string; // r2 +//// } +//// +//// var d: D; +//// d.[|prop0|]; // r3 +//// d.[|prop1|]; // r4 + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3, r4] = ranges; +verifyReferences(r0, [r0]); +verifyReferences(r1, [r1]); +verifyReferences(r2, [r2, r3]); +verifyReferences(r3, [r2, r3]); +verifyReferences(r4, []); diff --git a/tests/cases/fourslash/referencesForInheritedProperties3.ts b/tests/cases/fourslash/referencesForInheritedProperties3.ts new file mode 100644 index 00000000000..134f75da84b --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties3.ts @@ -0,0 +1,15 @@ +/// + +//// interface interface1 extends interface1 { +//// /*1*/doStuff(): void; +//// /*2*/propName: string; +//// } +//// +//// var v: interface1; +//// v./*3*/propName; +//// v./*4*/doStuff(); + +test.markers().forEach(m => { + goTo.position(m.position, m.fileName); + verify.referencesCountIs(2); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties4.ts b/tests/cases/fourslash/referencesForInheritedProperties4.ts new file mode 100644 index 00000000000..10dcc9c77a2 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties4.ts @@ -0,0 +1,15 @@ +/// + +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } +//// +//// var c: class1; +//// c./*3*/doStuff(); +//// c./*4*/propName; + +test.markers().forEach(m => { + goTo.position(m.position, m.fileName); + verify.referencesCountIs(2); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties5.ts b/tests/cases/fourslash/referencesForInheritedProperties5.ts new file mode 100644 index 00000000000..722c5c96f0a --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties5.ts @@ -0,0 +1,19 @@ +/// + +//// interface interface1 extends interface1 { +//// /*1*/doStuff(): void; +//// /*2*/propName: string; +//// } +//// interface interface2 extends interface1 { +//// /*3*/doStuff(): void; +//// /*4*/propName: string; +//// } +//// +//// var v: interface1; +//// v./*5*/propName; +//// v./*6*/doStuff(); + +test.markers().forEach(m => { + goTo.position(m.position, m.fileName); + verify.referencesCountIs(3); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties6.ts b/tests/cases/fourslash/referencesForInheritedProperties6.ts new file mode 100644 index 00000000000..de6a2f2eba1 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties6.ts @@ -0,0 +1,32 @@ +/// + +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } +//// class class2 extends class1 { +//// /*3*/doStuff() { } +//// /*4*/propName: string; +//// } +//// +//// var v: class2; +//// v./*5*/propName; +//// v./*6*/doStuff(); + +goTo.marker("1"); +verify.referencesCountIs(1); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(2); + +goTo.marker("4"); +verify.referencesCountIs(3); + +goTo.marker("5"); +verify.referencesCountIs(3); + +goTo.marker("6"); +verify.referencesCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties7.ts b/tests/cases/fourslash/referencesForInheritedProperties7.ts new file mode 100644 index 00000000000..000d4922222 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties7.ts @@ -0,0 +1,42 @@ +/// + +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } +//// interface interface1 extends interface1 { +//// /*3*/doStuff(): void; +//// /*4*/propName: string; +//// } +//// class class2 extends class1 implements interface1 { +//// /*5*/doStuff() { } +//// /*6*/propName: string; +//// } +//// +//// var v: class2; +//// v./*7*/propName; +//// v./*8*/doStuff(); + +goTo.marker("1"); +verify.referencesCountIs(1); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(3); + +goTo.marker("4"); +verify.referencesCountIs(3); + +goTo.marker("5"); +verify.referencesCountIs(3); + +goTo.marker("6"); +verify.referencesCountIs(4); + +goTo.marker("7"); +verify.referencesCountIs(4); + +goTo.marker("8"); +verify.referencesCountIs(3); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties8.ts b/tests/cases/fourslash/referencesForInheritedProperties8.ts new file mode 100644 index 00000000000..f34b327a472 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties8.ts @@ -0,0 +1,27 @@ +/// + +//// interface C extends D { +//// /*0*/propD: number; +//// } +//// interface D extends C { +//// /*1*/propD: string; +//// /*3*/propC: number; +//// } +//// var d: D; +//// d./*2*/propD; +//// d./*4*/propC; + +goTo.marker("0"); +verify.referencesCountIs(3); + +goTo.marker("1"); +verify.referencesCountIs(3); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(2); + +goTo.marker("4"); +verify.referencesCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties9.ts b/tests/cases/fourslash/referencesForInheritedProperties9.ts new file mode 100644 index 00000000000..b348d6e8cf6 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties9.ts @@ -0,0 +1,21 @@ +/// + +//// class D extends C { +//// /*0*/prop1: string; +//// } +//// +//// class C extends D { +//// /*1*/prop1: string; +//// } +//// +//// var c: C; +//// c./*2*/prop1; + +goTo.marker("0"); +verify.referencesCountIs(1); + +goTo.marker("1"); +verify.referencesCountIs(2) + +goTo.marker("2"); +verify.referencesCountIs(2) \ No newline at end of file diff --git a/tests/cases/fourslash/renameImportAndExport.ts b/tests/cases/fourslash/renameImportAndExport.ts new file mode 100644 index 00000000000..495e15c1e7e --- /dev/null +++ b/tests/cases/fourslash/renameImportAndExport.ts @@ -0,0 +1,10 @@ +/// + +////import [|a|] from "module"; +////export { [|a|] }; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} diff --git a/tests/cases/fourslash/renameImportAndShorthand.ts b/tests/cases/fourslash/renameImportAndShorthand.ts new file mode 100644 index 00000000000..bc4746aebdd --- /dev/null +++ b/tests/cases/fourslash/renameImportAndShorthand.ts @@ -0,0 +1,10 @@ +/// + +////import [|foo|] from 'bar'; +////const bar = { [|foo|] }; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} diff --git a/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts b/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts new file mode 100644 index 00000000000..a6b06c11408 --- /dev/null +++ b/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts @@ -0,0 +1,10 @@ +/// + +////import * as [|foo|] from 'bar'; +////const bar = { [|foo|] }; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} diff --git a/tests/cases/fourslash/renameImportOfExportEquals.ts b/tests/cases/fourslash/renameImportOfExportEquals.ts new file mode 100644 index 00000000000..9d71ee907c8 --- /dev/null +++ b/tests/cases/fourslash/renameImportOfExportEquals.ts @@ -0,0 +1,18 @@ +/// + +////declare namespace N { +//// export var x: number; +////} +////declare module "mod" { +//// export = N; +////} +////declare module "test" { +//// import * as [|N|] from "mod"; +//// export { [|N|] }; // Renaming N here would rename +////} + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} diff --git a/tests/cases/fourslash/renameImportRequire.ts b/tests/cases/fourslash/renameImportRequire.ts new file mode 100644 index 00000000000..c26cc80b616 --- /dev/null +++ b/tests/cases/fourslash/renameImportRequire.ts @@ -0,0 +1,12 @@ +/// + +////import [|e|] = require("mod4"); +////[|e|]; +////a = { [|e|] }; +////export { [|e|] }; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} diff --git a/tests/cases/fourslash/renameInheritedProperties1.ts b/tests/cases/fourslash/renameInheritedProperties1.ts new file mode 100644 index 00000000000..4698fe3d97b --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties1.ts @@ -0,0 +1,15 @@ +/// + +//// class class1 extends class1 { +//// [|propName|]: string; +//// } +//// +//// var v: class1; +//// v.[|propName|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties2.ts b/tests/cases/fourslash/renameInheritedProperties2.ts new file mode 100644 index 00000000000..ed99ec3e013 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties2.ts @@ -0,0 +1,15 @@ +/// + +//// class class1 extends class1 { +//// [|doStuff|]() { } +//// } +//// +//// var v: class1; +//// v.[|doStuff|](); + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties3.ts b/tests/cases/fourslash/renameInheritedProperties3.ts new file mode 100644 index 00000000000..17e7785fbc7 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties3.ts @@ -0,0 +1,15 @@ +/// + +//// interface interface1 extends interface1 { +//// [|propName|]: string; +//// } +//// +//// var v: interface1; +//// v.[|propName|]; + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties4.ts b/tests/cases/fourslash/renameInheritedProperties4.ts new file mode 100644 index 00000000000..ea2f7c40fbf --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties4.ts @@ -0,0 +1,15 @@ +/// + +//// interface interface1 extends interface1 { +//// [|doStuff|](): string; +//// } +//// +//// var v: interface1; +//// v.[|doStuff|](); + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties5.ts b/tests/cases/fourslash/renameInheritedProperties5.ts new file mode 100644 index 00000000000..45058827747 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties5.ts @@ -0,0 +1,17 @@ +/// + +//// interface C extends D { +//// propC: number; +//// } +//// interface D extends C { +//// [|propD|]: string; +//// } +//// var d: D; +//// d.[|propD|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} diff --git a/tests/cases/fourslash/renameInheritedProperties6.ts b/tests/cases/fourslash/renameInheritedProperties6.ts new file mode 100644 index 00000000000..6bdd32ce3e0 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties6.ts @@ -0,0 +1,17 @@ +/// + +//// interface C extends D { +//// propD: number; +//// } +//// interface D extends C { +//// [|propC|]: number; +//// } +//// var d: D; +//// d.[|propC|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties7.ts b/tests/cases/fourslash/renameInheritedProperties7.ts new file mode 100644 index 00000000000..a2f8c5a2b51 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties7.ts @@ -0,0 +1,19 @@ +/// + +//// class C extends D { +//// [|prop1|]: string; +//// } +//// +//// class D extends C { +//// prop1: string; +//// } +//// +//// var c: C; +//// c.[|prop1|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties8.ts b/tests/cases/fourslash/renameInheritedProperties8.ts new file mode 100644 index 00000000000..119e1a477aa --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties8.ts @@ -0,0 +1,19 @@ +/// + +//// class C implements D { +//// [|prop1|]: string; +//// } +//// +//// interface D extends C { +//// [|prop1|]: string; +//// } +//// +//// var c: C; +//// c.[|prop1|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file