Previously, the language service relied on deep imports such as `@angular/compiler/render3/...`. This is bad form, because that creates a dependency on the package's internal structure. Additionally, this is not compatible with google3.
In this PR, I replace all the deep imports with shallow imports, in some cases adding the missing symbol to the `compiler.ts` exports.
PR Close#54695
In order to allow both signals and non-signals in two-way bindings, we have to pass the expression through `ɵunwrapWritableSignal`. The problem is that the language service uses a bundled compiler that is fairly new, but it may be compiling an older version of Angular that doesn't expose `ɵunwrapWritableSignal` (see https://github.com/angular/vscode-ng-language-service/issues/2001).
These changes add a `_angularCoreVersion` flag to the compiler which the language service can use to pass the parsed Angular version to the compiler which can then decide whether to emit the function.
PR Close#54423
This fixes the definitions for signal-based inputs in the language
service and type checking symbol builder.
Signal inputs emit a slightly different output. The output works well
for comppletion and was designed to affect language service minimally.
Turns out there is a small adjustment needed for the definition symbols.
PR Close#54053
The `for` block has several parts which we know are required. This
commit improves the autocomplete snippet of the `for` block by adding
those required parts and providing placeholders.
PR Close#52405
Previously, autocompletions were not available in two main cases. We correct them.
1. Autocompletions immediately after `@` were usually not working, for example `foo @|`. We fix this by causing the lexer to not consider the `@` part of the text node.
2. Autocompletions such as `@\nfoo`, where a newline follows a bare `@`, were not working because the language service visitor considered us inside the subsequent text node. We fix this by adding a block name span for the block keyword, and special-case whether we are completing inside the name span. If we are, we don't continue to the following text node.
PR Close#52198
This commit introduces basic autocompletion support for the new block keywords. After typing `@`, the language service suggests the various block names.
PR Close#52121
Two key refactors to enable deeper language service support for blocks:
(1) We now generate accurate source spans for the various block types. Additionally, all the top-level source spans for a block are now *inclusive* of all the connected or descending blocks. This helps the language service visit connected blocks.
(2) The language service's template visitor was previously skipping over the AST nodes corresponding to several block types. We are now careful to visit all such nodes.
PR Close#52038
Adds an `UnknownBlock` node to the Ivy AST to represent blocks that haven't been recognized by the compiler. This will make it easier to integrate blocks into the language service.
PR Close#52047
When the `ts.Project` creates the language service plugin (in this case,
the Angular Language Service), it sets the project's language service to
the new language service returned by the plugin create:
https://sourcegraph.com/github.com/microsoft/TypeScript@b12af0fa2bbd4b015e59adcfb49988cea7f919a1/-/blob/src/server/project.ts?L2035-2044
The project may be reloaded in response to various events, such as a
change to the tsconfig file, which then recreates the plugin. When this
happens, the language service that gets passed to the plugin `create`
function will not be the typescript language service, but rather the
previous instance of the new language service returned by the last call
to `create`.
This commit ensures that subsequent calls to `create` for the
`NgLanguageService` plugin for a project after the first call are able
to retrieve and hold on to the _TypeScript_ language service.
fixes https://github.com/angular/vscode-ng-language-service/issues/1923
PR Close#51912
Adds support for template type checking inside `for` blocks. It is implemented by generating a JS `for...of` statement inside the TCB. The various loop variables (e.g. `$index`) are implemented by declaring a local number variable.
PR Close#51690
Adds support for template type checking inside `if` blocks. It is implemented by generating a JS `if` statement inside the TCB which allows us to do type narrowing of the expression. The `as` parameter is implemented by declaring a variable inside the `if` statement.
PR Close#51690
Currently internally Angular has some customized tsconfig files, because we don't align with the tsconfig of the rest of g3. These changes enable `noImplicitReturns` and `noPropertyAccessFromIndexSignature` to align better with the internal config.
PR Close#51728
Stores the `deferred` block triggers as a map instead of an array, because triggers can't be duplicated and because having to search through an array will be inconvenient later on.
I've also added a `DeferredBlock.visitAll` method to deduplicate the logic from the various visitor implementations.
PR Close#51262
Adds the logic to create `defer`-specific AST nodes from the generic HTML `BlockGroup` and `Block`. The logic for parsing the triggers will be in the next commit.
PR Close#51050
The options to generate NgFactory and NgSummary files were added to Ivy for backwards compatibility with ViewEngine. Since ViewEngine was deprecated and removed, the NgFactory and NgSummary files are no longer used as well.
This commit drops obsolete options to generate NgFactory and NgSummary files. Also, the logic that generates those files is also removed.
PR Close#48268
Reworks some of the existing compiler APIs to make them easier to use in a schematic and exposes a few new ones to surface information we already had. High-level list of changes:
* `getPotentialImportsFor` now requires a class reference, instead of a `PotentialDirective | PotentialPipe`.
* New `getNgModuleMetadata` method has been added to the type checker.
* New `getPipeMetadata` method has been added to the type checker.
* New `getUsedDirectives` method has been added to the type checker.
* New `getUsedPipes` method has been added to the type checker.
* The `decorator` property was exposed on the `TypeCheckableDirectiveMeta`. The property was already present at runtime, but it wasn't specified on the interface.
PR Close#48730
A previous PR introduced a new compiler abstraction that tracks *all* known exports and re-exports of Angular traits. This PR harnesses that abstraction in the language service, in order to allow automatic imports of pipes.
PR Close#48354
The Angular Language Service package is now tested & compiled using ESM.
Previously it was a mismatch of CommonJS and ESM.
Still the language-service ESM output is transformed into a single UMD
bundle to allow for module resolution to be overriden. See
`bundles/BUILD`.
This is kept as is. To fully ship ESM (language-service is an exception
here), we need to:
* Update all code to no longer reference typescript via import. Instead
typescript needs to be passed around so that the extension can
control the version
* The VSCode extension/ the TS server needs to be able to load ESM. It
looks like the server supports ESM global plugins, but the extension
might not yet.
This is out of scope for the dev-infra effort as it requires more
insight into VSCode & the extension system & the TS language server.
PR Close#48521
`getPotentialPipes` returns possible pipes which can be used in the provided context, whether already in scope or requiring an import.
This is necessary to implement auto-import support for pipes in the language service.
PR Close#48090
The `fix_missing_import` quick fix has several generic helper functions that deal with imports and decorators, which I want to reuse for other import-related features. Move these functions into `ts_utils.ts` instead. No substantive code changes are present.
PR Close#48074
Currently, when generating an import of a selector, the language service might crash if the compiler cannot emit a reference to the new symbol's file from the target component's file. (This might happen because the two are the same file.) We should handle that case by reusing the existing import if possible, or otherwise failing gracefully.
PR Close#47938
This change allows the language service to suggest imports for *all* directives returned from the compiler, and for *all* import specifiers for each directive. The first change has immediate effect, since there could already be multiple directives with the same selector. The second change is future-proofing; the compiler currently only returns a single best specifier, but will return more in the future.
PR Close#47787
The language service can now generate an import corresponding to a selector. This includes both the TypeScript module import and the decorator import. This applies to both standalone components and components declared in NgModules.
PR Close#47088
After implementing `getPotentialTemplateDirectives`, we will use this data struture to represent both in-scope and out-of-scope directives. So this rename is an advance cleanup.
PR Close#47561
The Angular compiler will report the invalid banana in box, this code fixes
will try to fix the error and all the same errors in the selected file.
Fixes#44941
PR Close#47393
Create three new helper methods: `addElementToArrayLiteral`, `objectPropertyAssignmentForKey`, and `updateObjectValueForKey`. These methods make interacting with array and object literals easier.
These will be useful for the standalone imports feature, which will need to add new terms to import arrays in Component and NgModule decorators.
PR Close#47181
The diagnostic of the component missing member comes from the ts service,
so the all code fixes for it are delegated to the ts service.
The code fixes are placed in the LS package because only LS can benefit from
it now, and The LS knows how to provide code fixes by the diagnostic and NgCompiler.
The class `CodeFixes` is useful to extend the code fixes if LS needs to
provide more code fixes for the template in the future. The ts service uses
the same way to provide code fixes.
1622247636/src/services/codeFixProvider.ts (L22)
Fixes https://github.com/angular/vscode-ng-language-service/issues/1610
PR Close#46764
When an external template is read, adds the template file to to the project which contains.
This is necessary to keep the projects open when navigating away from HTML files.
Since a `tsconfig` cannot express including non-TS files,
we need another way to indicate the template files are considered part of the project.
Note that this does not ensure that the project in question _directly_ contains the component
file. That is, the project might just include the component file through the program rather
than directly in the `include` glob of the `tsconfig`. This distinction is somewhat important
because the TypeScript language service/server prefers projects which _directly_ contain the TS
file (see `projectContainsInfoDirectly` in the TS codebase). What this means it that there can
possibly be a different project used between the TS and HTML files.
For example, in Nx projects, the referenced configs are `tsconfig.app.json` and
`tsconfig.editor.json`. `tsconfig.app.json` comes first in the base `tsconfig.json` and
contains the entry point of the app. `tsconfig.editor.json` contains the `**.ts` glob of all TS
files. This means that `tsconfig.editor.json` will be preferred by the TS server for TS files
but the `tsconfig.app.json` will be used for HTML files since it comes first and we cannot
effectively express `projectContainsInfoDirectly` for HTML files.
We could consider also updating the language server implementation to attempt
to select the project to use for the template file based on which project
contains its component file directly, using either the internal `project.projectContainsInfoDirectly`
or as a workaround, check `project.isRoot(componentTsFile)`.
Finally, keeping the projects open is hugely important in the solution style config case like
Nx. When a TS file is opened, TypeScript will only retain `tsconfig.editor.json` and not
`tsconfig.app.json`. However, if our extension does not also know to select
`tsconfig.editor.json`, it will automatically select `tsconfig.app.json` since it is defined
first in the `tsconfig.json` file. So we need to teach TS server that we are (1) interested in
keeping projects open when there is an HTML file open and (2) optionally attempt to do this
_only_ for projects that we know the TS language service will prioritize in TS files (i.e.,
attempt to only keep `tsconfig.editor.json` open and allow `tsconfig.app.json` to close)
and prioritize that project for all requests.
fixes https://github.com/angular/vscode-ng-language-service/issues/1623
fixes https://github.com/angular/vscode-ng-language-service/issues/876
PR Close#45601
Previously, the compiler tracked directives and pipes in template scopes
separately. This commit refactors the scope system to unify them into a
single data structure, disambiguated by a `kind` field.
PR Close#45672
We allow the path to contain both the `t.BoundAttribute` and `t.BoundEvent` for two-way
bindings but do not want the path to contain both the `t.BoundAttribute` with its
children when the position is in the value span because we would then logically create a path
that also contains the `PropertyWrite` from the `t.BoundEvent`. This early return condition
ensures we target just `t.BoundAttribute` for this case and exclude `t.BoundEvent` children.
Fixes https://github.com/angular/vscode-ng-language-service/issues/1626
PR Close#45582
Extends `TcbPosition` with a field that indicates whether the `tcbPath` is a
type-checking shim file, or an original source file with an inline type check
block.
This field is used in an upcoming commit that fixes an inconsistency with how
inline type check blocks are incorrectly interpreted as a type-checking shim
file instead.
PR Close#45454