mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
152 lines
7.6 KiB
TypeScript
152 lines
7.6 KiB
TypeScript
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
|
|
// See LICENSE.txt in the project root for complete license information.
|
|
|
|
///<reference path='references.ts' />
|
|
|
|
module TypeScript.Services {
|
|
export class FindReferenceHelpers {
|
|
public static compareSymbolsForLexicalIdentity(firstSymbol: TypeScript.PullSymbol, secondSymbol: TypeScript.PullSymbol): boolean {
|
|
// Unwrap modules so that we're always referring to the variable.
|
|
if (!firstSymbol.isAlias() && firstSymbol.isContainer()) {
|
|
var containerForFirstSymbol = (<TypeScript.PullContainerSymbol>firstSymbol);
|
|
if (containerForFirstSymbol.getInstanceSymbol()) {
|
|
firstSymbol = containerForFirstSymbol.getInstanceSymbol();
|
|
}
|
|
}
|
|
|
|
if (!secondSymbol.isAlias() && secondSymbol.isContainer()) {
|
|
var containerForSecondSymbol = (<TypeScript.PullContainerSymbol>secondSymbol);
|
|
if (containerForSecondSymbol.getInstanceSymbol()) {
|
|
secondSymbol = containerForSecondSymbol.getInstanceSymbol();
|
|
}
|
|
}
|
|
|
|
if (firstSymbol.kind === secondSymbol.kind) {
|
|
if (firstSymbol === secondSymbol) {
|
|
return true;
|
|
}
|
|
|
|
// If we have two variables and they have the same name and the same parent, then
|
|
// they are the same symbol.
|
|
if (firstSymbol.kind === TypeScript.PullElementKind.Variable &&
|
|
firstSymbol.name === secondSymbol.name &&
|
|
firstSymbol.getDeclarations() && firstSymbol.getDeclarations().length >= 1 &&
|
|
secondSymbol.getDeclarations() && secondSymbol.getDeclarations().length >= 1) {
|
|
|
|
var firstSymbolDecl = firstSymbol.getDeclarations()[0];
|
|
var secondSymbolDecl = secondSymbol.getDeclarations()[0];
|
|
|
|
return firstSymbolDecl.getParentDecl() === secondSymbolDecl.getParentDecl();
|
|
}
|
|
|
|
// If we have two properties that belong to an object literal, then we need ot see
|
|
// if they came from teh same object literal ast.
|
|
if (firstSymbol.kind === TypeScript.PullElementKind.Property &&
|
|
firstSymbol.name === secondSymbol.name &&
|
|
firstSymbol.getDeclarations() && firstSymbol.getDeclarations().length >= 1 &&
|
|
secondSymbol.getDeclarations() && secondSymbol.getDeclarations().length >= 1) {
|
|
|
|
var firstSymbolDecl = firstSymbol.getDeclarations()[0];
|
|
var secondSymbolDecl = secondSymbol.getDeclarations()[0];
|
|
|
|
var firstParentDecl = firstSymbolDecl.getParentDecl();
|
|
var secondParentDecl = secondSymbolDecl.getParentDecl();
|
|
|
|
if (firstParentDecl.kind === TypeScript.PullElementKind.ObjectLiteral &&
|
|
secondParentDecl.kind === TypeScript.PullElementKind.ObjectLiteral) {
|
|
|
|
return firstParentDecl.ast() === secondParentDecl.ast();
|
|
}
|
|
}
|
|
|
|
// check if we are dealing with the implementation of interface method or a method override
|
|
if (firstSymbol.name === secondSymbol.name) {
|
|
// at this point firstSymbol.kind === secondSymbol.kind so we can pick any of those
|
|
switch (firstSymbol.kind) {
|
|
case PullElementKind.Property:
|
|
case PullElementKind.Method:
|
|
case PullElementKind.GetAccessor:
|
|
case PullElementKind.SetAccessor:
|
|
// these kinds can only be defined in types
|
|
var t1 = <PullTypeSymbol>firstSymbol.getContainer();
|
|
var t2 = <PullTypeSymbol>secondSymbol.getContainer();
|
|
t1._resolveDeclaredSymbol();
|
|
t2._resolveDeclaredSymbol();
|
|
|
|
return t1.hasBase(t2) || t2.hasBase(t1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
else {
|
|
switch (firstSymbol.kind) {
|
|
case TypeScript.PullElementKind.Class: {
|
|
return this.checkSymbolsForDeclarationEquality(firstSymbol, secondSymbol);
|
|
}
|
|
case TypeScript.PullElementKind.Property: {
|
|
if (firstSymbol.isAccessor()) {
|
|
var getterSymbol = (<TypeScript.PullAccessorSymbol>firstSymbol).getGetter();
|
|
var setterSymbol = (<TypeScript.PullAccessorSymbol>firstSymbol).getSetter();
|
|
|
|
if (getterSymbol && getterSymbol === secondSymbol) {
|
|
return true;
|
|
}
|
|
|
|
if (setterSymbol && setterSymbol === secondSymbol) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
case TypeScript.PullElementKind.Function: {
|
|
if (secondSymbol.isAccessor()) {
|
|
var getterSymbol = (<TypeScript.PullAccessorSymbol>secondSymbol).getGetter();
|
|
var setterSymbol = (<TypeScript.PullAccessorSymbol>secondSymbol).getSetter();
|
|
|
|
if (getterSymbol && getterSymbol === firstSymbol) {
|
|
return true;
|
|
}
|
|
|
|
if (setterSymbol && setterSymbol === firstSymbol) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
case TypeScript.PullElementKind.ConstructorMethod: {
|
|
return this.checkSymbolsForDeclarationEquality(firstSymbol, secondSymbol);
|
|
}
|
|
}
|
|
}
|
|
|
|
return firstSymbol === secondSymbol;
|
|
}
|
|
|
|
private static checkSymbolsForDeclarationEquality(firstSymbol: TypeScript.PullSymbol, secondSymbol: TypeScript.PullSymbol): boolean {
|
|
var firstSymbolDeclarations: TypeScript.PullDecl[] = firstSymbol.getDeclarations();
|
|
var secondSymbolDeclarations: TypeScript.PullDecl[] = secondSymbol.getDeclarations();
|
|
for (var i = 0, iLen = firstSymbolDeclarations.length; i < iLen; i++) {
|
|
for (var j = 0, jLen = secondSymbolDeclarations.length; j < jLen; j++) {
|
|
if (this.declarationsAreSameOrParents(firstSymbolDeclarations[i], secondSymbolDeclarations[j])) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static declarationsAreSameOrParents(firstDecl: TypeScript.PullDecl, secondDecl: TypeScript.PullDecl): boolean {
|
|
var firstParent: TypeScript.PullDecl = firstDecl.getParentDecl();
|
|
var secondParent: TypeScript.PullDecl = secondDecl.getParentDecl();
|
|
if (firstDecl === secondDecl ||
|
|
firstDecl === secondParent ||
|
|
firstParent === secondDecl ||
|
|
firstParent === secondParent) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
} |