Commit Graph

154 Commits

Author SHA1 Message Date
Keen Yee Liau dd944ef73f fix(language-service): Insert parentheses for method completion (#33860)
This commit leverages the `insertText` field in `ts.CompletionEntry` to
return a completion text for class methods that includes parentheses.

PR closes https://github.com/angular/vscode-ng-language-service/issues/15

PR Close #33860
2019-12-03 10:13:36 -08:00
Keen Yee Liau 7eccbcd30d fix(language-service): Make missing module suggestion instead of error (#34115)
If a Component or Directive is not part of any NgModule, the language
service currently produces an error message. This should not be an
error. Instead, it should be a suggestion.

This PR removes `ng.DiagnosticKind`, and instead reuses
`ts.DiagnosticCategory`.

PR closes https://github.com/angular/vscode-ng-language-service/issues/458

PR Close #34115
2019-12-02 11:19:40 -08:00
Keen Yee Liau 99320e1ffc fix(language-service): use host.error() instead of console.error() (#34114)
`host.error()` would log to file, and makes error messages much easier
to inspect because entries are time-stamped.

PR Close #34114
2019-12-02 11:14:08 -08:00
Keen Yee Liau 39722df41e fix(language-service): Do not produce diagnostics if metadata for NgModule not found (#34113)
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
2019-12-02 11:13:41 -08:00
ayazhafiz 1425e63029 fix(language-service): determine correct type for ngFor exported values (#34089)
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
2019-12-02 11:03:34 -08:00
ivanwonder c5006e025f fix(language-service): fix error of array-index out of bounds exception (#33928)
PR Close #33928
2019-11-27 12:48:41 -08:00
ivanwonder 5a227d8d7c feat(language-service): completions support for tuple array (#33928)
PR Close #33928
2019-11-27 12:48:41 -08:00
ayazhafiz 49804fe017 fix(language-service): determine index types accessed using dot notation (#33884)
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
2019-11-26 15:57:07 -08:00
Keen Yee Liau 7cd16b9e2c fix(language-service): function.bind() should not be an error (#34041)
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
2019-11-25 21:20:56 -05:00
ayazhafiz 53fc2ed8bf feat(language-service): completions support for indexed types (#33775)
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
2019-11-15 16:16:06 -08:00
Keen Yee Liau 592fd37b3e fix(language-service): Provide completions for attribute values (#33839)
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
2019-11-15 16:13:08 -08:00
Keen Yee Liau cbb1d9f2bb fix(compiler-cli): Refactor getTsTypeFromBuiltinType (#33778)
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
2019-11-15 10:43:41 -08:00
Keen Yee Liau 1d3aae6f92 fix(language-service): Function alias should be callable (#33782)
This commit fixes a long standing bug whereby a template variable that
gets initialized to a class method gets resolved to the Any type, thus
when it is called the language service produces error "Member X is not
callable".

PR closes https://github.com/angular/angular/issues/16643
PR closes https://github.com/angular/vscode-ng-language-service/issues/234

PR Close #33782
2019-11-15 10:43:18 -08:00
Keen Yee Liau c5a75fd807 fix(language-service): Recompute analyzed modules only when source files change (#33806)
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
2019-11-15 10:42:09 -08:00
Keen Yee Liau c365eded5b fix(language-service): Remove getTemplateReferences() from LanguageService API (#33807)
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
2019-11-15 10:41:51 -08:00
Keen Yee Liau 9935aa43ad refactor(compiler-cli): Move diagnostics files to language service (#33809)
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
2019-11-14 09:29:07 -08:00
Keen Yee Liau 2be0a1d35b refactor(language-service): Colocate getAnalzyedModules and upToDate (#33779)
These two functions go hand-in-hand, putting them together improves
readability.

PR Close #33779
2019-11-12 21:34:52 -08:00
Keen Yee Liau 9ebac71521 fix(language-service): Should not crash if expr ends unexpectedly (#33524)
If there is any parser errors when parsing template, we should stop
immediately and not proceed with template expression diagnostics.

This regression is caused by 6d11154652
and affected v9.0.0-next.4 onwards.

PR closes https://github.com/angular/vscode-ng-language-service/issues/436

PR Close #33524
2019-11-01 17:37:48 +00:00
ayazhafiz da4eb91283 feat(language-service): add support for text replacement (#33091)
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
2019-10-29 11:47:01 -07:00
Keen Yee Liau c61f413477 refactor(language-service): Simplify ExpressionVisitor in completions.ts (#33391)
This commit simplifies the logic of `ExpressionVisitor` in
`completions.ts`.

Specifically,

1. helper functions `uniqueByName` and `lowerName` are removed.
2. Clean up the logic in visitElement()
3. Reorder constructor params
4. Add methods `addAttributeValuesToCompletions`,
`addKeysToCompletions`, and `addSymbolsToCompletions`.

PR Close #33391
2019-10-28 10:39:42 -07:00
Keen Yee Liau a78b70178e fix(language-service): Do not show HTML elements and attrs for ext template (#33388)
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
2019-10-25 09:18:16 -07:00
ayazhafiz ee4fc12e42 refactor(language-service): find expression ASTs using absolute spans (#33387)
Moves to using the absolute span of an expression AST (relative to an
entire template) rather than a relative span (relative to the start
of the expression) to find an expression AST given a position in a
template.

This is part of the changes needed to support text replacement in
templates (#33091).

PR Close #33387
2019-10-24 17:08:23 -07:00
Keen Yee Liau 4c4217c5b7 refactor(language-service): Remove unused function 'createElementCssSelector' (#33383)
It's no longer used and needed.

PR Close #33383
2019-10-24 14:10:47 -07:00
Keen Yee Liau 93a0b1ba13 refactor(language-service): Remove AttrInfo interface (#33380)
It's no longer used and needed.

PR Close #33380
2019-10-24 14:10:14 -07:00
Keen Yee Liau 73530a9e25 refactor(language-service): Create ng.CompletionEntry to replace ts.CompletionEntry (#33379)
It is messy to keep casting `CompletionEntry.kind` from
`ng.CompletionKind` to `ts.ScriptElementKind`.

Instead, create a new type `ng.CompletionEntry` that is exactly the same
as `ts.CompletionEntry`, but with the `kind` type overridden to
`ng.CompletionKind`.

This way, we only have to cast it once, and can do so in a safe manner.

PR Close #33379
2019-10-24 14:09:33 -07:00
Keen Yee Liau 3f257e96c6 fix(language-service): Add global symbol for $any() (#33245)
This commit introduces a "global symbol table" in the language service for symbols that are available in the top level scope,
and add `$any()` to it.

See https://angular.io/guide/template-syntax#the-any-type-cast-function

PR closes https://github.com/angular/vscode-ng-language-service/issues/242

PR Close #33245
2019-10-23 10:02:50 -07:00
Keen Yee Liau 49eec5d872 fix(language-service): Add directive selectors & banana-in-a-box to completions (#33311)
This commit refactors attribute completions and fixes two bugs:
1. selectors for directives are not provided
2. banana-in-a-box (two way binding) syntax are not provided

PR closes https://github.com/angular/vscode-ng-language-service/issues/358

PR Close #33311
2019-10-23 09:10:39 -07:00
Keen Yee Liau 65a0d2b53d fix(language-service): Preserve CRLF in templates for language-service (#33241)
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
2019-10-22 13:29:23 -04:00
Suguru Inatomi e0059c7d51 refactor: format files (#31248)
PR Close #31248
2019-10-18 14:49:12 -04:00
Suguru Inatomi e122d27176 refactor: fix by beedback (#31248)
PR Close #31248
2019-10-18 14:49:12 -04:00
Suguru Inatomi bab740d793 refactor: format files (#31248)
PR Close #31248
2019-10-18 14:49:12 -04:00
Suguru Inatomi 60e4490808 refactor: fix by feedback (#31248)
PR Close #31248
2019-10-18 14:49:12 -04:00
Suguru Inatomi 251a512222 refactor: create CompletionKind.PSEUDO_ELEMENT (#31248)
PR Close #31248
2019-10-18 14:49:12 -04:00
Suguru Inatomi 692535a935 refactor: make pseudo elements array readonly (#31248)
PR Close #31248
2019-10-18 14:49:12 -04:00
Suguru Inatomi 7c64b8d3fd feat(language-service): add Angular pseudo elements into completions (#31248)
PR Close #31248
2019-10-18 14:49:12 -04:00
Igor Minar 86e1e6c082 feat: typescript 3.6 support (#32946)
BREAKING CHANGE: typescript 3.4 and 3.5 are no longer supported, please update to typescript 3.6

Fixes #32380

PR Close #32946
2019-10-18 13:15:16 -04:00
ayazhafiz d2222541e8 refactor(language-service): use strict comparisons (#33114)
PR Close #33114
2019-10-17 21:19:02 -04:00
ayazhafiz ce7f934c66 feat(language-service): directive info when looking up attribute's symbol (#33127)
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
2019-10-15 16:49:18 +00:00
ayazhafiz e409ed0eab feat(language-service): hover information for component NgModules (#33118)
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
2019-10-14 20:28:06 +00:00
Ayaz Hafiz b04488d692 feat(compiler): record absolute span of template expressions in parser (#31897)
Currently, the spans of expressions are recorded only relative to the
template node that they reside in, not their source file.

Introduce a `sourceSpan` property on expression ASTs that records the
location of an expression relative to the entire source code file that
it is in. This may allow for reducing duplication of effort in
ngtsc/typecheck/src/diagnostics later on as well.

Child of #31898

PR Close #31897
2019-10-14 20:14:16 +00:00
Keen Yee Liau adb562bca6 fix(language-service): create StaticReflector once only (#32543)
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
2019-10-03 15:02:03 -07:00
ayazhafiz 0d186dda35 feat(language-service): module definitions on directive hover (#32763)
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
2019-10-02 13:26:30 -07:00
ayazhafiz 98feee7e0e feat(language-service): allow retreiving synchronized analyzed NgModules (#32779)
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
2019-10-01 11:02:09 -07:00
ayazhafiz 2846505dbd feat(language-service): expose determining the NgModule of a Directive (#32710)
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
2019-09-18 12:59:35 -07:00
ayazhafiz 4c168ed9ba feat(language-service): provide diagnostics for invalid styleUrls (#32674)
Similar to diagnostics for invalid templateUrls, check that styleUrls
actually point to a valid Url.

Closes #32564.

PR Close #32674
2019-09-17 13:38:37 -07:00
ayazhafiz e1065eec5b refactor(language-service): let -> const (#32668)
Another flyby cleanup

PR Close #32668
2019-09-13 08:56:43 -07:00
Keen Yee Liau bbb2798d41 fix(language-service): Use tsLSHost.fileExists() to resolve modules (#32642)
The ModuleResolutionHost implementation inside ReflectorHost currently
relies on reading the snapshot to determine if a file exists, and use
the snapshot to retrieve the file content.
It is more straightforward and efficient to use the already existing
method fileExists() instead.

At runtime, the TypeScript LanguageServiceHost is really a Project, so
both fileExists() and readFile() methods are defined.

As a micro-optimization, skip fs lookup for tsx files.

PR Close #32642
2019-09-12 17:18:06 -07:00
Keen Yee Liau e82f56b96f feat(language-service): enable logging on TypeScriptHost (#32645)
This PR adds loggin methods to TypeScriptHost so that proper logging
to file could be done.
Three new methods are added: log(), error(), and debug().

PR Close #32645
2019-09-12 14:02:18 -07:00
ayazhafiz adeee0fa7f feat(language-service): provide diagnostic for invalid templateUrls (#32586)
`templateUrls` that do not point to actual files are now diagnosed as such
by the Language Service. Support for `styleUrls` will come in a next PR.

This introduces a utility method `getPropertyValueOfType` that scans
TypeScript ASTs until a property assignment whose initializer of a
certain type is found. This PR also notices a couple of things that
could be improved in the language-service implementation, such as
enumerating directive properties and unifying common logic, that will be
fixed in future PRs.

Part of #32564.

PR Close #32586
2019-09-12 11:47:44 -07:00
Keen Yee Liau 1771d6ff25 fix(language-service): Lazily instantiate MetadataResolver (#32631)
The instantiation of the resolver also requires instantiation of the
StaticReflector, and the latter requires resolution of core Angular symbols.
Module resolution should not be done during instantiation to avoid potential
cyclic dependency between the plugin and the containing Project, so the
Singleton pattern is used to create the resolver.

PR Close #32631
2019-09-12 10:24:32 -07:00