Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular Compiler messes up return statement and duplicates comment in some arrow functions #23829

Closed
interrobrian opened this issue May 10, 2018 · 8 comments
Assignees
Labels
area: compiler Issues related to `ngc`, Angular's template compiler freq1: low needs reproduction This issue needs a reproduction in order for the team to investigate further type: bug/fix
Milestone

Comments

@interrobrian
Copy link

interrobrian commented May 10, 2018

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report 
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

When targeting es5, the Angular Compiler (ngc) produces incorrect JavaScript when it encounters a single statement arrow function with a line comment between the arrow and the statement. This bug prevents the body of the arrow function from executing. For example, this:

const foo = () =>
  // Print "bar"
  console.log("bar");

compiles into this, when using ngc:

var foo = function () {
    // Print "bar"
    return 
    // Print "bar"
    console.log("bar");
};

Not only did it duplicate the comment, but it put the duplicated comment on its own line after return, which causes the function to return before the actual code is run.

Expected behavior

The Angular Compiler should produce the same JavaScript that the TypeScript compiler does with this code:

var foo = function () {
    // Print "bar"
    return console.log("bar");
};

Minimal reproduction of the problem with instructions

Compile the above TypeScript with ngc. For reference, here is the tsconfig.json I used:

{
  "compilerOptions": {
    "target": "es5",
    "experimentalDecorators": true
  }
}

EDIT: More detailed reproduction here

What is the motivation / use case for changing the behavior?

This bug creates unwanted behavior that is very difficult to trace, especially when creating an Angular library. For example, it can make arrow functions used with an array forEach or filter return nothing.

Environment


Angular version: 6.0.0

Browser:
All
 
For Tooling issues:
- Node version: 8.9.4
- Platform:  Mac
@IgorMinar
Copy link
Contributor

Can you please provide a reproduction? We generally don't mess around with the function body of app code so I'm not sure how could we be responsible for this but maybe there is some kind of odd interaction that is not obvious. A repro would help.

@IgorMinar IgorMinar added needs reproduction This issue needs a reproduction in order for the team to investigate further area: core Issues related to the framework runtime labels May 10, 2018
@ngbot ngbot bot added this to the needsTriage milestone May 10, 2018
@interrobrian
Copy link
Author

interrobrian commented May 11, 2018

Sure, I can provide a more detailed reproduction. Since this deals with library compilation, I can't figure out a way to get it into a StackBlitz. However, here's how to reproduce it in a more realistic situation:

  1. Create a fresh app with ng new my-app
  2. Enter the app's directory and create a library with ng g library my-lib
  3. Open up projects/my-lib/src/lib/my-lib.service.ts and add the following function:
public filterLessThanThree(numList: number[]): number[] {
  return numList.filter(n =>
    // Hey look I'm a comment
    n < 3);
}
  1. Run ng build my-lib (Note that it's very important that you test this by building the lib and not by running the app with ng serve, as ng serve uses a different compilation path for local libraries)
  2. At this point, you can find the function has been compiled incorrectly in the following versions:

dist/my-lib/bundles/my-lib.umd.js

...
MyLibService.prototype.filterLessThanThree = /**
    ...
    */
    function (numList) {
        return numList.filter(function (n) {
            // Hey look I'm a comment
            return;
        });
    };
...

dist/my-lib/bundles/my-lib.umd.min.js

... e.prototype.filterLessThanThree=function(e){return e.filter(function(e){})}, ...

dist/my-lib/esm5/lib/my-lib.service.js

MyLibService.prototype.filterLessThanThree = /**
    ...
    */
function (numList) {
    return numList.filter(function (n) {
        // Hey look I'm a comment
        return 
        // Hey look I'm a comment
        n < 3;
    });
};

dist/my-lib/fesm5/my-lib.js

MyLibService.prototype.filterLessThanThree = /**
    ...
    */
function (numList) {
    return numList.filter(function (n) {
        // Hey look I'm a comment
        return 
    });
};

If you'd like to further see how this will effect an app at runtime, you'll need to create a second app and reference the packaged output (simulating as if you had published the package to npm and somebody else is using it):

  1. In the directory containing my-app and run ng new my-second-app
  2. Open the package.json for my-second-app and add "my-lib": "file:../my-app/dist/my-lib" to your dependencies
  3. Run npm install
  4. Add the following to app.component.ts:
import { MyLibService } from "my-lib"
...
export class AppComponent {
  ...
  numListJSON: string;
  constructor(myLibService: MyLibService) {
    this.numListJSON = JSON.stringify(myLibService.filterLessThanThree([1, 2, 3, 4, 5]));
  }
}
  1. Add {{ numListJSON }} somewhere in app.component.html.
  2. Run ng serve and take a look at the app. Note that the JSON string on the page is [] when it should be [1, 2]

@trotyl
Copy link
Contributor

trotyl commented May 11, 2018

Could reproduce by ngc, seems to be a tsickle issue when transformDecorators enabled.

@interrobrian
Copy link
Author

interrobrian commented May 11, 2018

Good find, @trotyl! Looks like this might be related to tsickle issue 57. I'll create a specific issue for this one as well and file it on there.

@interrobrian
Copy link
Author

Filed as tsickle issue 802.

@mprobst
Copy link
Contributor

mprobst commented May 14, 2018

The original tsickle issue has been fixed; it's kind of related in that it's about arrow function emit being a bit fickle. I've sent out a PR to fix angular/tsickle#802, it's caused by the source map transformer synthesizing comments in a way that breaks TS emit (maybe TS emit is also slightly wrong here, see microsoft/TypeScript#24096).

@JoostK
Copy link
Member

JoostK commented Feb 15, 2020

Closing as resolved in angular/tsickle#802

@JoostK JoostK closed this as completed Feb 15, 2020
@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Mar 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: compiler Issues related to `ngc`, Angular's template compiler freq1: low needs reproduction This issue needs a reproduction in order for the team to investigate further type: bug/fix
Projects
None yet
Development

No branches or pull requests

7 participants