Sitelet https://github.com/angular/angular/pull/39065
Skip to content

feat(language-service): [Ivy] getSemanticDiagnostics for external templates - #39065

Closed
kyliau wants to merge 1 commit into
angular:masterfrom
kyliau:ivy-ls-external-template
Closed

kyliau wants to merge 1 commit into
angular:masterfrom
kyliau:ivy-ls-external-template

Conversation

@kyliau

@kyliau kyliau commented Sep 30, 2020 •

Copy link
Copy Markdown
Contributor

This PR enables getSemanticDiagnostics() to be called on external templates.

Several changes are needed to land this feature:

  1. The adapter needs to implement two additional methods:
    a. readResource()
    Load the template from snapshot instead of reading from disk
    b. getModifiedResourceFiles()
    Inform the compiler that external templates have changed so that the
    loader could invalidate its internal cache.
  2. Create ScriptInfo for external templates in MockHost.
    Prior to this, MockHost only track changes in TypeScript files. Now it
    needs to create ScriptInfo for external templates as well.

For (1), in order to make sure we don't reload the template if it hasn't
changed, we need to keep track of its version. Since the complexity has
increased, the adapter is refactored into its own class.

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@kyliau kyliau added area: language-service Issues related to Angular's VS Code language service target: major This PR is targeted for the next major release labels Sep 30, 2020
@kyliau
kyliau requested review from atscott and ayazhafiz September 30, 2020 18:36
@ngbot ngbot Bot added this to the needsTriage milestone Sep 30, 2020
@kyliau kyliau changed the title feat(language-service): [Ivy] getSemanticDiagnostics for external tem… feat(language-service): [Ivy] getSemanticDiagnostics for external templates Sep 30, 2020
Comment thread packages/language-service/ivy/language_service.ts Outdated
Comment thread packages/language-service/ivy/language_service.ts Outdated
Comment thread packages/language-service/ivy/language_service.ts Outdated
Comment thread packages/language-service/ivy/language_service.ts Outdated
@kyliau
kyliau force-pushed the ivy-ls-external-template branch 2 times, most recently from ad22e90 to 1062e3b Compare October 1, 2020 22:40
@kyliau
kyliau requested review from atscott and ayazhafiz October 1, 2020 22:50
@kyliau

kyliau commented Oct 1, 2020

Copy link
Copy Markdown
Contributor Author

@atscott @ayazhafiz As mentioned in the meeting just now, I've refactored the adapter into a standalone class, and added more comments to explain why we need to manage resource (templates) separately. PTAL.

@kyliau
kyliau force-pushed the ivy-ls-external-template branch from 1062e3b to 66e03b2 Compare October 1, 2020 22:52
@kyliau
kyliau force-pushed the ivy-ls-external-template branch from 66e03b2 to a4aad45 Compare October 1, 2020 23:17
Comment thread packages/language-service/ivy/language_service_adapter.ts Outdated
Comment thread packages/language-service/ivy/language_service.ts Outdated
Comment on lines 78 to 83

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For example, could we clear the modifiedTemplates here and return the previous contents? (If the compiler only needs the same changes once)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think it's not a good idea to clear the modified templates here, because

  1. we are relying on the compiler to only call this method once
    This assumption is fragile. Within the compiler it's perfectly fine for it to call this method multiple times, and it'd be surprising to them if the results of the first call is different from the second call
  2. the behavior would not be consistent within the same compiler run
    This is a method defined by the compiler, and we need to adhere to the behavior they expect, not the behavior we provide.
    /**
    * Get the absolute paths to the changed files that triggered the current compilation
    * or `undefined` if this is not an incremental build.
    */
    getModifiedResourceFiles?(): Set<string>|undefined;

    I gave this some more thought, and realize that we could clear the modified template after the compiler has read the updated version. The pro is that it'll always be consistent, i.e. once the compiler reads the template, it's no longer marked as modified. The con is that there's no explicit way for language service to make sure the template update is cleared after every request. I think pro > con in this case, because it's very unlikely that the compiler would not read a template that's been marked as modified.
    With this, I deleted the clearTemplateUpdates() method.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One more note: let's say the compiler asks for all the modified resources (getModifiedResourceFiles), then reads one modified resource, then asks for the modified resources again. In this case, with what you have described, the second set of modified resources would be one less than the first, so the expectation that first call = second call in the same run is lost. Is this something we need to be concerned about?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the behavior is still consistent in this case, because once the compiler reads a template, it already has the latest state of the file, so the file is no longer considered "modified".
That said, I agree this is not the best design. I think the initial design with clearTemplateUpdates() is the most straightforward solution with no surprise. Would you prefer that over the current solution?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why don't we just recreate the program adapter each time we create a compiler?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The adapter is stateful because it needs to keep track of the template versions.
We could make it stateless, but in that case, the language service class itself will have to keep track of the template versions. I think the responsibility of tracking versions should fall under the adapter, not the language service.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh youre right I forgot about the versioning. Okay I am fine either way, sorry this was such a long discussion. Maybe later on we can figure out some nicer abstractions, even on the compiler side.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's good, your comments make me think more about the architecture, and I agree there's an opportunity here to reuse some of TS logic to keep track of changed files, instead of us doing our custom checking.
Could you please approve this PR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Of course :)

@kyliau
kyliau force-pushed the ivy-ls-external-template branch 2 times, most recently from b29925a to a66ac03 Compare October 5, 2020 21:15
@kyliau
kyliau requested a review from ayazhafiz October 5, 2020 21:15
@kyliau
kyliau force-pushed the ivy-ls-external-template branch 2 times, most recently from 7789bac to 5163226 Compare October 6, 2020 21:16
…plates

This PR enables `getSemanticDiagnostics()` to be called on external templates.

Several changes are needed to land this feature:

1. The adapter needs to implement two additional methods:
   a. `readResource()`
       Load the template from snapshot instead of reading from disk
   b. `getModifiedResourceFiles()`
       Inform the compiler that external templates have changed so that the
       loader could invalidate its internal cache.
2. Create `ScriptInfo` for external templates in MockHost.
   Prior to this, MockHost only track changes in TypeScript files. Now it
   needs to create `ScriptInfo` for external templates as well.

For (1), in order to make sure we don't reload the template if it hasn't
changed, we need to keep track of its version. Since the complexity has
increased, the adapter is refactored into its own class.
@kyliau
kyliau force-pushed the ivy-ls-external-template branch from 5163226 to 680a368 Compare October 6, 2020 21:39
Comment on lines 78 to 83

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Of course :)

@kyliau kyliau added the action: merge The PR is ready for merge by the caretaker label Oct 6, 2020
@atscott atscott closed this in 63624a2 Oct 8, 2020
@kyliau
kyliau deleted the ivy-ls-external-template branch October 8, 2020 15:51
@angular-automatic-lock-bot

Copy link
Copy Markdown

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 8, 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.

4 participants