Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upIvy LS: Emit diagnostics for parse errors #39434
Comments
Discussed in meeting: we should keep the parse errors in the state of the compiler, such that getSemanticDiagnostics always returns the parse errors of the current template (type errors are already cached correctly) |
removing good first issue b/c not so easy to keep track of parse errors on compiler state |
Currently when queried for semantic diagnostics, the language service only returns diagnostics from typechecking the program TCB. However parse errors are likely to be just as (if not more) frequent than type errors, so we should return those as well.
When
getSemanticDiagnostics
is called, we retrieve a compiler for the program that file is in. The file is checked for changed contents; if contents have been changed and it's an external template, we update known components using the template to have the new template:angular/packages/language-service/ivy/compiler_factory.ts
Lines 56 to 71 in 3236ae0
ttc.overrideComponentTemplate
parses the template and returns errors, so our work is nearly done. The only thing left to do is marshall the each of the compiler'sParseError
into ats.Diagnostic
. The compiler also provides a method for creatingts.Diagnostic
s for a template:angular/packages/compiler-cli/src/ngtsc/typecheck/diagnostics/src/diagnostic.ts
Lines 33 to 39 in 3236ae0
A usage of which for
ParseError
s is already present for the collection of components during the regular compilation pipeline:angular/packages/compiler-cli/src/ngtsc/annotations/src/component.ts
Lines 265 to 283 in 3236ae0
Most of the "hard" work is already done, the only missing piece is the
mapping: TemplateSourceMapping
parameter expected bymakeTemplateDiagnostic
. Actually we have this information too, we just needTemplateTypeChecker#overrideComponentTemplate
to return it to us:angular/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts
Lines 105 to 134 in 3236ae0
fileRecord.sourceManager
has information about theTemplateSourceMapping
for the particular template, so we can get it from there. In particular note thatoverrideComponentTemplate
, when called by the language service (AFAIK also the only user) should only call this for external templates (we may need to make this contract more strict/explicit), so there shouldn't need to be any extra work to be done here.This is a "good first issue"; I have tagged it as such, if no one wants to claim it I will take a stab when I have some free time.
Side notes:
TemplateTypeChecker
also exposesgetDiagnosticsForFile
, should that be extended to include parse errors? Maybe, because then the TTC can cache this stuff and be the "source of truth" for a template, but I argue no, because it should be concerned with TypeChecker and That's ItgetOrCreateWithChangedFile
now does more than just create a compiler; it also returns parse errors. Here is where I think it may make sense to make the contract between what language service queries should be used to identify changes in the workspace, and which can called without changed, more strict. In particular, I suggest one of the following:didChange
API that notifies the LS of workspace changes and returns semantic diagnostics. This fits more cleanly into how the LSP actually works (getSemanticDiagnostics
is not exposed by the LSP, a server publishes a message containing diagnostics to the client). The problem with this ists.LanguageService
does not have such a method, making this idea incompatible if we need to keep the Angular LS as a tsserver plugin (but even in that case it might work if we just assume getSemanticDiagnostic calls on tsserver == changed workspace)getSemanticDiagnostics
is always called and answered before any other LS API is called.Kind-of related to #38061