mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-15 08:20:53 -06:00
Merge pull request #7945 from Microsoft/renameAndFindRef
Fixes rename for destructuring, named imports and default imports
This commit is contained in:
commit
41c1a5b497
2
.gitignore
vendored
2
.gitignore
vendored
@ -26,6 +26,8 @@ rwc-report.html
|
||||
*.swp
|
||||
build.json
|
||||
*.actual
|
||||
tests/webTestServer.js
|
||||
tests/webTestServer.js.map
|
||||
tests/webhost/*.d.ts
|
||||
tests/webhost/webtsc.js
|
||||
tests/cases/**/*.js
|
||||
|
||||
@ -83,6 +83,7 @@ namespace ts {
|
||||
getShorthandAssignmentValueSymbol,
|
||||
getExportSpecifierLocalTargetSymbol,
|
||||
getTypeAtLocation: getTypeOfNode,
|
||||
getPropertySymbolOfDestructuringAssignment,
|
||||
typeToString,
|
||||
getSymbolDisplayBuilder,
|
||||
symbolToString,
|
||||
@ -11810,39 +11811,43 @@ namespace ts {
|
||||
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
const properties = node.properties;
|
||||
for (const p of properties) {
|
||||
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
const name = <PropertyName>(<PropertyAssignment>p).name;
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
checkComputedPropertyName(<ComputedPropertyName>name);
|
||||
}
|
||||
if (isComputedNonLiteralName(name)) {
|
||||
continue;
|
||||
}
|
||||
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, contextualMapper);
|
||||
}
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
const text = getTextOfPropertyName(name);
|
||||
const type = isTypeAny(sourceType)
|
||||
? sourceType
|
||||
: getTypeOfPropertyOfType(sourceType, text) ||
|
||||
isNumericLiteralName(text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
|
||||
getIndexTypeOfType(sourceType, IndexKind.String);
|
||||
if (type) {
|
||||
if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
checkDestructuringAssignment(<ShorthandPropertyAssignment>p, type);
|
||||
}
|
||||
else {
|
||||
// non-shorthand property assignments should always have initializers
|
||||
checkDestructuringAssignment((<PropertyAssignment>p).initializer, type);
|
||||
}
|
||||
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElement, contextualMapper?: TypeMapper) {
|
||||
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
const name = <PropertyName>(<PropertyAssignment>property).name;
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
checkComputedPropertyName(<ComputedPropertyName>name);
|
||||
}
|
||||
if (isComputedNonLiteralName(name)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const text = getTextOfPropertyName(name);
|
||||
const type = isTypeAny(objectLiteralType)
|
||||
? objectLiteralType
|
||||
: getTypeOfPropertyOfType(objectLiteralType, text) ||
|
||||
isNumericLiteralName(text) && getIndexTypeOfType(objectLiteralType, IndexKind.Number) ||
|
||||
getIndexTypeOfType(objectLiteralType, IndexKind.String);
|
||||
if (type) {
|
||||
if (property.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
return checkDestructuringAssignment(<ShorthandPropertyAssignment>property, type);
|
||||
}
|
||||
else {
|
||||
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), declarationNameToString(name));
|
||||
// non-shorthand property assignments should always have initializers
|
||||
return checkDestructuringAssignment((<PropertyAssignment>property).initializer, type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(p, Diagnostics.Property_assignment_expected);
|
||||
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), declarationNameToString(name));
|
||||
}
|
||||
}
|
||||
return sourceType;
|
||||
else {
|
||||
error(property, Diagnostics.Property_assignment_expected);
|
||||
}
|
||||
}
|
||||
|
||||
function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
@ -11852,44 +11857,51 @@ namespace ts {
|
||||
const elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false) || unknownType;
|
||||
const elements = node.elements;
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
const e = elements[i];
|
||||
if (e.kind !== SyntaxKind.OmittedExpression) {
|
||||
if (e.kind !== SyntaxKind.SpreadElementExpression) {
|
||||
const propName = "" + i;
|
||||
const type = isTypeAny(sourceType)
|
||||
? sourceType
|
||||
: isTupleLikeType(sourceType)
|
||||
? getTypeOfPropertyOfType(sourceType, propName)
|
||||
: elementType;
|
||||
if (type) {
|
||||
checkDestructuringAssignment(e, type, contextualMapper);
|
||||
}
|
||||
else {
|
||||
if (isTupleType(sourceType)) {
|
||||
error(e, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), (<TupleType>sourceType).elementTypes.length, elements.length);
|
||||
}
|
||||
else {
|
||||
error(e, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName);
|
||||
}
|
||||
}
|
||||
checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, contextualMapper);
|
||||
}
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
function checkArrayLiteralDestructuringElementAssignment(node: ArrayLiteralExpression, sourceType: Type,
|
||||
elementIndex: number, elementType: Type, contextualMapper?: TypeMapper) {
|
||||
const elements = node.elements;
|
||||
const element = elements[elementIndex];
|
||||
if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||
if (element.kind !== SyntaxKind.SpreadElementExpression) {
|
||||
const propName = "" + elementIndex;
|
||||
const type = isTypeAny(sourceType)
|
||||
? sourceType
|
||||
: isTupleLikeType(sourceType)
|
||||
? getTypeOfPropertyOfType(sourceType, propName)
|
||||
: elementType;
|
||||
if (type) {
|
||||
return checkDestructuringAssignment(element, type, contextualMapper);
|
||||
}
|
||||
else {
|
||||
if (i < elements.length - 1) {
|
||||
error(e, Diagnostics.A_rest_element_must_be_last_in_an_array_destructuring_pattern);
|
||||
if (isTupleType(sourceType)) {
|
||||
error(element, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), (<TupleType>sourceType).elementTypes.length, elements.length);
|
||||
}
|
||||
else {
|
||||
const restExpression = (<SpreadElementExpression>e).expression;
|
||||
if (restExpression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>restExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
error((<BinaryExpression>restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
}
|
||||
else {
|
||||
checkDestructuringAssignment(restExpression, createArrayType(elementType), contextualMapper);
|
||||
}
|
||||
error(element, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (elementIndex < elements.length - 1) {
|
||||
error(element, Diagnostics.A_rest_element_must_be_last_in_an_array_destructuring_pattern);
|
||||
}
|
||||
else {
|
||||
const restExpression = (<SpreadElementExpression>element).expression;
|
||||
if (restExpression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>restExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
error((<BinaryExpression>restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
}
|
||||
else {
|
||||
return checkDestructuringAssignment(restExpression, createArrayType(elementType), contextualMapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sourceType;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
@ -16562,6 +16574,53 @@ namespace ts {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
// Gets the type of object literal or array literal of destructuring assignment.
|
||||
// { a } from
|
||||
// for ( { a } of elems) {
|
||||
// }
|
||||
// [ a ] from
|
||||
// [a] = [ some array ...]
|
||||
function getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr: Expression): Type {
|
||||
Debug.assert(expr.kind === SyntaxKind.ObjectLiteralExpression || expr.kind === SyntaxKind.ArrayLiteralExpression);
|
||||
// If this is from "for of"
|
||||
// for ( { a } of elems) {
|
||||
// }
|
||||
if (expr.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
const iteratedType = checkRightHandSideOfForOf((<ForOfStatement>expr.parent).expression);
|
||||
return checkDestructuringAssignment(expr, iteratedType || unknownType);
|
||||
}
|
||||
// If this is from "for" initializer
|
||||
// for ({a } = elems[0];.....) { }
|
||||
if (expr.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
const iteratedType = checkExpression((<BinaryExpression>expr.parent).right);
|
||||
return checkDestructuringAssignment(expr, iteratedType || unknownType);
|
||||
}
|
||||
// If this is from nested object binding pattern
|
||||
// for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
|
||||
if (expr.parent.kind === SyntaxKind.PropertyAssignment) {
|
||||
const typeOfParentObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(<Expression>expr.parent.parent);
|
||||
return checkObjectLiteralDestructuringPropertyAssignment(typeOfParentObjectLiteral || unknownType, <ObjectLiteralElement>expr.parent);
|
||||
}
|
||||
// Array literal assignment - array destructuring pattern
|
||||
Debug.assert(expr.parent.kind === SyntaxKind.ArrayLiteralExpression);
|
||||
// [{ property1: p1, property2 }] = elems;
|
||||
const typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(<Expression>expr.parent);
|
||||
const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false) || unknownType;
|
||||
return checkArrayLiteralDestructuringElementAssignment(<ArrayLiteralExpression>expr.parent, typeOfArrayLiteral,
|
||||
indexOf((<ArrayLiteralExpression>expr.parent).elements, expr), elementType || unknownType);
|
||||
}
|
||||
|
||||
// Gets the property symbol corresponding to the property in destructuring assignment
|
||||
// 'property1' from
|
||||
// for ( { property1: a } of elems) {
|
||||
// }
|
||||
// 'property1' at location 'a' from:
|
||||
// [a] = [ property1, property2 ]
|
||||
function getPropertySymbolOfDestructuringAssignment(location: Identifier) {
|
||||
// Get the type of the object or array literal and then look for property of given name in the type
|
||||
const typeOfObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(<Expression>location.parent.parent);
|
||||
return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.text);
|
||||
}
|
||||
|
||||
function getTypeOfExpression(expr: Expression): Type {
|
||||
if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
|
||||
|
||||
@ -1741,6 +1741,7 @@ namespace ts {
|
||||
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol;
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
|
||||
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
|
||||
|
||||
@ -5660,8 +5660,51 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function isImportSpecifierSymbol(symbol: Symbol) {
|
||||
return (symbol.flags & SymbolFlags.Alias) && !!getDeclarationOfKind(symbol, SyntaxKind.ImportSpecifier);
|
||||
function getAliasSymbolForPropertyNameSymbol(symbol: Symbol, location: Node): Symbol {
|
||||
if (symbol.flags & SymbolFlags.Alias) {
|
||||
// Default import get alias
|
||||
const defaultImport = getDeclarationOfKind(symbol, SyntaxKind.ImportClause);
|
||||
if (defaultImport) {
|
||||
return typeChecker.getAliasedSymbol(symbol);
|
||||
}
|
||||
|
||||
const importOrExportSpecifier = <ImportOrExportSpecifier>forEach(symbol.declarations,
|
||||
declaration => (declaration.kind === SyntaxKind.ImportSpecifier ||
|
||||
declaration.kind === SyntaxKind.ExportSpecifier) ? declaration : undefined);
|
||||
if (importOrExportSpecifier &&
|
||||
// export { a }
|
||||
(!importOrExportSpecifier.propertyName ||
|
||||
// export {a as class } where a is location
|
||||
importOrExportSpecifier.propertyName === location)) {
|
||||
// If Import specifier -> get alias
|
||||
// else Export specifier -> get local target
|
||||
return importOrExportSpecifier.kind === SyntaxKind.ImportSpecifier ?
|
||||
typeChecker.getAliasedSymbol(symbol) :
|
||||
typeChecker.getExportSpecifierLocalTargetSymbol(importOrExportSpecifier);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getPropertySymbolOfDestructuringAssignment(location: Node) {
|
||||
return isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) &&
|
||||
typeChecker.getPropertySymbolOfDestructuringAssignment(<Identifier>location);
|
||||
}
|
||||
|
||||
function isObjectBindingPatternElementWithoutPropertyName(symbol: Symbol) {
|
||||
const bindingElement = <BindingElement>getDeclarationOfKind(symbol, SyntaxKind.BindingElement);
|
||||
return bindingElement &&
|
||||
bindingElement.parent.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
!bindingElement.propertyName;
|
||||
}
|
||||
|
||||
function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol) {
|
||||
if (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
|
||||
const bindingElement = <BindingElement>getDeclarationOfKind(symbol, SyntaxKind.BindingElement);
|
||||
const typeOfPattern = typeChecker.getTypeAtLocation(bindingElement.parent);
|
||||
return typeOfPattern && typeChecker.getPropertyOfType(typeOfPattern, (<Identifier>bindingElement.name).text);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getInternedName(symbol: Symbol, location: Node, declarations: Declaration[]): string {
|
||||
@ -5709,6 +5752,12 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If symbol is of object binding pattern element without property name we would want to
|
||||
// look for property too and that could be anywhere
|
||||
if (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// if this symbol is visible from its parent container, e.g. exported, then bail out
|
||||
// if symbol correspond to the union property - bail out
|
||||
if (symbol.parent || (symbol.flags & SymbolFlags.SyntheticProperty)) {
|
||||
@ -6104,18 +6153,30 @@ namespace ts {
|
||||
// The search set contains at least the current symbol
|
||||
let result = [symbol];
|
||||
|
||||
// If the symbol is an alias, add what it aliases to the list
|
||||
if (isImportSpecifierSymbol(symbol)) {
|
||||
result.push(typeChecker.getAliasedSymbol(symbol));
|
||||
// If the location is name of property symbol from object literal destructuring pattern
|
||||
// Search the property symbol
|
||||
// for ( { property: p2 } of elems) { }
|
||||
if (isNameOfPropertyAssignment(location) && location.parent.kind !== SyntaxKind.ShorthandPropertyAssignment) {
|
||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(location);
|
||||
if (propertySymbol) {
|
||||
result.push(propertySymbol);
|
||||
}
|
||||
}
|
||||
|
||||
// For export specifiers, the exported name can be referring to a local symbol, e.g.:
|
||||
// If the symbol is an alias, add what it aliases to the list
|
||||
// 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(<ExportSpecifier>location.parent));
|
||||
// export {a}
|
||||
// If the symbol is an alias to default declaration, add what it aliases to the list
|
||||
// declare "mod" { export default class B { } }
|
||||
// import B from "mod";
|
||||
//// For export specifiers, the exported name can be referring 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)
|
||||
const aliasSymbol = getAliasSymbolForPropertyNameSymbol(symbol, location);
|
||||
if (aliasSymbol) {
|
||||
result = result.concat(populateSearchSymbolSet(aliasSymbol, location));
|
||||
}
|
||||
|
||||
// If the location is in a context sensitive location (i.e. in an object literal) try
|
||||
@ -6152,6 +6213,13 @@ namespace ts {
|
||||
result = result.concat(typeChecker.getSymbolsOfParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration, symbol.name));
|
||||
}
|
||||
|
||||
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
||||
// Include the property in the search
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol);
|
||||
if (bindingElementPropertySymbol) {
|
||||
result.push(bindingElementPropertySymbol);
|
||||
}
|
||||
|
||||
// If this is a union property, add all the symbols from all its source symbols in all unioned types.
|
||||
// If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
|
||||
forEach(typeChecker.getRootSymbols(symbol), rootSymbol => {
|
||||
@ -6233,32 +6301,40 @@ namespace ts {
|
||||
}
|
||||
|
||||
// If the reference symbol is an alias, check if what it is aliasing is one of the search
|
||||
// symbols.
|
||||
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(<ExportSpecifier>referenceLocation.parent);
|
||||
if (searchSymbols.indexOf(aliasedSymbol) >= 0) {
|
||||
return aliasedSymbol;
|
||||
}
|
||||
// symbols but by looking up for related symbol of this alias so it can handle multiple level of indirectness.
|
||||
const aliasSymbol = getAliasSymbolForPropertyNameSymbol(referenceSymbol, referenceLocation);
|
||||
if (aliasSymbol) {
|
||||
return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation);
|
||||
}
|
||||
|
||||
// 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
|
||||
if (isNameOfPropertyAssignment(referenceLocation)) {
|
||||
return forEach(getPropertySymbolsFromContextualType(referenceLocation), contextualSymbol => {
|
||||
const contextualSymbol = forEach(getPropertySymbolsFromContextualType(referenceLocation), contextualSymbol => {
|
||||
return forEach(typeChecker.getRootSymbols(contextualSymbol), s => searchSymbols.indexOf(s) >= 0 ? s : undefined);
|
||||
});
|
||||
|
||||
if (contextualSymbol) {
|
||||
return contextualSymbol;
|
||||
}
|
||||
|
||||
// If the reference location is the name of property from object literal destructuring pattern
|
||||
// Get the property symbol from the object literal's type and look if thats the search symbol
|
||||
// In below eg. get 'property' from type of elems iterating type
|
||||
// for ( { property: p2 } of elems) { }
|
||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation);
|
||||
if (propertySymbol && searchSymbols.indexOf(propertySymbol) >= 0) {
|
||||
return propertySymbol;
|
||||
}
|
||||
}
|
||||
|
||||
// If the reference location is the binding element and doesn't have property name
|
||||
// then include the binding element in the related symbols
|
||||
// let { a } : { a };
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol);
|
||||
if (bindingElementPropertySymbol && searchSymbols.indexOf(bindingElementPropertySymbol) >= 0) {
|
||||
return bindingElementPropertySymbol;
|
||||
}
|
||||
|
||||
// Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
////}
|
||||
////
|
||||
////var foo: I;
|
||||
////var [{ [|property1|]: prop1 }, { property1, property2 } ] = [foo, foo];
|
||||
////var [{ [|property1|]: prop1 }, { [|property1|], property2 } ] = [foo, foo];
|
||||
|
||||
let ranges = test.ranges();
|
||||
for (let range of ranges) {
|
||||
|
||||
@ -6,14 +6,12 @@
|
||||
////}
|
||||
////
|
||||
////function f({ /**/[|property1|]: p1 }: I,
|
||||
//// { /*SHOULD_BE_A_REFERENCE*/property1 }: I,
|
||||
//// { [|property1|] }: I,
|
||||
//// { property1: p2 }) {
|
||||
////
|
||||
//// return property1 + 1;
|
||||
//// return [|property1|] + 1;
|
||||
////}
|
||||
|
||||
// NOTE: In the future, the identifier at
|
||||
// SHOULD_BE_A_REFERENCE should be in the set of ranges.
|
||||
goTo.marker();
|
||||
|
||||
let ranges = test.ranges();
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
////var elems: I[];
|
||||
////for (let { [|property1|]: p } of elems) {
|
||||
////}
|
||||
////for (let { property1 } of elems) {
|
||||
////for (let { [|property1|] } of elems) {
|
||||
////}
|
||||
////for (var { [|property1|]: p1 } of elems) {
|
||||
////}
|
||||
////var p2;
|
||||
////for ({ property1 : p2 } of elems) {
|
||||
////for ({ [|property1|] : p2 } of elems) {
|
||||
////}
|
||||
|
||||
// Note: if this test ever changes, consider updating
|
||||
|
||||
@ -1,19 +1,17 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////interface I {
|
||||
//// /*SHOULD_BE_A_REFERENCE1*/property1: number;
|
||||
//// [|property1|]: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////
|
||||
////function f({ /*SHOULD_BE_A_REFERENCE2*/property1: p1 }: I,
|
||||
////function f({ [|property1|]: p1 }: I,
|
||||
//// { /**/[|property1|] }: I,
|
||||
//// { property1: p2 }) {
|
||||
////
|
||||
//// return [|property1|] + 1;
|
||||
////}
|
||||
|
||||
// NOTE: In the future, the identifiers at
|
||||
// SHOULD_BE_A_REFERENCE[1/2] should be in the set of ranges.
|
||||
goTo.marker();
|
||||
|
||||
let ranges = test.ranges();
|
||||
|
||||
19
tests/cases/fourslash/renameDefaultImport.ts
Normal file
19
tests/cases/fourslash/renameDefaultImport.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: B.ts
|
||||
////export default class [|B|] {
|
||||
//// test() {
|
||||
//// }
|
||||
////}
|
||||
|
||||
// @Filename: A.ts
|
||||
////import [|B|] from "./B";
|
||||
////let b = new [|B|]();
|
||||
////b.test();
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.file(range.fileName);
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
23
tests/cases/fourslash/renameDefaultImportDifferentName.ts
Normal file
23
tests/cases/fourslash/renameDefaultImportDifferentName.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: B.ts
|
||||
////export default class /*1*/C {
|
||||
//// test() {
|
||||
//// }
|
||||
////}
|
||||
|
||||
// @Filename: A.ts
|
||||
////import [|B|] from "./B";
|
||||
////let b = new [|B|]();
|
||||
////b.test();
|
||||
|
||||
goTo.file("B.ts");
|
||||
goTo.marker("1");
|
||||
verify.occurrencesAtPositionCount(1);
|
||||
|
||||
goTo.file("A.ts");
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
14
tests/cases/fourslash/renameDestructuringAssignment.ts
Normal file
14
tests/cases/fourslash/renameDestructuringAssignment.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// [|x|]: number;
|
||||
////}
|
||||
////var a: I;
|
||||
////var x;
|
||||
////({ [|x|]: x } = a);
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
20
tests/cases/fourslash/renameDestructuringAssignmentInFor.ts
Normal file
20
tests/cases/fourslash/renameDestructuringAssignmentInFor.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// /*1*/[|property1|]: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////var elems: I[];
|
||||
////
|
||||
////var p2: number, property1: number;
|
||||
////for ({ [|property1|] } = elems[0]; p2 < 100; p2++) {
|
||||
//// p2 = property1++;
|
||||
////}
|
||||
////for ({ /*2*/[|property1|]: p2 } = elems[0]; p2 < 100; p2++) {
|
||||
////}
|
||||
|
||||
goTo.marker("1");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
|
||||
goTo.marker("2");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
20
tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts
Normal file
20
tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// property1: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////var elems: I[];
|
||||
////
|
||||
////var p2: number, [|property1|]: number;
|
||||
////for ({ [|property1|] } = elems[0]; p2 < 100; p2++) {
|
||||
//// p2 = [|property1|]++;
|
||||
////}
|
||||
////for ({ property1: p2 } = elems[0]; p2 < 100; p2++) {
|
||||
////}
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// /*1*/[|property1|]: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////var elems: I[];
|
||||
////
|
||||
////var property1: number, p2: number;
|
||||
////for ({ [|property1|] } of elems) {
|
||||
//// property1++;
|
||||
////}
|
||||
////for ({ /*2*/[|property1|]: p2 } of elems) {
|
||||
////}
|
||||
|
||||
goTo.marker("1");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
|
||||
goTo.marker("2");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// property1: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////var elems: I[];
|
||||
////
|
||||
////var [|property1|]: number, p2: number;
|
||||
////for ({ [|property1|] } of elems) {
|
||||
//// [|property1|]++;
|
||||
////}
|
||||
////for ({ property1: p2 } of elems) {
|
||||
////}
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// /*1*/[|property1|]: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////var elems: I[], p1: number, property1: number;
|
||||
////[{ /*2*/[|property1|]: p1 }] = elems;
|
||||
////[{ [|property1|] }] = elems;
|
||||
|
||||
goTo.marker("1");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
|
||||
goTo.marker("2");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// property1: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////var elems: I[], p1: number, [|property1|]: number;
|
||||
////[{ property1: p1 }] = elems;
|
||||
////[{ [|property1|] }] = elems;
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface MultiRobot {
|
||||
//// name: string;
|
||||
//// skills: {
|
||||
//// /*1*/[|primary|]: string;
|
||||
//// secondary: string;
|
||||
//// };
|
||||
////}
|
||||
////let multiRobot: MultiRobot;
|
||||
////for ({ skills: { /*2*/[|primary|]: primaryA, secondary: secondaryA } } = multiRobot, i = 0; i < 1; i++) {
|
||||
//// console.log(primaryA);
|
||||
////}
|
||||
////for ({ skills: { [|primary|], secondary } } = multiRobot, i = 0; i < 1; i++) {
|
||||
//// console.log(primary);
|
||||
////}
|
||||
|
||||
goTo.marker("1");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
|
||||
goTo.marker("2");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface MultiRobot {
|
||||
//// name: string;
|
||||
//// skills: {
|
||||
//// primary: string;
|
||||
//// secondary: string;
|
||||
//// };
|
||||
////}
|
||||
////let multiRobot: MultiRobot, [|primary|]: string;
|
||||
////for ({ skills: { primary: primaryA, secondary: secondaryA } } = multiRobot, i = 0; i < 1; i++) {
|
||||
//// console.log(primaryA);
|
||||
////}
|
||||
////for ({ skills: { [|primary|], secondary } } = multiRobot, i = 0; i < 1; i++) {
|
||||
//// console.log([|primary|]);
|
||||
////}
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface MultiRobot {
|
||||
//// name: string;
|
||||
//// skills: {
|
||||
//// /*1*/[|primary|]: string;
|
||||
//// secondary: string;
|
||||
//// };
|
||||
////}
|
||||
////let multiRobots: MultiRobot[];
|
||||
////for ({ skills: { /*2*/[|primary|]: primaryA, secondary: secondaryA } } of multiRobots) {
|
||||
//// console.log(primaryA);
|
||||
////}
|
||||
////for ({ skills: { [|primary|], secondary } } of multiRobots) {
|
||||
//// console.log(primary);
|
||||
////}
|
||||
|
||||
goTo.marker("1");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
|
||||
goTo.marker("2");
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface MultiRobot {
|
||||
//// name: string;
|
||||
//// skills: {
|
||||
//// primary: string;
|
||||
//// secondary: string;
|
||||
//// };
|
||||
////}
|
||||
////let multiRobots: MultiRobot[], [|primary|]: string;
|
||||
////for ({ skills: { primary: primaryA, secondary: secondaryA } } of multiRobots) {
|
||||
//// console.log(primaryA);
|
||||
////}
|
||||
////for ({ skills: { [|primary|], secondary } } of multiRobots) {
|
||||
//// console.log([|primary|]);
|
||||
////}
|
||||
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
23
tests/cases/fourslash/renameDestructuringClassProperty.ts
Normal file
23
tests/cases/fourslash/renameDestructuringClassProperty.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class A {
|
||||
//// [|foo|]: string;
|
||||
////}
|
||||
////class B {
|
||||
//// syntax1(a: A): void {
|
||||
//// let { [|foo|] } = a;
|
||||
//// }
|
||||
//// syntax2(a: A): void {
|
||||
//// let { [|foo|]: foo } = a;
|
||||
//// }
|
||||
//// syntax11(a: A): void {
|
||||
//// let { [|foo|] } = a;
|
||||
//// [|foo|] = "newString";
|
||||
//// }
|
||||
////}
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
20
tests/cases/fourslash/renameDestructuringDeclarationInFor.ts
Normal file
20
tests/cases/fourslash/renameDestructuringDeclarationInFor.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// [|property1|]: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////var elems: I[];
|
||||
////
|
||||
////var p2: number, property1: number;
|
||||
////for (let { [|property1|]: p2 } = elems[0]; p2 < 100; p2++) {
|
||||
////}
|
||||
////for (let { [|property1|] } = elems[0]; p2 < 100; p2++) {
|
||||
//// [|property1|] = p2;
|
||||
////}
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface I {
|
||||
//// [|property1|]: number;
|
||||
//// property2: string;
|
||||
////}
|
||||
////var elems: I[];
|
||||
////
|
||||
////for (let { [|property1|] } of elems) {
|
||||
//// [|property1|]++;
|
||||
////}
|
||||
////for (let { [|property1|]: p2 } of elems) {
|
||||
////}
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f({[|a|]}: {[|a|]}) {
|
||||
//// f({[|a|]});
|
||||
////}
|
||||
let ranges = test.ranges();
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface MultiRobot {
|
||||
//// name: string;
|
||||
//// skills: {
|
||||
//// [|primary|]: string;
|
||||
//// secondary: string;
|
||||
//// };
|
||||
////}
|
||||
////let multiRobots: MultiRobot[];
|
||||
////for (let { skills: {[|primary|]: primaryA, secondary: secondaryA } } of multiRobots) {
|
||||
//// console.log(primaryA);
|
||||
////}
|
||||
////for (let { skills: {[|primary|], secondary } } of multiRobots) {
|
||||
//// console.log([|primary|]);
|
||||
////}
|
||||
|
||||
let ranges = test.ranges()
|
||||
for (let range of ranges) {
|
||||
goTo.position(range.start);
|
||||
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);
|
||||
}
|
||||
18
tests/cases/fourslash/renameImportAndExportInDiffFiles.ts
Normal file
18
tests/cases/fourslash/renameImportAndExportInDiffFiles.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: a.ts
|
||||
////export var /*1*/a;
|
||||
|
||||
// @Filename: b.ts
|
||||
////import { /*2*/a } from './a';
|
||||
////export { /*3*/a };
|
||||
|
||||
goTo.file("a.ts");
|
||||
goTo.marker("1");
|
||||
|
||||
goTo.file("b.ts");
|
||||
goTo.marker("2");
|
||||
verify.referencesCountIs(3);
|
||||
|
||||
goTo.marker("3");
|
||||
verify.referencesCountIs(3);
|
||||
Loading…
x
Reference in New Issue
Block a user