mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-16 15:45:27 -05:00
Merge pull request #9270 from Microsoft/this_references
Allow to find all references of the 'this 'keyword
This commit is contained in:
@@ -2473,16 +2473,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function buildDisplayForParametersAndDelimiters(thisType: Type, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
function buildDisplayForParametersAndDelimiters(thisParameter: Symbol | undefined, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
writePunctuation(writer, SyntaxKind.OpenParenToken);
|
||||
if (thisType) {
|
||||
writeKeyword(writer, SyntaxKind.ThisKeyword);
|
||||
writePunctuation(writer, SyntaxKind.ColonToken);
|
||||
writeSpace(writer);
|
||||
buildTypeDisplay(thisType, writer, enclosingDeclaration, flags, symbolStack);
|
||||
if (thisParameter) {
|
||||
buildParameterDisplay(thisParameter, writer, enclosingDeclaration, flags, symbolStack);
|
||||
}
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
if (i > 0 || thisType) {
|
||||
if (i > 0 || thisParameter) {
|
||||
writePunctuation(writer, SyntaxKind.CommaToken);
|
||||
writeSpace(writer);
|
||||
}
|
||||
@@ -2538,7 +2535,7 @@ namespace ts {
|
||||
buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, symbolStack);
|
||||
}
|
||||
|
||||
buildDisplayForParametersAndDelimiters(signature.thisType, signature.parameters, writer, enclosingDeclaration, flags, symbolStack);
|
||||
buildDisplayForParametersAndDelimiters(signature.thisParameter, signature.parameters, writer, enclosingDeclaration, flags, symbolStack);
|
||||
|
||||
buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack);
|
||||
}
|
||||
@@ -2981,12 +2978,14 @@ namespace ts {
|
||||
if (func.kind === SyntaxKind.SetAccessor && !hasDynamicName(func)) {
|
||||
const getter = <AccessorDeclaration>getDeclarationOfKind(declaration.parent.symbol, SyntaxKind.GetAccessor);
|
||||
if (getter) {
|
||||
const signature = getSignatureFromDeclaration(getter);
|
||||
const getterSignature = getSignatureFromDeclaration(getter);
|
||||
const thisParameter = getAccessorThisParameter(func as AccessorDeclaration);
|
||||
if (thisParameter && declaration === thisParameter) {
|
||||
return signature.thisType;
|
||||
// Use the type from the *getter*
|
||||
Debug.assert(!thisParameter.type);
|
||||
return getTypeOfSymbol(getterSignature.thisParameter);
|
||||
}
|
||||
return getReturnTypeOfSignature(signature);
|
||||
return getReturnTypeOfSignature(getterSignature);
|
||||
}
|
||||
}
|
||||
// Use contextual parameter type if one is available
|
||||
@@ -3208,14 +3207,13 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getAnnotatedAccessorThisType(accessor: AccessorDeclaration): Type {
|
||||
if (accessor) {
|
||||
const parameter = getAccessorThisParameter(accessor);
|
||||
if (parameter && parameter.type) {
|
||||
return getTypeFromTypeNode(accessor.parameters[0].type);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
function getAnnotatedAccessorThisParameter(accessor: AccessorDeclaration): Symbol | undefined {
|
||||
const parameter = getAccessorThisParameter(accessor);
|
||||
return parameter && parameter.symbol;
|
||||
}
|
||||
|
||||
function getThisTypeOfDeclaration(declaration: SignatureDeclaration): Type | undefined {
|
||||
return getThisTypeOfSignature(getSignatureFromDeclaration(declaration));
|
||||
}
|
||||
|
||||
function getTypeOfAccessors(symbol: Symbol): Type {
|
||||
@@ -3898,13 +3896,13 @@ namespace ts {
|
||||
resolveObjectTypeMembers(type, source, typeParameters, typeArguments);
|
||||
}
|
||||
|
||||
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisType: Type, parameters: Symbol[],
|
||||
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[],
|
||||
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature {
|
||||
const sig = new Signature(checker);
|
||||
sig.declaration = declaration;
|
||||
sig.typeParameters = typeParameters;
|
||||
sig.parameters = parameters;
|
||||
sig.thisType = thisType;
|
||||
sig.thisParameter = thisParameter;
|
||||
sig.resolvedReturnType = resolvedReturnType;
|
||||
sig.typePredicate = typePredicate;
|
||||
sig.minArgumentCount = minArgumentCount;
|
||||
@@ -3914,7 +3912,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function cloneSignature(sig: Signature): Signature {
|
||||
return createSignature(sig.declaration, sig.typeParameters, sig.thisType, sig.parameters, sig.resolvedReturnType,
|
||||
return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, sig.resolvedReturnType,
|
||||
sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals);
|
||||
}
|
||||
|
||||
@@ -4012,8 +4010,9 @@ namespace ts {
|
||||
// Union the result types when more than one signature matches
|
||||
if (unionSignatures.length > 1) {
|
||||
s = cloneSignature(signature);
|
||||
if (forEach(unionSignatures, sig => sig.thisType)) {
|
||||
s.thisType = getUnionType(map(unionSignatures, sig => sig.thisType || anyType));
|
||||
if (forEach(unionSignatures, sig => sig.thisParameter)) {
|
||||
const thisType = getUnionType(map(unionSignatures, sig => getTypeOfSymbol(sig.thisParameter) || anyType));
|
||||
s.thisParameter = createTransientSymbol(signature.thisParameter, thisType);
|
||||
}
|
||||
// Clear resolved return type we possibly got from cloneSignature
|
||||
s.resolvedReturnType = undefined;
|
||||
@@ -4466,7 +4465,7 @@ namespace ts {
|
||||
const parameters: Symbol[] = [];
|
||||
let hasStringLiterals = false;
|
||||
let minArgumentCount = -1;
|
||||
let thisType: Type = undefined;
|
||||
let thisParameter: Symbol = undefined;
|
||||
let hasThisParameter: boolean;
|
||||
const isJSConstructSignature = isJSDocConstructSignature(declaration);
|
||||
|
||||
@@ -4484,7 +4483,7 @@ namespace ts {
|
||||
}
|
||||
if (i === 0 && paramSymbol.name === "this") {
|
||||
hasThisParameter = true;
|
||||
thisType = param.type ? getTypeFromTypeNode(param.type) : unknownType;
|
||||
thisParameter = param.symbol;
|
||||
}
|
||||
else {
|
||||
parameters.push(paramSymbol);
|
||||
@@ -4508,10 +4507,12 @@ namespace ts {
|
||||
// If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation
|
||||
if ((declaration.kind === SyntaxKind.GetAccessor || declaration.kind === SyntaxKind.SetAccessor) &&
|
||||
!hasDynamicName(declaration) &&
|
||||
(!hasThisParameter || thisType === unknownType)) {
|
||||
(!hasThisParameter || !thisParameter)) {
|
||||
const otherKind = declaration.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
|
||||
const setter = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, otherKind);
|
||||
thisType = getAnnotatedAccessorThisType(setter);
|
||||
const other = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, otherKind);
|
||||
if (other) {
|
||||
thisParameter = getAnnotatedAccessorThisParameter(other);
|
||||
}
|
||||
}
|
||||
|
||||
if (minArgumentCount < 0) {
|
||||
@@ -4532,7 +4533,7 @@ namespace ts {
|
||||
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
|
||||
undefined;
|
||||
|
||||
links.resolvedSignature = createSignature(declaration, typeParameters, thisType, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasStringLiterals);
|
||||
links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasStringLiterals);
|
||||
}
|
||||
return links.resolvedSignature;
|
||||
}
|
||||
@@ -4614,6 +4615,12 @@ namespace ts {
|
||||
return anyType;
|
||||
}
|
||||
|
||||
function getThisTypeOfSignature(signature: Signature): Type | undefined {
|
||||
if (signature.thisParameter) {
|
||||
return getTypeOfSymbol(signature.thisParameter);
|
||||
}
|
||||
}
|
||||
|
||||
function getReturnTypeOfSignature(signature: Signature): Type {
|
||||
if (!signature.resolvedReturnType) {
|
||||
if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) {
|
||||
@@ -5465,7 +5472,7 @@ namespace ts {
|
||||
freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper);
|
||||
}
|
||||
const result = createSignature(signature.declaration, freshTypeParameters,
|
||||
signature.thisType && instantiateType(signature.thisType, mapper),
|
||||
signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper),
|
||||
instantiateList(signature.parameters, mapper, instantiateSymbol),
|
||||
instantiateType(signature.resolvedReturnType, mapper),
|
||||
freshTypePredicate,
|
||||
@@ -5737,17 +5744,22 @@ namespace ts {
|
||||
target = getErasedSignature(target);
|
||||
|
||||
let result = Ternary.True;
|
||||
if (source.thisType && target.thisType && source.thisType !== voidType) {
|
||||
// void sources are assignable to anything.
|
||||
const related = compareTypes(source.thisType, target.thisType, /*reportErrors*/ false)
|
||||
|| compareTypes(target.thisType, source.thisType, reportErrors);
|
||||
if (!related) {
|
||||
if (reportErrors) {
|
||||
errorReporter(Diagnostics.The_this_types_of_each_signature_are_incompatible);
|
||||
|
||||
const sourceThisType = getThisTypeOfSignature(source);
|
||||
if (sourceThisType && sourceThisType !== voidType) {
|
||||
const targetThisType = getThisTypeOfSignature(target);
|
||||
if (targetThisType) {
|
||||
// void sources are assignable to anything.
|
||||
const related = compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false)
|
||||
|| compareTypes(targetThisType, sourceThisType, reportErrors);
|
||||
if (!related) {
|
||||
if (reportErrors) {
|
||||
errorReporter(Diagnostics.The_this_types_of_each_signature_are_incompatible);
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
return Ternary.False;
|
||||
result &= related;
|
||||
}
|
||||
result &= related;
|
||||
}
|
||||
|
||||
const sourceMax = getNumNonRestParameters(source);
|
||||
@@ -6762,13 +6774,21 @@ namespace ts {
|
||||
source = getErasedSignature(source);
|
||||
target = getErasedSignature(target);
|
||||
let result = Ternary.True;
|
||||
if (!ignoreThisTypes && source.thisType && target.thisType) {
|
||||
const related = compareTypes(source.thisType, target.thisType);
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
|
||||
if (!ignoreThisTypes) {
|
||||
const sourceThisType = getThisTypeOfSignature(source);
|
||||
if (sourceThisType) {
|
||||
const targetThisType = getThisTypeOfSignature(target);
|
||||
if (targetThisType) {
|
||||
const related = compareTypes(sourceThisType, targetThisType);
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
}
|
||||
result &= related;
|
||||
}
|
||||
}
|
||||
result &= related;
|
||||
}
|
||||
|
||||
const targetLen = target.parameters.length;
|
||||
for (let i = 0; i < targetLen; i++) {
|
||||
const s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfParameter(source.parameters[i]);
|
||||
@@ -8594,9 +8614,10 @@ namespace ts {
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
const signature = getSignatureFromDeclaration(container);
|
||||
if (signature.thisType) {
|
||||
return signature.thisType;
|
||||
|
||||
const thisType = getThisTypeOfDeclaration(container);
|
||||
if (thisType) {
|
||||
return thisType;
|
||||
}
|
||||
}
|
||||
if (isClassLike(container.parent)) {
|
||||
@@ -8837,7 +8858,7 @@ namespace ts {
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
return contextualSignature.thisType;
|
||||
return getThisTypeOfSignature(contextualSignature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10637,10 +10658,11 @@ namespace ts {
|
||||
context.failedTypeParameterIndex = undefined;
|
||||
}
|
||||
|
||||
if (signature.thisType) {
|
||||
const thisType = getThisTypeOfSignature(signature);
|
||||
if (thisType) {
|
||||
const thisArgumentNode = getThisArgumentOfCall(node);
|
||||
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
|
||||
inferTypes(context, thisArgumentType, signature.thisType);
|
||||
inferTypes(context, thisArgumentType, thisType);
|
||||
}
|
||||
|
||||
// We perform two passes over the arguments. In the first pass we infer from all arguments, but use
|
||||
@@ -10716,8 +10738,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[], reportErrors: boolean) {
|
||||
|
||||
if (signature.thisType && signature.thisType !== voidType && node.kind !== SyntaxKind.NewExpression) {
|
||||
const thisType = getThisTypeOfSignature(signature);
|
||||
if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) {
|
||||
// If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType
|
||||
// If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible.
|
||||
// If the expression is a new expression, then the check is skipped.
|
||||
@@ -10725,7 +10747,7 @@ namespace ts {
|
||||
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
|
||||
const errorNode = reportErrors ? (thisArgumentNode || node) : undefined;
|
||||
const headMessage = Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1;
|
||||
if (!checkTypeRelatedTo(thisArgumentType, signature.thisType, relation, errorNode, headMessage)) {
|
||||
if (!checkTypeRelatedTo(thisArgumentType, getThisTypeOfSignature(signature), relation, errorNode, headMessage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -11444,7 +11466,7 @@ namespace ts {
|
||||
if (getReturnTypeOfSignature(signature) !== voidType) {
|
||||
error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
|
||||
}
|
||||
if (signature.thisType === voidType) {
|
||||
if (getThisTypeOfSignature(signature) === voidType) {
|
||||
error(node, Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void);
|
||||
}
|
||||
return signature;
|
||||
@@ -13482,7 +13504,7 @@ namespace ts {
|
||||
// TypeScript 1.0 spec (April 2014): 4.5
|
||||
// If both accessors include type annotations, the specified types must be identical.
|
||||
checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, Diagnostics.get_and_set_accessor_must_have_the_same_type);
|
||||
checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorThisType, Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
|
||||
checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
|
||||
}
|
||||
}
|
||||
getTypeOfAccessors(getSymbolOfNode(node));
|
||||
@@ -17162,6 +17184,15 @@ namespace ts {
|
||||
return getSymbolOfEntityNameOrPropertyAccessExpression(<EntityName | PropertyAccessExpression>node);
|
||||
|
||||
case SyntaxKind.ThisKeyword:
|
||||
const container = getThisContainer(node, /*includeArrowFunctions*/ false);
|
||||
if (isFunctionLike(container)) {
|
||||
const sig = getSignatureFromDeclaration(container);
|
||||
if (sig.thisParameter) {
|
||||
return sig.thisParameter;
|
||||
}
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case SyntaxKind.SuperKeyword:
|
||||
const type = isExpression(node) ? checkExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
|
||||
return type.symbol;
|
||||
@@ -18694,7 +18725,7 @@ namespace ts {
|
||||
return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 0 : 1);
|
||||
}
|
||||
|
||||
function getAccessorThisParameter(accessor: AccessorDeclaration) {
|
||||
function getAccessorThisParameter(accessor: AccessorDeclaration): ParameterDeclaration {
|
||||
if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2) &&
|
||||
accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>accessor.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
|
||||
|
||||
@@ -1874,7 +1874,7 @@ namespace ts {
|
||||
buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildDisplayForParametersAndDelimiters(thisType: Type, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
}
|
||||
@@ -2394,7 +2394,8 @@ namespace ts {
|
||||
declaration: SignatureDeclaration; // Originating declaration
|
||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
parameters: Symbol[]; // Parameters
|
||||
thisType?: Type; // type of this-type
|
||||
/* @internal */
|
||||
thisParameter?: Symbol; // symbol of this-type parameter
|
||||
/* @internal */
|
||||
resolvedReturnType: Type; // Resolved return type
|
||||
/* @internal */
|
||||
|
||||
@@ -760,7 +760,7 @@ namespace FourSlash {
|
||||
// Find the unaccounted-for reference.
|
||||
for (const actual of actualReferences) {
|
||||
if (!ts.forEach(expectedReferences, r => r.start === actual.textSpan.start)) {
|
||||
this.raiseError(`A reference ${actual} is unaccounted for.`);
|
||||
this.raiseError(`A reference ${stringify(actual)} is unaccounted for.`);
|
||||
}
|
||||
}
|
||||
// Probably will never reach here.
|
||||
@@ -907,13 +907,13 @@ namespace FourSlash {
|
||||
assert.equal(getDisplayPartsJson(actualQuickInfo.documentation), getDisplayPartsJson(documentation), this.messageAtLastKnownMarker("QuickInfo documentation"));
|
||||
}
|
||||
|
||||
public verifyRenameLocations(findInStrings: boolean, findInComments: boolean) {
|
||||
public verifyRenameLocations(findInStrings: boolean, findInComments: boolean, ranges?: Range[]) {
|
||||
const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (renameInfo.canRename) {
|
||||
let references = this.languageService.findRenameLocations(
|
||||
this.activeFile.fileName, this.currentCaretPosition, findInStrings, findInComments);
|
||||
|
||||
let ranges = this.getRanges();
|
||||
ranges = ranges || this.getRanges();
|
||||
|
||||
if (!references) {
|
||||
if (ranges.length !== 0) {
|
||||
@@ -3128,8 +3128,8 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRenameInfoFailed(message);
|
||||
}
|
||||
|
||||
public renameLocations(findInStrings: boolean, findInComments: boolean) {
|
||||
this.state.verifyRenameLocations(findInStrings, findInComments);
|
||||
public renameLocations(findInStrings: boolean, findInComments: boolean, ranges?: FourSlash.Range[]) {
|
||||
this.state.verifyRenameLocations(findInStrings, findInComments, ranges);
|
||||
}
|
||||
|
||||
public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: { start: number; length: number; },
|
||||
|
||||
@@ -779,7 +779,7 @@ namespace ts {
|
||||
declaration: SignatureDeclaration;
|
||||
typeParameters: TypeParameter[];
|
||||
parameters: Symbol[];
|
||||
thisType: Type;
|
||||
thisParameter: Symbol;
|
||||
resolvedReturnType: Type;
|
||||
minArgumentCount: number;
|
||||
hasRestParameter: boolean;
|
||||
@@ -5819,17 +5819,32 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (node.kind !== SyntaxKind.Identifier &&
|
||||
// TODO (drosen): This should be enabled in a later release - currently breaks rename.
|
||||
// node.kind !== SyntaxKind.ThisKeyword &&
|
||||
// node.kind !== SyntaxKind.SuperKeyword &&
|
||||
node.kind !== SyntaxKind.StringLiteral &&
|
||||
!isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
|
||||
return undefined;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
if (!isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
|
||||
break;
|
||||
}
|
||||
// Fallthrough
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
// case SyntaxKind.SuperKeyword: TODO:GH#9268
|
||||
case SyntaxKind.StringLiteral:
|
||||
return getReferencedSymbolsForNode(node, program.getSourceFiles(), findInStrings, findInComments);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.NumericLiteral || node.kind === SyntaxKind.StringLiteral);
|
||||
return getReferencedSymbolsForNode(node, program.getSourceFiles(), findInStrings, findInComments);
|
||||
function isThis(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ThisKeyword:
|
||||
// case SyntaxKind.ThisType: TODO: GH#9267
|
||||
return true;
|
||||
case SyntaxKind.Identifier:
|
||||
// 'this' as a parameter
|
||||
return (node as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword && node.parent.kind === SyntaxKind.Parameter;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getReferencedSymbolsForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] {
|
||||
@@ -5849,7 +5864,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.ThisType) {
|
||||
if (isThis(node)) {
|
||||
return getReferencesForThisKeyword(node, sourceFiles);
|
||||
}
|
||||
|
||||
@@ -6384,7 +6399,7 @@ namespace ts {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
const node = getTouchingWord(sourceFile, position);
|
||||
if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) {
|
||||
if (!node || !isThis(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8012,11 +8027,11 @@ namespace ts {
|
||||
|
||||
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
|
||||
|
||||
// Can only rename an identifier.
|
||||
if (node) {
|
||||
if (node.kind === SyntaxKind.Identifier ||
|
||||
node.kind === SyntaxKind.StringLiteral ||
|
||||
isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
|
||||
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
|
||||
isThis(node)) {
|
||||
const symbol = typeChecker.getSymbolAtLocation(node);
|
||||
|
||||
// Only allow a symbol to be renamed if it actually has at least one declaration.
|
||||
|
||||
@@ -357,8 +357,8 @@ namespace ts.SignatureHelp {
|
||||
}
|
||||
|
||||
function getArgumentIndex(argumentsList: Node, node: Node) {
|
||||
// The list we got back can include commas. In the presence of errors it may
|
||||
// also just have nodes without commas. For example "Foo(a b c)" will have 3
|
||||
// The list we got back can include commas. In the presence of errors it may
|
||||
// also just have nodes without commas. For example "Foo(a b c)" will have 3
|
||||
// args without commas. We want to find what index we're at. So we count
|
||||
// forward until we hit ourselves, only incrementing the index if it isn't a
|
||||
// comma.
|
||||
@@ -390,8 +390,8 @@ namespace ts.SignatureHelp {
|
||||
// 'a' '<comma>'. So, in the case where the last child is a comma, we increase the
|
||||
// arg count by one to compensate.
|
||||
//
|
||||
// Note: this subtlety only applies to the last comma. If you had "Foo(a,," then
|
||||
// we'll have: 'a' '<comma>' '<missing>'
|
||||
// Note: this subtlety only applies to the last comma. If you had "Foo(a,," then
|
||||
// we'll have: 'a' '<comma>' '<missing>'
|
||||
// That will give us 2 non-commas. We then add one for the last comma, givin us an
|
||||
// arg count of 3.
|
||||
const listChildren = argumentsList.getChildren();
|
||||
@@ -563,7 +563,7 @@ namespace ts.SignatureHelp {
|
||||
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
|
||||
suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
|
||||
const parameterParts = mapToDisplayParts(writer =>
|
||||
typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisType, candidateSignature.parameters, writer, invocation));
|
||||
typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisParameter, candidateSignature.parameters, writer, invocation));
|
||||
addRange(suffixDisplayParts, parameterParts);
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user