-
Notifications
You must be signed in to change notification settings - Fork 26.3k
feat(language-service): add semantic tokens for templates #60260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Since this feature requires changes in vscode-ng-language-service, I prepared a fork feature/semantic-tokens to test this PR in an actual editor. This is a screenshot from VSCode with semantic tokens enabled: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! I was waiting for this to move from draft to ready for review but maybe the fact that it was created in draft mode wasn't noticed.
5d1775c
to
74904fa
Compare
Thanks for your review and kind words! |
Adds support for `getEncodedSemanticClassifications` to the language service. The service now classifies components in a template as the `class` type.
74904fa
to
564c1b5
Compare
visitElement(element: TmplAstElement) { | ||
const tag = element.name; | ||
const potentialDirective = this.tags.get(tag); | ||
const isComponent = potentialDirective && potentialDirective.isComponent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind adding a comment about why this was done? e.g. to prevent the classifications for directives from applying to the element.
BTW, the way we attempt to determine if an attribute is what causes the directive to be a match for the element is by removing the attribute and checking to see if the directive still matches:
angular/packages/language-service/src/utils/index.ts
Lines 331 to 341 in 286f9f5
const allAttrs = attributes.map(toAttributeCssSelector); | |
const allDirectiveMatches = getDirectiveMatchesForSelector( | |
directives, | |
getNodeName(hostNode) + allAttrs.join(''), | |
); | |
const attrsExcludingName = attributes.filter((a) => a.name !== name).map(toAttributeCssSelector); | |
const matchesWithoutAttr = getDirectiveMatchesForSelector( | |
directives, | |
getNodeName(hostNode) + attrsExcludingName.join(''), | |
); | |
return difference(allDirectiveMatches, matchesWithoutAttr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my PR can wait for this to be merged. We all need to visit the template node and get the component node.
Adds support for
getEncodedSemanticClassifications
to the language service. The service now classifies components in a template as theclass
type.PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
The language service does not provide semantic tokens.
Issue Number: #60262
What is the new behavior?
The Angular language service now implements the
getEncodedSemanticClassifications
call, which in turn is needed on the language server/client side to provide the desired contextual syntax highlighting in the editor.For now, the service only tries to highlight component tags by classifying them as classes (similiar to TSX highlighting done by TypeScript). To this extent the token types are the same as in the TypeScript language service to ensure this service keeps working as a strict superset.
For details about semantic tokens see the LSP protocol.
Does this PR introduce a breaking change?