The language service incorrectly reports an error if it fails to find
NgModule metadata for a particular Component / Directive. In many cases,
the use case is legit, particularly in test.
This commit removes such diagnostic message and cleans up the interface
for `TypeScriptHost.getTemplateAst()`.
PR closes https://github.com/angular/vscode-ng-language-service/issues/463
PR Close#34113
Currently, variables of an unknown type in an `*ngFor` expression are
refined to have the type of the iterable binding of the `*ngFor`
expression. Unfortunately, this is a bug for variables aliasing
[values exported by
`*ngFor`](https://angular.io/api/common/NgForOf#local-variables),
including `index` and `first`, because they are also given the type of
the binding expression, but they are not of the binding type. For
example, in
```typescript
@Component({
selector: 'test',
template: `
<div *ngFor="let hero of heroes; let i = index; let isFirst = first">
{{ hero }}
</div>
`
})
export class TestComponent {
heroes: Hero[];
}
```
The local variables `i` and `isFirst` are determined to have a type of
`Hero`, when actually their types are `number` and `boolean`,
respectively.
This commit fixes this bug by checking if the value of a variable in an
`*ngFor` expression is known to be an export and assigning the variable
the type of that export value. Only if the variable does not alias an
export is it typed with the binding value of the `*ngFor` expression.
Closes https://github.com/angular/vscode-ng-language-service/issues/460
PR Close#34089
Commit 53fc2ed8bf added support for
determining index types accessed using index signatures, but did not
include support for index types accessed using dot notation:
```typescript
const obj<T>: { [key: string]: T };
obj['stringKey']. // gets `T.` completions
obj.stringKey. // did not peviously get `T.` completions
```
This adds support for determining an index type accessed via dot
notation by rigging an object's symbol table to return the string index
signature type a property access refers to, if that property does not
explicitly exist on the object. This is very similar to @ivanwonder's
work in #29811.
`SymbolWrapper` now takes an additional parameter to explicitly set the
type of the symbol wrapped. This is done because
`SymbolTableWrapper#get` only has access to the symbol of the index
type, _not_ the index signature symbol itself. An attempt to get the
type of the index type will give an error.
Closes#29811
Closes https://github.com/angular/vscode-ng-language-service/issues/126
PR Close#33884
When performing diagnostic checks or completions, we should take into
account members and properties in the base class, if any. Otherwise, the
language service will produce a false error.
PR closes https://github.com/angular/vscode-ng-language-service/issues/93
PR Close#34041
Previously, indexing a container type would not return completions for
the indexed type because for every TypeScript type, the recorded index
type was always marked as `undefined`, regardless of the index
signature.
This PR now returns the index type of TypeScript containers with numeric
or string index signatures. This allows use to generate completions for
arrays and defined index types:
```typescript
interface Container<T> {
[key: string]: T;
}
const ctr: Container<T>;
ctr['stringKey']. // gives `T.` completions
const arr: T[];
arr[0]. // gives `T.` completions
```
Note that this does _not_ provide completions for properties indexed by
string literals, e.g.
```typescript
interface Container<T> {
foo: T;
}
const ctr: Container<T>;
ctr['foo']. // does not give `T.` completions
```
Closes angular/vscode-ng-language-service#110
Closes angular/vscode-ng-language-service#277
PR Close#33775
This commit fixes a bug whereby completions for attribute values are only
provided for directives that support the micro-syntax format, all other
bindings are ignored.
I'm not sure if this is a regresssion or a bug, because there were no
tests prior to this.
PR Close#33839
This commit fixes a few issues with helper method
`getBuiltInTypeFromTsType`.
1. The function is wrongly named. It should be the other way round.
2. The ts.Type returned by the function should not contain any value.
This is because for some data types like Number and String, the
SourceFile (context.node) is not the correct value. Value is never
needed for program correctness in this case.
PR Close#33778
This commit fixes a bug brought up by @andrius-pra whereby the language
service host would recompute the analyzed modules even when none of the
source files changes. This is due to a bug in our unit test that
precludes non-TS files from incrementing the project version.
Consequently, when the external template is updated, the program remains
the same.
With the bug fixed, the next step is to figure out if any source files
have been added / changed / removed since the last computation. The
previously analyzed could be safely retained only when none of these
operations happen.
PR Close#33806
The method `getTemplateReferences()` appears in both the LanguageService
interface and LanguageServiceHost interface. It should belong in the
latter and not the former, since the former deals with the semantics of
the language and not the mechanics.
PR Close#33807
The following files are consumed only by the language service and do not
have to be in compiler-cli:
1. expression_diagnostics.ts
2. expression_type.ts
3. typescript_symbols.ts
4. symbols.ts
PR Close#33809
Adds a `replacementSpan` field on a completion that will allow typed
text to be replaced with the suggested completion value if a user
selects the completion. Previously, the completion value would simply be
appended to the text already typed. E.g. if we had
```
{{ti}}
```
typed in a template and `title` was recommended as a completion and
selected, the template would become
```
{{tititle}}
```
With `replacementSpan`, the original text `ti` will be replaced for
`title`.
PR Close#33091
This commit removes HTML elements and HTML attributes from the
completions list for external template. This is because these
completions should be handled by the native HTML extension, and not
Angular.
Once we setup TextMate grammar for inline templates, we could remove the
HTML completions completely.
PR closes https://github.com/angular/vscode-ng-language-service/issues/370
PR Close#33388
This is a potential fix for https://github.com/angular/vscode-ng-language-service/issues/235
suggested by @andrius-pra in
47696136e3.
Currently, CRLF line endings are converted to LFs and this causes the
diagnostics span to be off in templates that use CRLF. The line endings
must be preserved in order to maintain correct span offset. The solution
is to add an option to the Tokenizer to indicate such preservation.
PR Close#33241
This commit speeds up the tests by calling `MockHost.reset()` in
`beforeEach()` instead of destroying the entire language service and
creating a new one. The creation of a new language service instance is
expensive due to the need to initialize many core Symbols when creating
a new program.
This speeds ups the test (on my local machine) from 35 secs to 15 secs.
PR Close#33200
There are many specs in `ts_plugin_spec.ts` that exercise the behavior
of completions. These specs should belong in `completions_spec` instead.
In addition,
1. Tests for `getExternalFiles()` added in `ts_plugin_spec.ts`
2. Fixed bug in MockHost.reset() to remove overriden script names
3. Add test for TS diagnostics when `angularOnly = true` is not set
PR Close#33159
Now, hovering over an attribute on an element will provide information
about the directive that attribute matches in the element, if any.
(More generally, we return information about directive symbols
matched on an element attribute.)
I believe this is similar to how the indexer provides this kind of
information, though more precise in the sense that this commit provides
directive information only if the directive selector exactly matches the
attribute selector. In another sense, this is a limitation.
In fact, there are the limitations of:
- Directives matched on the element, but with a selector of anything
more than the attribute (e.g. `div[string-model]` or
`[string-model][other-attr]`) will not be returned as symbols matching
on the attribute.
- Only one symbol can be returned currently. If the attribute matches
multiple directives, only one directive symbol will be returned.
Furthermore, we cannot say that the directive symbol returned is
determinstic.
Resolution of these limitations can be discussed in the future. At least
the second limitation should be very easy to fixup in a future commit.
This relies solely on the template compiler and is agnostic to any Ivy
changes, so this is strictly a feature enhancement that will not have to
be refactored when we migrate the language service to Ivy.
PR Close#33127
This PR adds es2015 lib to the `tsconfig.json` of the test project so
that `Promise` could be used. Note this only affects diagnostics in the
IDE. The tsconfig in Language Service Mock Host is the actual config
values used, and it already has es2015 lib.
- Other minor cleanup: Rename imports in `main.ts`.
- Add more cases to `parsing-cases.ts`, which are tested in later PRs
PR Close#33157
Enables providing information about the NgModule a component is in when
its selector is hovered on in a template. Also enables differentiation
of a component and a directive when a directive class name is hovered
over in a TypeScript file.
Next step is to enable hover information for directives.
Part of #32565.
PR Close#33118
Currently, method `getVarDeclarations()` does not try to resolve the type of
exported variable from *ngIf directive. It always returns `any` type.
By resolving the real type of exported variable, it is now possible to use this
type information in language service and provide completions, go to definition
and quick info functionality in expressions that use exported variable.
Also language service will provide more accurate diagnostic errors during
development.
PR Close#33016
A few specs in `completions_spec.ts` are non-deterministic and do not provide much value to test a specific behavior of language service.
Besides that, they are also slow to run.
PR Close#33120
Remove the following methods from MockHost:
1. `getMarkerLocations`: Replaced with `getLocationMarkerFor()`
2. `getReferenceMarkers`: Replaced with `getReferenceMarkerFor()`
PR Close#33115
The creation of StaticReflector in createMetadataResolver() is a very expensive operation because it involves numerous module resolutions.
To make matter worse, since the API of the Reflector does not provide the ability to invalidate its internal caches, it has to be destroyed and recreated on *every* program change.
This has a HUGE impact on performance.
This PR fixes this problem by carefully invalidating all StaticSymbols in a file that has changed, thereby reducing the overhead of recomputation on program change.
PR Close#32543
Adds information about the NgModule a Directive is declared in when the
Directive class name is hovered over, in the form
```
(directive) NgModule.Directive: class
```
Closes#32565
PR Close#32763
Sometimes modules retreived from the language service need to be
synchronized to the last time they were updated, and not updated
on-the-fly. This PR adds a flag to
`TypeScriptServiceHost#getAnalyzedModules` that retreives cached
analyzed NgModules rather than potentially recomputing them.
PR Close#32779
This is the last part in refactoring of the test project.
This PR turns on strict mode for typechecking and fixed tests that
fail under this mode.
PR Close#32783
readFileContent() has the exact same functionality as readFile(), but it
is not actually part of ts.LanguageServiceHost interface.
It's not actually needed, so replace it with readFile() instead.
PR Close#32782
Remove MockData from the constructor parameters of MockTypescriptHost
since the entire Tour of Heroes (TOH) project is now loaded from disk.
Added a new method `reset()` to MockTypescriptHost that is necessary to
reset the state of the project before each spec if run to make sure
previous overrides are cleared.
PR Close#32752
Language service uses a canonical "Tour of Heroes" project to test
various features, but the files are all contained in test_data.ts which
is hard to read and often contains errors that are difficult to catch
without proper IDE syntax highlighting. The directory structure is also
not clear from first glance.
This PR refactors the test project into standalone files in the proper
format.
Next up:
[ ] Update the interface of MockTypeScript to only accept scriptNames.
[ ] Remove test_data.ts
PR Close#32653
This sets up the Language Service to support #32565.
This PR exposes a `getDirectiveModule` method on `TypeScriptServiceHost`
that returns the NgModule owning a Directive given the Directive's
TypeScript node or its Angular `StaticSymbol`. Both types are supported
to reduce extraneous helper methods.
PR Close#32710
Removes `addCodeAndCallback` function, opting instead to add code to a
file and then testing expectations on that fileName. Also renames
`contains` to `expectContains` to clarify its expectations.
PR Close#32656