Repository navigation
Conversation
There was a problem hiding this comment.
Both Esm2015ReflectionHost and Esm5ReflectionHost seem to be unused here.
There was a problem hiding this comment.
ClassSymbol (as well as CtorParameter and isFromDtsFile above) seem to be unused.
There was a problem hiding this comment.
I generally find type casting easier to "manually verify", if it is as close as possible to the variable declaration. Consider:
-const declarationSymbol = this.checker.getSymbolAtLocation(outerDeclaration.name);
+const declarationSymbol = this.checker.getSymbolAtLocation(outerDeclaration.name) as ClassSymbol | undefined;
...
return {
name: declarationSymbol.name,
- declaration: declarationSymbol as ClassSymbol,
+ declaration: declarationSymbol,There was a problem hiding this comment.
superSymbol seems a strange name here. It implies (to me) that we are getting a symbol for the super class declaration. But in reality we are asking the super host for the symbol that represents the class. Perhaps classSymbol or es2015ClassSymbol would be preferable?
There was a problem hiding this comment.
Ah, I see how this can cause confusion. I don't personally like es2015ClassSymbol, as it could as well be the TypeScript symbol, so went with classSymbol instead 👍
There was a problem hiding this comment.
typo: change node to declaration here
There was a problem hiding this comment.
typo: change node to declaration here
There was a problem hiding this comment.
superSymbol => classSymbol ?
In ngcc's reflection hosts for compiled JS bundles, such as ESM2015,
special care needs to be taken for classes as there may be an outer
declaration (referred to as "declaration") and an inner declaration
(referred to as "implementation") for a given class. Therefore, there
will also be two `ts.Symbol`s bound per class, and ngcc needs to switch
between those declarations and symbols depending on where certain
information can be found.
Prior to this commit, the `NgccReflectionHost` interface had methods
`getClassSymbol` and `findClassSymbols` that would return a `ts.Symbol`.
These class symbols would be used to kick off compilation of components
using ngtsc, so it is important for these symbols to correspond with the
publicly visible outer declaration of the class. However, the ESM2015
reflection host used to return the `ts.Symbol` for the inner
declaration, if the class was declared as follows:
```javascript
var MyClass = class MyClass {};
```
For the above code, `Esm2015ReflectionHost.getClassSymbol` would return
the `ts.Symbol` corresponding with the `class MyClass {}` declaration,
whereas it should have corresponded with the `var MyClass` declaration.
As a consequence, no `NgModule` could be resolved for the component, so
no components/directives would be in scope for the component. This
resulted in errors during runtime.
This commit resolves the issue by introducing a `NgccClassSymbol` that
contains references to both the outer and inner `ts.Symbol`, instead of
just a single `ts.Symbol`. This avoids the unclarity of whether a
`ts.Symbol` corresponds with the outer or inner declaration.
More details can be found here: https://hackmd.io/7nkgWOFWQlSRAuIW_8KPPw
Fixes angular#32078
Closes FW-1507
c2e4e96 to
3a14c37
Compare
In ngcc's reflection hosts for compiled JS bundles, such as ESM2015,
special care needs to be taken for classes as there may be an outer
declaration (referred to as "declaration") and an inner declaration
(referred to as "implementation") for a given class. Therefore, there
will also be two `ts.Symbol`s bound per class, and ngcc needs to switch
between those declarations and symbols depending on where certain
information can be found.
Prior to this commit, the `NgccReflectionHost` interface had methods
`getClassSymbol` and `findClassSymbols` that would return a `ts.Symbol`.
These class symbols would be used to kick off compilation of components
using ngtsc, so it is important for these symbols to correspond with the
publicly visible outer declaration of the class. However, the ESM2015
reflection host used to return the `ts.Symbol` for the inner
declaration, if the class was declared as follows:
```javascript
var MyClass = class MyClass {};
```
For the above code, `Esm2015ReflectionHost.getClassSymbol` would return
the `ts.Symbol` corresponding with the `class MyClass {}` declaration,
whereas it should have corresponded with the `var MyClass` declaration.
As a consequence, no `NgModule` could be resolved for the component, so
no components/directives would be in scope for the component. This
resulted in errors during runtime.
This commit resolves the issue by introducing a `NgccClassSymbol` that
contains references to both the outer and inner `ts.Symbol`, instead of
just a single `ts.Symbol`. This avoids the unclarity of whether a
`ts.Symbol` corresponds with the outer or inner declaration.
More details can be found here: https://hackmd.io/7nkgWOFWQlSRAuIW_8KPPw
Fixes #32078
Closes FW-1507
PR Close #32539
In ESM2015 bundles, a class with decorators may be emitted as follows:
```javascript
var MyClass_1;
let MyClass = MyClass_1 = class MyClass {};
MyClass.decorators = [/* here be decorators */];
```
Such a class has two declarations: the publicly visible `let MyClass`
and the implementation `class MyClass {}` node. In angular#32539 a refactoring
took place to handle such classes more consistently, however the logic
to find static properties was mistakenly kept identical to its broken
state before the refactor, by looking for static properties on the
implementation symbol (the one for `class MyClass {}`) whereas the
static properties need to be obtained from the symbol corresponding with
the `let MyClass` declaration, as that is where the `decorators`
property is assigned to in the example above.
This commit fixes the behavior by looking for static properties on the
public declaration symbol. This fixes an issue where decorators were not
found for classes that do in fact have decorators, therefore preventing
the classes from being compiled for Ivy.
Fixes angular#31791
In ESM2015 bundles, a class with decorators may be emitted as follows:
```javascript
var MyClass_1;
let MyClass = MyClass_1 = class MyClass {};
MyClass.decorators = [/* here be decorators */];
```
Such a class has two declarations: the publicly visible `let MyClass`
and the implementation `class MyClass {}` node. In #32539 a refactoring
took place to handle such classes more consistently, however the logic
to find static properties was mistakenly kept identical to its broken
state before the refactor, by looking for static properties on the
implementation symbol (the one for `class MyClass {}`) whereas the
static properties need to be obtained from the symbol corresponding with
the `let MyClass` declaration, as that is where the `decorators`
property is assigned to in the example above.
This commit fixes the behavior by looking for static properties on the
public declaration symbol. This fixes an issue where decorators were not
found for classes that do in fact have decorators, therefore preventing
the classes from being compiled for Ivy.
Fixes #31791
PR Close #32619
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
In ngcc's reflection hosts for compiled JS bundles, such as ESM2015,
special care needs to be taken for classes as there may be an outer
declaration (referred to as "declaration") and an inner declaration
(referred to as "implementation") for a given class. Therefore, there
will also be two
ts.Symbols bound per class, and ngcc needs to switchbetween those declarations and symbols depending on where certain
information can be found.
Prior to this commit, the
NgccReflectionHostinterface had methodsgetClassSymbolandfindClassSymbolsthat would return ats.Symbol.These class symbols would be used to kick off compilation of components
using ngtsc, so it is important for these symbols to correspond with the
publicly visible outer declaration of the class. However, the ESM2015
reflection host used to return the
ts.Symbolfor the innerdeclaration, if the class was declared as follows:
For the above code,
Esm2015ReflectionHost.getClassSymbolwould returnthe
ts.Symbolcorresponding with theclass MyClass {}declaration,whereas it should have corresponded with the
var MyClassdeclaration.As a consequence, no
NgModulecould be resolved for the component, sono components/directives would be in scope for the component. This
resulted in errors during runtime.
This commit resolves the issue by introducing a
NgccClassSymbolthatcontains references to both the outer and inner
ts.Symbol, instead ofjust a single
ts.Symbol. This avoids the unclarity of whether ats.Symbolcorresponds with the outer or inner declaration.More details can be found here: https://hackmd.io/7nkgWOFWQlSRAuIW_8KPPw
Fixes #32078
Closes FW-1507