GeezerVison is showing github.com — Proposal: AOT Compiler instructions · Issue #14128 · angular/angular
Proposal: AOT Compiler instructions #14128Description[ ] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
Currently, the AOT compiler is very strict and requires every object involved in DI / metadata to resolve to a symbol that the AOT compiler can work with.
It is so strict that in some scenarios, even though the symbol information is not required, it will still fail (#12631, #13138)
It makes it difficult to write custom decorators to angular component or classes that are @Injectable
It is clear why all items in providers must resolve to a known symbol, but custom decorators for a @Component class can fail even though it's not important.
It also creates coupling between the compiler and the core. In general it must know about every runtime generated object even if the type is known in design time (via generic).
To solve this, the compiler workaround is to import core and register a bypass to all core decorators
this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Host'), Host);
this._registerDecoratorOrConstructor(
this.findDeclaration(diDecorators, 'Injectable'), Injectable);
this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Self'), Self);
See code
This behaviour make is almost impossible to customise angular, you can customise in JIT but not in AOT.
Since the compiler can not get instructions how to resolve symbols for dynamic objects the experience between JIT and AOT is different.
Expected behavior
Allow developers to provide instruction to the compiler.
The best approach would be to use design-time decorators, not yet supported microsoft/TypeScript#2900
This gives the user the ability to provide design time information to the AOT compiler.
Until it lands a workaround to remove it can be using a webpack loader either via Transformers API or through a simple loader that removes that code in 2 places.
A great use case is mixins. Now that microsoft/TypeScript#13604 is in master, and will be in 2.2 this is really important for implementing the mixin pattern.
class User_ {
}
export const User = RestMixin(User);
export type User = User_ & Mixin
Currently, this will fail if User is included as a provider.
There is no actual reason for it to fail since RestMixin returns all the type information.
It fails because the compiler can't resolve User into a symbol since it is dealing with complex function (RestMixin)
If I could notify the compiler what to do no compilation error.
In this case telling the compiler to resolve the symbol of User_ to User
In the current code I tried it via this hack, it worked:
if (staticSymbol.name === 'RestMixin') converter = (ctx, args) => { return args[0]};
@mhevery @tbosch Activitymhevery commented on Jan 28, 2017 chuckjaz commented on Jan 28, 2017 Custom decorators are ignored and transparent to ngc. There was a bug introduced in 2.4.0 that has been fixed, #13605. If there are other cases where custom decorators produce errors during ngc please file a bug.
Libraries that use custom decorators cannot turn on strict metadata checking as such annotation will still record errors in the metadata, but the errors will not be reported by the static reflector.
As for RestMixin, it seems like what you need is a way to mark a function as a class factory (that is a function that produces a reference to a class). It is not important how User is constructed, only that it is exported and should be treated as if it were a class. Maybe something recording if @classfactory is in the comment block associated with the function would be sufficient. Then the StaticReflector would consider symbols that have the a value returned from a @classfactory identically as it treats symbols created by using the class syntax. shlomiassaf commented on Jan 30, 2017 ContributorAuthor More actions @chuckjaz I will test the first part, see if custom decorators work past 2.4.x
The RestMixin case is a bit more complicated, I'm not sure this single "flag" will do, but it might be so... The AOT compiler is mysterious in many (many) recursive ways :)
If so, why do you register a bypass to all class decorators defined in core?
this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Host'), Host);
this._registerDecoratorOrConstructor(
this.findDeclaration(diDecorators, 'Injectable'), Injectable);
this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Self'), Self);
See code
Seems redundant?
The usage of the base objects (Host, Injectable, Self...) is wired, it is getting instantiated (e.g. new Host()) inside the compiler, which is not an angular runtime environment so my guess it's really not that important as you say.
By the way mixin's are now fully supported, microsoft/TypeScript#13743 , that is from 2.2 :) chuckjaz commented on Jan 30, 2017 What you are seeing is not a "bypass". It is registration of classes that have special meaning in the context of AOT compile. The functions and constructors registered have known and tested semantics for use during AOT compile.
I am not convinced extending the StaticReflector is the right solution here.
Once #14154 is fixed, we will support the syntax proposed in microsoft/TypeScript#13743:
class Customer extends Tagged(Person) {
}
The only thing we need to support:
const TaggedPoint = Tagged(Point);
is something to tell us that Tagged produces classes. Currently the StaticReflector does not need type information to provide the information necessary for the AOT compiler to produce valid TypeScript. The only thing, without annotation, that tells me that Tagged returns a class is its type. Using @classfactory would allow me to distinguish it as a class factory without having to look for a new function in its type. shlomiassaf commented on Jan 31, 2017 ContributorAuthor More actions @chuckjaz that's great.
Implementation details... are you planning on comment annotation or code decorators?
While comments will work with no issues they are limiting refactor wise, analysis wise etc...
On the other hand, decorators will currently effect code output, they require a new decorator construct in angular and they require an extra build configuration. chuckjaz commented on Jan 31, 2017 functions cannot have decorators so we are restricted to comment annotations for now.
shlomiassaf commented on Feb 6, 2017 ContributorAuthor More actions @chuckjaz Another update
export const User = RestMixin(User_);
export type User = RestMixin<Use_r>;
This works with AOT as long as User is not part of any providers array.
export class User extends RestMixin(User_) { }
This does not work with AOT regardless, even if the class is not used in angular it still errors.
The latter is also a mixin pattern supported in TS 2.2 (end ES6 in general)
Does your proposed solution solve this as well? chuckjaz commented on Feb 7, 2017 #14154 should have fixed this. shlomiassaf commented on Feb 13, 2017 ContributorAuthor More actions @chuckjaz @mhevery does this issue needs to be tagged so it won't get forgotten?
What's the milestone for this? DzmitryShylovich commented on Mar 25, 2017 tbosch commented on Apr 10, 2017 shlomiassaf commented on Apr 12, 2017 ContributorAuthor More actions @tbosch @DzmitryShylovich @chuckjaz
Not working... AOT fails:
Error: Error encountered resolving symbol values statically. Calling function 'RestMixin', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol UserConst
Tested with:
Typescript: 2.3.0-dev.20170329
angular/compiler 4.0.0
angular/compiler-cli 4.0.0
crh225 commented on May 12, 2017 shlomiassaf commented on May 12, 2017 ContributorAuthor More actions Lol, yep, didn't notice that.
My first message was that it was ok, then I ran AOT and it failed.
I edited before he closed but I guess his browser only updated the message in real time, not the edit. It happens on GitHub.
Ping @tbosch tbosch commented on May 12, 2017 @shlomiassaf could you create a branch that reproduces the error? vicb commented on May 31, 2018 Closing after no update in 1 year angular-automatic-lock-bot commented on Sep 13, 2019 This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|