Merge pull request #1098 from Microsoft/getOccsForModifiers

Support getOccurrences for modifier keywords.
This commit is contained in:
Daniel Rosenwasser 2014-11-25 19:44:55 -08:00
commit faf3413c40
16 changed files with 976 additions and 0 deletions

View file

@ -609,6 +609,7 @@ module ts {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.Constructor:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:

View file

@ -3446,6 +3446,11 @@ module ts {
if (hasKind(node.parent, SyntaxKind.GetAccessor) || hasKind(node.parent, SyntaxKind.SetAccessor)) {
return getGetAndSetOccurrences(<AccessorDeclaration>node.parent);
}
default:
if (isModifier(node.kind) && node.parent &&
(isDeclaration(node.parent) || node.parent.kind === SyntaxKind.VariableStatement)) {
return getModifierOccurrences(node.kind, node.parent);
}
}
return undefined;
@ -3790,6 +3795,87 @@ module ts {
}
}
function getModifierOccurrences(modifier: SyntaxKind, declaration: Declaration) {
var container = declaration.parent;
// Make sure we only highlight the keyword when it makes sense to do so.
if (declaration.flags & NodeFlags.AccessibilityModifier) {
if (!(container.kind === SyntaxKind.ClassDeclaration ||
(declaration.kind === SyntaxKind.Parameter && hasKind(container, SyntaxKind.Constructor)))) {
return undefined;
}
}
else if (declaration.flags & NodeFlags.Static) {
if (container.kind !== SyntaxKind.ClassDeclaration) {
return undefined;
}
}
else if (declaration.flags & (NodeFlags.Export | NodeFlags.Ambient)) {
if (!(container.kind === SyntaxKind.ModuleBlock || container.kind === SyntaxKind.SourceFile)) {
return undefined;
}
}
var keywords: Node[] = [];
var modifierFlag: NodeFlags = getFlagFromModifier(modifier);
var nodes: Node[];
switch (container.kind) {
case SyntaxKind.ModuleBlock:
case SyntaxKind.SourceFile:
nodes = (<Block>container).statements;
break;
case SyntaxKind.Constructor:
nodes = (<Node[]>(<ConstructorDeclaration>container).parameters).concat(
(<ClassDeclaration>container.parent).members);
break;
case SyntaxKind.ClassDeclaration:
nodes = (<ClassDeclaration>container).members;
// If we're an accessibility modifier, we're in an instance member and should search
// the constructor's parameter list for instance members as well.
if (modifierFlag & NodeFlags.AccessibilityModifier) {
var constructor = forEach((<ClassDeclaration>container).members, member => {
return member.kind === SyntaxKind.Constructor && <ConstructorDeclaration>member;
});
if (constructor) {
nodes = nodes.concat(constructor.parameters);
}
}
break;
default:
Debug.fail("Invalid container kind.")
}
forEach(nodes, node => {
if (node.flags & modifierFlag) {
forEach(node.getChildren(), child => pushKeywordIf(keywords, child, modifier));
}
});
return map(keywords, getReferenceEntryFromNode);
function getFlagFromModifier(modifier: SyntaxKind) {
switch (modifier) {
case SyntaxKind.PublicKeyword:
return NodeFlags.Public;
case SyntaxKind.PrivateKeyword:
return NodeFlags.Private;
case SyntaxKind.ProtectedKeyword:
return NodeFlags.Protected;
case SyntaxKind.StaticKeyword:
return NodeFlags.Static;
case SyntaxKind.ExportKeyword:
return NodeFlags.Export;
case SyntaxKind.DeclareKeyword:
return NodeFlags.Ambient;
default:
Debug.fail();
}
}
}
// returns true if 'node' is defined and has a matching 'kind'.
function hasKind(node: Node, kind: SyntaxKind) {
return node !== undefined && node.kind === kind;

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export [|declare|] module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// [|declare|] var ambientThing: number;
//// export var exportedThing = 10;
//// [|declare|] function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// [|declare|] var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,72 @@
/// <reference path='fourslash.ts' />
////
////[|declare|] var x;
////export [|declare|] var y, z;
////
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
////
////[|declare|] export var v1, v2;
////[|declare|] module dm { }
////export class EC { }
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// [|export|] class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// [|export|] interface I1 {
//// }
////
//// [|export|] declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// [|export|] module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// [|export|] var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// [|export|] class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,72 @@
/// <reference path='fourslash.ts' />
////
////declare var x;
////[|export|] declare var y, z;
////
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
////
////declare [|export|] var v1, v2;
////declare module dm { }
////[|export|] class EC { }
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,41 @@
/// <reference path='fourslash.ts' />
////class C {
//// [|export|] foo;
//// [|declare|] bar;
//// [|export|] [|declare|] foobar;
//// [|declare|] [|export|] barfoo;
////
//// constructor([|export|] conFoo,
//// [|declare|] conBar,
//// [|export|] [|declare|] conFooBar,
//// [|declare|] [|export|] conBarFoo,
//// [|static|] sue,
//// [|static|] [|export|] [|declare|] sueFooBar,
//// [|static|] [|declare|] [|export|] sueBarFoo,
//// [|declare|] [|static|] [|export|] barSueFoo) {
//// }
////}
////
////module m {
//// [|static|] a;
//// [|public|] b;
//// [|private|] c;
//// [|protected|] d;
//// [|static|] [|public|] [|private|] [|protected|] e;
//// [|public|] [|static|] [|protected|] [|private|] f;
//// [|protected|] [|static|] [|public|] g;
////}
////[|static|] a;
////[|public|] b;
////[|private|] c;
////[|protected|] d;
////[|static|] [|public|] [|private|] [|protected|] e;
////[|public|] [|static|] [|protected|] [|private|] f;
////[|protected|] [|static|] [|public|] g;
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(0);
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// [|private|] priv1;
//// [|private|] priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// [|private|] private;
//// protected protected;
////
//// public constructor(public a, [|private|] b, protected c, public d, [|private|] e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// [|private|] static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// [|private|] priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, [|private|] private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// [|protected|] prot1;
//// [|protected|] prot2;
////
//// public public;
//// private private;
//// [|protected|] protected;
////
//// public constructor(public a, private b, [|protected|] c, public d, private e, [|protected|] f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// [|protected|] static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// [|protected|] prot1;
////
//// [|protected|] constructor(public public, [|protected|] protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// [|public|] pub1;
//// [|public|] pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// [|public|] public;
//// private private;
//// protected protected;
////
//// [|public|] constructor([|public|] a, private b, protected c, [|public|] d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// [|public|] get x() { return 10; }
//// [|public|] set x(value) { }
////
//// [|public|] static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public static statPub;
//// private static statPriv;
//// protected static statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// [|public|] pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor([|public|] public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});

View file

@ -0,0 +1,64 @@
/// <reference path='fourslash.ts' />
////module m {
//// export class C1 {
//// public pub1;
//// public pub2;
//// private priv1;
//// private priv2;
//// protected prot1;
//// protected prot2;
////
//// public public;
//// private private;
//// protected protected;
////
//// public constructor(public a, private b, protected c, public d, private e, protected f) {
//// this.public = 10;
//// this.private = 10;
//// this.protected = 10;
//// }
////
//// public get x() { return 10; }
//// public set x(value) { }
////
//// public [|static|] statPub;
//// private [|static|] statPriv;
//// protected [|static|] statProt;
//// }
////
//// export interface I1 {
//// }
////
//// export declare module ma.m1.m2.m3 {
//// interface I2 {
//// }
//// }
////
//// export module mb.m1.m2.m3 {
//// declare var foo;
////
//// export class C2 {
//// public pub1;
//// private priv1;
//// protected prot1;
////
//// protected constructor(public public, protected protected, private private) {
//// public = private = protected;
//// }
//// }
//// }
////
//// declare var ambientThing: number;
//// export var exportedThing = 10;
//// declare function foo(): string;
////}
test.ranges().forEach(r => {
goTo.position(r.start);
verify.occurrencesAtPositionCount(test.ranges().length);
test.ranges().forEach(range => {
verify.occurrencesAtPositionContains(range, false);
});
});