Skip to content

Commit 86691f0

Browse files
Merge pull request #653 from Microsoft/getOccurrences
getOccurrencesAtPosition Implemented
2 parents 2ba3ae9 + 0af26bc commit 86691f0

28 files changed

+2051
-146
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,29 +3468,6 @@ module ts {
34683468
return getTypeOfSymbol(getExportSymbolOfValueSymbolIfExported(symbol));
34693469
}
34703470

3471-
function getThisContainer(node: Node): Node {
3472-
while (true) {
3473-
node = node.parent;
3474-
if (!node) {
3475-
return node;
3476-
}
3477-
switch (node.kind) {
3478-
case SyntaxKind.FunctionDeclaration:
3479-
case SyntaxKind.FunctionExpression:
3480-
case SyntaxKind.ModuleDeclaration:
3481-
case SyntaxKind.Property:
3482-
case SyntaxKind.Method:
3483-
case SyntaxKind.Constructor:
3484-
case SyntaxKind.GetAccessor:
3485-
case SyntaxKind.SetAccessor:
3486-
case SyntaxKind.EnumDeclaration:
3487-
case SyntaxKind.SourceFile:
3488-
case SyntaxKind.ArrowFunction:
3489-
return node;
3490-
}
3491-
}
3492-
}
3493-
34943471
function captureLexicalThis(node: Node, container: Node): void {
34953472
var classNode = container.parent && container.parent.kind === SyntaxKind.ClassDeclaration ? container.parent : undefined;
34963473
getNodeLinks(node).flags |= NodeCheckFlags.LexicalThis;
@@ -3503,11 +3480,14 @@ module ts {
35033480
}
35043481

35053482
function checkThisExpression(node: Node): Type {
3506-
var container = getThisContainer(node);
3483+
// Stop at the first arrow function so that we can
3484+
// tell whether 'this' needs to be captured.
3485+
var container = getThisContainer(node, /* includeArrowFunctions */ true);
35073486
var needToCaptureLexicalThis = false;
3508-
// skip arrow functions
3509-
while (container.kind === SyntaxKind.ArrowFunction) {
3510-
container = getThisContainer(container);
3487+
3488+
// Now skip arrow functions to get the "real" owner of 'this'.
3489+
if (container.kind === SyntaxKind.ArrowFunction) {
3490+
container = getThisContainer(container, /* includeArrowFunctions */ false);
35113491
needToCaptureLexicalThis = true;
35123492
}
35133493

@@ -4407,37 +4387,6 @@ module ts {
44074387
return voidType;
44084388
}
44094389

4410-
// WARNING: This has the same semantics as the forEach family of functions,
4411-
// in that traversal terminates in the event that 'visitor' supplies a truthy value.
4412-
function forEachReturnStatement<T>(body: Block, visitor: (stmt: ReturnStatement) => T): T {
4413-
4414-
return traverse(body);
4415-
4416-
function traverse(node: Node): T {
4417-
switch (node.kind) {
4418-
case SyntaxKind.ReturnStatement:
4419-
return visitor(node);
4420-
case SyntaxKind.Block:
4421-
case SyntaxKind.FunctionBlock:
4422-
case SyntaxKind.IfStatement:
4423-
case SyntaxKind.DoStatement:
4424-
case SyntaxKind.WhileStatement:
4425-
case SyntaxKind.ForStatement:
4426-
case SyntaxKind.ForInStatement:
4427-
case SyntaxKind.WithStatement:
4428-
case SyntaxKind.SwitchStatement:
4429-
case SyntaxKind.CaseClause:
4430-
case SyntaxKind.DefaultClause:
4431-
case SyntaxKind.LabelledStatement:
4432-
case SyntaxKind.TryStatement:
4433-
case SyntaxKind.TryBlock:
4434-
case SyntaxKind.CatchBlock:
4435-
case SyntaxKind.FinallyBlock:
4436-
return forEachChild(node, traverse);
4437-
}
4438-
}
4439-
}
4440-
44414390
/// Returns a set of types relating to every return expression relating to a function block.
44424391
function checkAndAggregateReturnExpressionTypes(body: Block, contextualMapper?: TypeMapper): Type[] {
44434392
var aggregatedTypes: Type[] = [];
@@ -5856,17 +5805,6 @@ module ts {
58565805
// TODO: Check that target label is valid
58575806
}
58585807

5859-
function getContainingFunction(node: Node): SignatureDeclaration {
5860-
while (true) {
5861-
node = node.parent;
5862-
if (!node || node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression ||
5863-
node.kind === SyntaxKind.ArrowFunction || node.kind === SyntaxKind.Method || node.kind === SyntaxKind.Constructor ||
5864-
node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor) {
5865-
return <SignatureDeclaration>node;
5866-
}
5867-
}
5868-
}
5869-
58705808
function checkReturnStatement(node: ReturnStatement) {
58715809
if (node.expression && !(getNodeLinks(node.expression).flags & NodeCheckFlags.TypeChecked)) {
58725810
var func = getContainingFunction(node);

src/compiler/parser.ts

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,107 @@ module ts {
350350
}
351351
}
352352

353+
// Warning: This has the same semantics as the forEach family of functions,
354+
// in that traversal terminates in the event that 'visitor' supplies a truthy value.
355+
export function forEachReturnStatement<T>(body: Block, visitor: (stmt: ReturnStatement) => T): T {
356+
357+
return traverse(body);
358+
359+
function traverse(node: Node): T {
360+
switch (node.kind) {
361+
case SyntaxKind.ReturnStatement:
362+
return visitor(node);
363+
case SyntaxKind.Block:
364+
case SyntaxKind.FunctionBlock:
365+
case SyntaxKind.IfStatement:
366+
case SyntaxKind.DoStatement:
367+
case SyntaxKind.WhileStatement:
368+
case SyntaxKind.ForStatement:
369+
case SyntaxKind.ForInStatement:
370+
case SyntaxKind.WithStatement:
371+
case SyntaxKind.SwitchStatement:
372+
case SyntaxKind.CaseClause:
373+
case SyntaxKind.DefaultClause:
374+
case SyntaxKind.LabelledStatement:
375+
case SyntaxKind.TryStatement:
376+
case SyntaxKind.TryBlock:
377+
case SyntaxKind.CatchBlock:
378+
case SyntaxKind.FinallyBlock:
379+
return forEachChild(node, traverse);
380+
}
381+
}
382+
}
383+
384+
export function isAnyFunction(node: Node): boolean {
385+
if (node) {
386+
switch (node.kind) {
387+
case SyntaxKind.FunctionExpression:
388+
case SyntaxKind.FunctionDeclaration:
389+
case SyntaxKind.ArrowFunction:
390+
case SyntaxKind.Method:
391+
case SyntaxKind.GetAccessor:
392+
case SyntaxKind.SetAccessor:
393+
case SyntaxKind.Constructor:
394+
return true;
395+
}
396+
}
397+
398+
return false;
399+
}
400+
401+
export function getContainingFunction(node: Node): SignatureDeclaration {
402+
while (true) {
403+
node = node.parent;
404+
if (!node || isAnyFunction(node)) {
405+
return <SignatureDeclaration>node;
406+
}
407+
}
408+
}
409+
410+
export function getThisContainer(node: Node, includeArrowFunctions: boolean): Node {
411+
while (true) {
412+
node = node.parent;
413+
if (!node) {
414+
return undefined;
415+
}
416+
switch (node.kind) {
417+
case SyntaxKind.ArrowFunction:
418+
if (!includeArrowFunctions) {
419+
continue;
420+
}
421+
// Fall through
422+
case SyntaxKind.FunctionDeclaration:
423+
case SyntaxKind.FunctionExpression:
424+
case SyntaxKind.ModuleDeclaration:
425+
case SyntaxKind.Property:
426+
case SyntaxKind.Method:
427+
case SyntaxKind.Constructor:
428+
case SyntaxKind.GetAccessor:
429+
case SyntaxKind.SetAccessor:
430+
case SyntaxKind.EnumDeclaration:
431+
case SyntaxKind.SourceFile:
432+
return node;
433+
}
434+
}
435+
}
436+
437+
export function getSuperContainer(node: Node): Node {
438+
while (true) {
439+
node = node.parent;
440+
if (!node) {
441+
return undefined;
442+
}
443+
switch (node.kind) {
444+
case SyntaxKind.Property:
445+
case SyntaxKind.Method:
446+
case SyntaxKind.Constructor:
447+
case SyntaxKind.GetAccessor:
448+
case SyntaxKind.SetAccessor:
449+
return node;
450+
}
451+
}
452+
}
453+
353454
export function hasRestParameters(s: SignatureDeclaration): boolean {
354455
return s.parameters.length > 0 && (s.parameters[s.parameters.length - 1].flags & NodeFlags.Rest) !== 0;
355456
}

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ module ts {
220220
LastFutureReservedWord = YieldKeyword,
221221
FirstTypeNode = TypeReference,
222222
LastTypeNode = ArrayType,
223-
FirstPunctuation= OpenBraceToken,
223+
FirstPunctuation = OpenBraceToken,
224224
LastPunctuation = CaretEqualsToken
225225
}
226226

0 commit comments

Comments
 (0)