Commit Graph

10 Commits

Author SHA1 Message Date
Alex Rickabaugh 1eba57eb00 fix(language-service): show suggestion when type inference is suboptimal (#41072)
The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a suggestion diagnostic
which is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes #41042

PR Close #41072
2021-03-23 09:39:19 -07:00
Alex Rickabaugh 53c65f468f test(language-service): update compiler_spec to use the new testing env (#40679)
This commit updates compiler_spec.ts in the Ivy LS suite to utilize the new
testing environment which was introduced in the previous commit. Eventually
all specs should be converted, but converting one right now helps ensure
that the new testing env is working properly and able to support real tests.

PR Close #40679
2021-02-22 08:40:41 -08:00
Alex Rickabaugh b6893d23c5 test(language-service): introduce new virtual testing environment (#39594)
This commit adds new language service testing infrastructure which allows
for in-memory testing. It solves a number of issues with the previous
testing infrastructure that relied on a single integration project across
all of the tests, and also provides for much faster builds by using
the compiler-cli's mock versions of @angular/core and @angular/common.

A new `LanguageServiceTestEnvironment` class (conceptually mirroring the
compiler-cli `NgtscTestEnvironment`) controls setup and execution of tests.
The `FileSystem` abstraction is used to drive a `ts.server.ServerHost`,
which backs the language service infrastructure.

Since many language service tests revolve around the template, the API is
currently optimized to spin up a "skeleton" project and then override its
template for each test.

The existing Quick Info tests (quick_info_spec.ts) were ported to the new
infrastructure for validation. The tests were cleaned up a bit to remove
unnecessary initializations as well as correct legitimate template errors
which did not affect the test outcome, but caused additional validation of
test correctness to fail. They still utilize a shared project with all
fields required for each individual unit test, which is an anti-pattern, but
new tests can now easily be written independently without relying on the
shared project, which was extremely difficult previously. Future cleanup
work might refactor these tests to be more independent.

PR Close #39594
2020-11-17 11:59:56 -08:00
Alex Rickabaugh a7155bc2fa test(language-service): move existing tests to legacy directory (#39594)
In preparation for in-memory testing infrastructure, the existing Ivy
language service tests are moved to a `legacy` directory. These existing
tests rely on a single integration project in `test/project/app`, which
presents a number of challenges:

 * adding extra fields/properties to the integration project for one test
   can cause others to fail/flake.
 * it's especially difficult to test any cases that require introducing
   intentional errors, as those tend to break other tests.
 * tests load files from disk, which is slower.
 * tests rely on the real built versions of @angular/core and
   @angular/common, which makes them both slow to build and require rebuilds
   on every compiler change.
 * tests share a single tsconfig.json, making it extremely difficult to test
   how the language service handles different configuration scenarios (e.g.
   different type-checking flags).

PR Close #39594
2020-11-17 11:59:56 -08:00
Keen Yee Liau b48cc6ead5 feat(language-service): introduce hybrid visitor to locate AST node (#38540)
This commit introduces two visitors, one for Template AST and the other
for Expression AST to allow us to easily find the node that most closely
corresponds to a given cursor position.

This is crucial because many language service APIs take in a `position`
parameter, and the information returned depends on how well we can find
a good candidate node.

In View Engine implementation of language service, the search for the node
and the processing of information to return the result are strongly coupled.
This makes the code hard to understand and hard to debug because the stack
trace is often littered with layers of visitor calls.

With this new feature, we could test the "searching" part separately and
colocate all the logic (aka hacks) that's required to retrieve an accurate
span for a given node.

Right now, only the most "narrow" node is returned by the main exported
function `findNodeAtPosition`. If needed, we could expose the entire AST
path, or expose other methods to provide more context for a node.

Note that due to limitations in the template AST interface, there are
a few known cases where microsyntax spans are not recorded properly.
This will be dealt with in a follow-up PR.

PR Close #38540
2020-08-24 09:24:18 -07:00
Keen Yee Liau cfe424e875 refactor(language-service): [Ivy] remove temporary compiler (#38310)
Now that Ivy compiler has a proper `TemplateTypeChecker` interface
(see https://github.com/angular/angular/pull/38105) we no longer need to
keep the temporary compiler implementation.

The temporary compiler was created to enable testing infrastructure to
be developed for the Ivy language service.

This commit removes the whole `ivy/compiler` directory and moves two
functions `createTypeCheckingProgramStrategy` and
`getOrCreateTypeCheckScriptInfo` to the `LanguageService` class.

Also re-enable the Ivy LS test since it's no longer blocking development.

PR Close #38310
2020-08-17 11:30:33 -07:00
Keen Yee Liau 92c436dd1a test(language-service): disable ivy ls tests on CI (#37348)
This commit disables the tests for Ivy version of language service on CI
because the compiler APIs are not yet stable, so language service should
not assert against its behavipr.

PR Close #37348
2020-06-01 17:18:51 -04:00
Keen Yee Liau 1142c378fd feat(language-service): [ivy] wrap ngtsc to handle typecheck files (#36930)
This commit adds a Compiler interface that wraps the actual ngtsc
compiler. The language-service specific compiler manages multiple
typecheck files using the Project interface, creating and adding
ScriptInfos as necessary.

This commit also adds `overrideInlineTemplate()` method to the mock
service so that we could test the Compiler diagnostics feature.

PR Close #36930
2020-05-08 14:42:11 -07:00
Keen Yee Liau dbd0f8e699 feat(language-service): [ivy] Parse Angular compiler options (#36922)
Parse Angular compiler options in Angular language service.

In View Engine, only TypeScript compiler options are read, Angular
compiler options are not. With Ivy, there could be different modes of
compilation, most notably how strict the templates should be checked.
This commit makes the behavior of language service consistent with the
Ivy compiler.

PR Close #36922
2020-05-05 12:01:00 -07:00
Keen Yee Liau 58ea040570 test(language-service): add new mock host for testing ivy (#36879)
This commit adds a new mock host for testing the ivy language service.

Unlike the existing mock_host which mocks the LanguageServiceHost, the
Ivy mock host mocks just the filesystem interface, aka ts.ServerHost.

This is because Ivy language service requires an actual Project to
perform operations like adding synthetic typecheck files to the project,
and by extension, to the ts.Program. These requirements make the existing
mock host unsuitable to be reused.

This new testing structure also improves test performance, because the
old mock host copies (it actually creates symlinks, but still that's
relatively expensive due to the sheer number of files involved) all
@angular/* packages along with the typescript package to a temporary
node_modules directory. This is done every time setup() is called.
Instead, this new mock host just loads them from a pre-determined path
in Bazel runfiles.

PR Close #36879
2020-05-04 12:47:15 -07:00