Skip to content

Conversation

atscott
Copy link
Contributor

@atscott atscott commented Oct 6, 2020

…efinition)

This commit adds the implementation for providing "go to type definition"
functionality in the Ivy Language Service.

@atscott atscott added action: review The PR is still awaiting reviews from at least one requested reviewer area: language-service Issues related to Angular's VS Code language service target: major This PR is targeted for the next major release labels Oct 6, 2020
@atscott atscott requested review from kyliau and ayazhafiz October 6, 2020 22:43
@atscott atscott self-assigned this Oct 6, 2020
@ngbot ngbot bot added this to the needsTriage milestone Oct 6, 2020
@google-cla google-cla bot added the cla: yes label Oct 6, 2020
Copy link
Contributor

@ayazhafiz ayazhafiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so exciting

Comment on lines 87 to 105
it('should return nothing for input providers', () => {
const definitions = getTypeDefinitionsAndAssertBoundSpan({
templateOverride: `<test-comp [tcN¦ame]="name"></test-comp>`,
});
expect(definitions).toEqual([]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't tcName have a type, namely string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually just the behavior of the ts language service itself for primitives. However, if I set the type to String rather than string, I do get definitions from the lib.es2015.core.d.ts, lib.es5.d.ts, etc. I think this case is generally covered in the new test that Keen requested (go to type definition of toLowerCase)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. I think it would be worth reworking this test to use a value that has a go-to-definition type, because I think the test title "should return nothing for input providers" is incorrect - in general we do want to return something for input providers, when there is something to return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Done.

Copy link
Contributor

@kyliau kyliau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor comments. LGTM overall

}
}

function getDefinitionsForSymbols(
symbols: {shimLocation: ShimLocation}[],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the custom type, why not just pass in the shim locations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes calling the function easier. I would otherwise have to map all the symbols before passing them in. I also can't use the Symbol type because some don't have shimLocation at the top level. If you feel strongly about this, I can change it.

@atscott atscott force-pushed the gototypedefinition branch 3 times, most recently from ecdbf2d to d43ea0f Compare October 7, 2020 18:52
Copy link
Contributor Author

@atscott atscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL. I had to make some adjustments to the getDirectiveMatches to allow matching compound selectors that included the tag name.

}
}

function getDefinitionsForSymbols(
symbols: {shimLocation: ShimLocation}[],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes calling the function easier. I would otherwise have to map all the symbols before passing them in. I also can't use the Symbol type because some don't have shimLocation at the top level. If you feel strongly about this, I can change it.

Comment on lines 87 to 105
it('should return nothing for input providers', () => {
const definitions = getTypeDefinitionsAndAssertBoundSpan({
templateOverride: `<test-comp [tcN¦ame]="name"></test-comp>`,
});
expect(definitions).toEqual([]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually just the behavior of the ts language service itself for primitives. However, if I set the type to String rather than string, I do get definitions from the lib.es2015.core.d.ts, lib.es5.d.ts, etc. I think this case is generally covered in the new test that Keen requested (go to type definition of toLowerCase)

@atscott atscott requested review from ayazhafiz and kyliau October 7, 2020 18:56
@atscott atscott force-pushed the gototypedefinition branch 3 times, most recently from f0ecc84 to 61d11e5 Compare October 7, 2020 20:08
Comment on lines 90 to 93
return symbols.reduce((result, {shimLocation}) => {
const defs = this.tsLS.getDefinitionAtPosition(
shimLocation.shimPath, shimLocation.positionInShimFile) ??
[];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: clang format is really weird here, maybe something like

Suggested change
return symbols.reduce((result, {shimLocation}) => {
const defs = this.tsLS.getDefinitionAtPosition(
shimLocation.shimPath, shimLocation.positionInShimFile) ??
[];
return symbols.reduce((result, {shimLocation}) => {
const {shimPath, positionInShimFile} = shimLocation;
const defs = this.tsLS.getDefinitionAtPosition(shimPath, positionInShimFile) ?? [];

to make it a bit more linear?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, can we use map and flatten here rather than creating a new array on each reduce iteration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

switch (symbol.kind) {
case SymbolKind.Template: {
const matches = getDirectiveMatches(
{name: symbol.templateNode.tagName, kind: DirectiveMatchKind.TAG_NAME},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we pass the name and kind as separate params? Constructing an object feels verbose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored this into two totally separate functions. This was feeling a little bit like a code smell the way it was.

}, [] as ts.DefinitionInfo[]);
}

private getSymbolAndNodeAtPosition(fileName: string, position: number): DefinitionMeta {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usages of this function return value unpack symbol and node and check that both are defined before moving on, so I think it would be better to make the return type DefinitionMeta|undefined. I think this would make it clearer that the metadata is either entirely defined with a symbol and node, or not at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I have a WIP branch that distinguish between templateInfo is undefined vs if the node/symbol lookup failed so I just extracted the templateInfo getter out of this function.

@atscott atscott force-pushed the gototypedefinition branch from 61d11e5 to 4baab21 Compare October 8, 2020 17:08
@atscott atscott requested a review from ayazhafiz October 8, 2020 19:07
Copy link
Contributor

@ayazhafiz ayazhafiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice 👍

@atscott atscott force-pushed the gototypedefinition branch from 4baab21 to 29f9779 Compare October 9, 2020 15:35
@atscott atscott force-pushed the gototypedefinition branch from 29f9779 to 0ffc386 Compare October 9, 2020 16:59
@atscott atscott removed the action: review The PR is still awaiting reviews from at least one requested reviewer label Oct 9, 2020
@atscott atscott added the action: merge The PR is ready for merge by the caretaker label Oct 9, 2020
…efinition)

This commit adds the implementation for providing "go to type definition"
functionality in the Ivy Language Service.
@atscott atscott force-pushed the gototypedefinition branch from 0ffc386 to 25a4d4f Compare October 9, 2020 17:11
@atscott atscott closed this in a84976f Oct 9, 2020
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: language-service Issues related to Angular's VS Code language service cla: yes target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants