GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Proposal: AOT Compiler instructions · Issue #14128 · angular/angular

Proposal: AOT Compiler instructions #14128

New issue
Copy link
New issue
Copy link
Closed
Closed
Proposal: AOT Compiler instructions#14128
Copy link
Labels
area: coreIssues related to the framework runtimeIssues related to the framework runtimefeatureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issuesneeds reproductionThis issue needs a reproduction in order for the team to investigate furtherThis issue needs a reproduction in order for the team to investigate further
Milestone
Backlog

Description

@shlomiassaf
shlomiassaf
opened on Jan 26, 2017
Issue body actions
[ ] 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

Activity

  1. mhevery commented on Jan 28, 2017

    @mhevery
    mhevery
    on Jan 28, 2017
    Contributor
    More actions

    /cc @chuckjaz

  2. chuckjaz commented on Jan 28, 2017

    @chuckjaz
    chuckjaz
    on Jan 28, 2017
    Contributor
    More actions

    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.

  3. shlomiassaf commented on Jan 30, 2017

    @shlomiassaf
    shlomiassaf
    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 :)

  4. chuckjaz commented on Jan 30, 2017

    @chuckjaz
    chuckjaz
    on Jan 30, 2017
    Contributor
    More actions

    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.

  5. shlomiassaf commented on Jan 31, 2017

    @shlomiassaf
    shlomiassaf
    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.

  6. chuckjaz commented on Jan 31, 2017

    @chuckjaz
    chuckjaz
    on Jan 31, 2017
    Contributor
    More actions

    functions cannot have decorators so we are restricted to comment annotations for now.

    Reacted by Shlomi Assaf
  7. shlomiassaf commented on Feb 6, 2017

    @shlomiassaf
    shlomiassaf
    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?

  8. chuckjaz commented on Feb 7, 2017

    @chuckjaz
    chuckjaz
    on Feb 7, 2017
    Contributor
    More actions

    #14154 should have fixed this.

  9. shlomiassaf commented on Feb 13, 2017

    @shlomiassaf
    shlomiassaf
    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?

  10. DzmitryShylovich commented on Mar 25, 2017

    @DzmitryShylovich
    DzmitryShylovich
    on Mar 25, 2017
    Contributor
    More actions

    @shlomiassaf #14154 was fixed

  11. tbosch commented on Apr 10, 2017

    @tbosch
    tbosch
    on Apr 10, 2017
    Contributor
    More actions

    @shlomiassaf does it work now for you?

  12. tbosch
    added
    area: coreIssues related to the framework runtimeIssues related to the framework runtime
    flag: can be closed?
    featureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issues
    and removed
    featureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issues
    on Apr 10, 2017
  13. shlomiassaf commented on Apr 12, 2017

    @shlomiassaf
    shlomiassaf
    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
    
  14. tbosch
    closed this as completedon Apr 12, 2017
  15. crh225 commented on May 12, 2017

    @crh225
    crh225
    on May 12, 2017
    More actions

    @shlomiassaf, you commented AOT fails, but @tbosch still closed the ticket? I am confused

  16. shlomiassaf commented on May 12, 2017

    @shlomiassaf
    shlomiassaf
    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

  17. tbosch commented on May 12, 2017

    @tbosch
    tbosch
    on May 12, 2017
    Contributor
    More actions

    @shlomiassaf could you create a branch that reproduces the error?

  18. tbosch
    added
    needs reproductionThis issue needs a reproduction in order for the team to investigate furtherThis issue needs a reproduction in order for the team to investigate further
    and removed
    flag: can be closed?
    on May 12, 2017
  19. tbosch
    reopened this on May 12, 2017
  20. chuckjaz
    added
    featureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issues
    on Nov 21, 2017
  21. ngbot
    added this to the Backlog milestone on Jan 23, 2018
  22. vicb commented on May 31, 2018

    @vicb
    vicb
    on May 31, 2018
    Contributor
    More actions

    Closing after no update in 1 year

    Reacted by Euler Chavez
  23. vicb
    closed this as completedon May 31, 2018
  24. angular-automatic-lock-bot commented on Sep 13, 2019

    @angular-automatic-lock-bot
    angular-automatic-lock-botBot
    on Sep 13, 2019
    More actions

    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.

  25. angular-automatic-lock-bot
    locked and limited conversation to collaborators on Sep 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues related to the framework runtimeIssues related to the framework runtimefeatureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issuesneeds reproductionThis issue needs a reproduction in order for the team to investigate furtherThis issue needs a reproduction in order for the team to investigate further

    Type

    No type

    Projects

    No projects

      Milestone

      • BacklogNo due date

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.