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

Batch of ngtsc changes for Material, CLI, g3 compatibility. #25080

Closed
wants to merge 8 commits into from

Conversation

alxhub
Copy link
Member

@alxhub alxhub commented Jul 25, 2018

No description provided.

@alxhub alxhub requested a review from vicb July 25, 2018 00:16
@mary-poppins
Copy link

You can preview 87f72d7 at https://pr25080-87f72d7.ngbuilds.io/.

foreignFunctionResolver?(node: ts.FunctionDeclaration|ts.MethodDeclaration): ts.Expression|null;
foreignFunctionResolver?
(ref: Reference<ts.FunctionDeclaration|ts.MethodDeclaration>,
args: ReadonlyArray<ts.Expression>): ts.Expression|null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a ReadonlyArray here but not in other places?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it can directly accept the .arguments property of a ts.CallExpression, which is a NodeArray that extends ReadonlyArray.

return node;
}
const arg = node.arguments[0];
if (!ts.isArrowFunction(arg) || ts.isBlock(arg.body)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it have to be an arrow function?
Wouldn't that be a problem for (f)esm5 in ngcc?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Fixed.

@@ -14,7 +14,7 @@ import {Reference, filterToMembersWithDecorator, reflectObjectLiteral, staticall
import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform';

import {SelectorScopeRegistry} from './selector_scope';
import {getConstructorDependencies, isAngularCore, unwrapExpression} from './util';
import {forwardRefResolver, getConstructorDependencies, isAngularCore, unwrapExpression, unwrapForwardRef} from './util';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forwardRefResolver looks unused, could it be removed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -103,3 +103,33 @@ export function unwrapExpression(node: ts.Expression): ts.Expression {
}
return node;
}

export function unwrapForwardRef(node: ts.Expression, reflector: ReflectionHost): ts.Expression {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a one liner comment

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -78,6 +78,11 @@ export interface ResolvedValueArray extends Array<ResolvedValue> {}
*/
type Scope = Map<ts.ParameterDeclaration, ResolvedValue>;

export enum ImportMode {
USE_EXISTING_IMPORT,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: enums use PascalCase

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use const enum ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. No need for const enum, this never ends up in the browser.

vicb
vicb previously requested changes Jul 25, 2018
Copy link
Contributor

@vicb vicb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a few minor comments. LGTM otherwise

@mary-poppins
Copy link

You can preview 6d97ae0 at https://pr25080-6d97ae0.ngbuilds.io/.

@mary-poppins
Copy link

You can preview ea60fe3 at https://pr25080-ea60fe3.ngbuilds.io/.

@alxhub alxhub changed the title Two ngtsc changes for Material compatibility Batch of ngtsc changes for Material, CLI, g3 compatibility. Jul 26, 2018
@mary-poppins
Copy link

You can preview 054df5e at https://pr25080-054df5e.ngbuilds.io/.

@ContentChild[ren] and @ViewChild[ren] can contain a forwardRef() to a
type. This commit allows ngtsc to unwrap the forward reference and
deal with the node inside.

It includes two modes of support for forward reference resolution -
a foreign function resolver which understands deeply nested forward
references in expressions that are being statically evaluated, and
an unwrapForwardRef() function which deals only with top-level nodes.

Both will be useful in the future, but for now only unwrapForwardRef()
is used.
When ngtsc encounters a reference to a type (for example, a Component
type listed in an NgModule declarations array), it traces the import
of that type and attempts to determine the best way to refer to it.

In the event the type is defined in the same file where a reference
is being generated, the identifier of the type is used. If the type
was imported, ngtsc has a choice. It can use the identifier from the
original import, or it can write a new import to the module where the
type came from.

ngtsc has a bug currently when it elects to rely on the user's import.
When writing a .d.ts file, the user's import may have been elided as
the type was not referred to from the type side of the program. Thus,
in .d.ts files ngtsc must always assume the import may not exist, and
generate a new one.

In .js output the import is guaranteed to still exist, so it's
preferable for ngtsc to continue using the existing import if one is
available.

This commit changes how @angular/compiler writes type definitions, and
allows it to use a different expression to write a type definition than
is used to write the value. This allows ngtsc to specify that types in
type definitions should always be imported. A corresponding change to
the staticallyResolve() Reference system allows the choice of which
type of import to use when generating an Expression from a Reference.
There is a bug in the existing handling for cross-file references.
Suppose there are two files, module.ts and component.ts.

component.ts declares two components, one of which uses the other.
In the Ivy model, this means the component will get a directives:
reference to the other in its defineComponent call.

That reference is generated by looking at the declared components
of the module (in module.ts). However, the way ngtsc tracks this
reference, it ends up comparing the identifier of the component
in module.ts with the component.ts file, detecting they're not in
the same file, and generating a relative import.

This commit changes ngtsc to track all identifiers of a reference,
including the one by which it is declared. This allows toExpression()
to correctly decide that a local reference is okay in component.ts.
ngtsc used to assume that all .d.ts dependencies (that is, third party
packages) were imported via an absolute module path. It turns out this
assumption isn't valid; some build tools allow relative imports of
other compilation units.

In the absolute case, ngtsc assumes (and still does) that all referenced
types are available through the entrypoint from which an @NgModule was
imported. This commit adds support for relative imports, in which case
ngtsc will use relative path resolution to determine the imports.
ngtsc used to have a custom ts.CompilerHost which delegated to the plain
ts.CompilerHost. There's no need for this wrapper class and it causes
issues with CLI integration, so delete it.
compile_strategy() is used to decide whether to build Angular code
using ngc (legacy) or ngtsc (local). In order for g3 BUILD rules
to switch properly and allow testing of Ivy in g3, they need to
import this function.

This commit removes the _ prefix which allows the function to be
imported.
loadNgStructureAsync() for ngtsc has a bug where it returns a
Promise<Promise[]> instead of awaiting the entire array of Promises.

This commit uses Promise.all() to await the whole set.
This commit replaces the "not implemented" error when calling
listLazyRoutes() with an empty result, which will allow testing
in the CLI before listLazyRoutes() is implemented.
@mary-poppins
Copy link

You can preview 2c0fa0f at https://pr25080-2c0fa0f.ngbuilds.io/.

@alxhub alxhub added action: merge The PR is ready for merge by the caretaker target: major This PR is targeted for the next major release labels Jul 26, 2018
@alxhub
Copy link
Member Author

alxhub commented Jul 26, 2018

Copy link
Contributor

@mhevery mhevery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable to me. Please take care of comments by others before merging.

@IgorMinar IgorMinar dismissed vicb’s stale review July 26, 2018 23:01

all comments have been addressed as far as I can tell.

@IgorMinar IgorMinar closed this in f902b5e Jul 26, 2018
IgorMinar pushed a commit that referenced this pull request Jul 26, 2018
When ngtsc encounters a reference to a type (for example, a Component
type listed in an NgModule declarations array), it traces the import
of that type and attempts to determine the best way to refer to it.

In the event the type is defined in the same file where a reference
is being generated, the identifier of the type is used. If the type
was imported, ngtsc has a choice. It can use the identifier from the
original import, or it can write a new import to the module where the
type came from.

ngtsc has a bug currently when it elects to rely on the user's import.
When writing a .d.ts file, the user's import may have been elided as
the type was not referred to from the type side of the program. Thus,
in .d.ts files ngtsc must always assume the import may not exist, and
generate a new one.

In .js output the import is guaranteed to still exist, so it's
preferable for ngtsc to continue using the existing import if one is
available.

This commit changes how @angular/compiler writes type definitions, and
allows it to use a different expression to write a type definition than
is used to write the value. This allows ngtsc to specify that types in
type definitions should always be imported. A corresponding change to
the staticallyResolve() Reference system allows the choice of which
type of import to use when generating an Expression from a Reference.

PR Close #25080
IgorMinar pushed a commit that referenced this pull request Jul 26, 2018
There is a bug in the existing handling for cross-file references.
Suppose there are two files, module.ts and component.ts.

component.ts declares two components, one of which uses the other.
In the Ivy model, this means the component will get a directives:
reference to the other in its defineComponent call.

That reference is generated by looking at the declared components
of the module (in module.ts). However, the way ngtsc tracks this
reference, it ends up comparing the identifier of the component
in module.ts with the component.ts file, detecting they're not in
the same file, and generating a relative import.

This commit changes ngtsc to track all identifiers of a reference,
including the one by which it is declared. This allows toExpression()
to correctly decide that a local reference is okay in component.ts.

PR Close #25080
IgorMinar pushed a commit that referenced this pull request Jul 26, 2018
ngtsc used to assume that all .d.ts dependencies (that is, third party
packages) were imported via an absolute module path. It turns out this
assumption isn't valid; some build tools allow relative imports of
other compilation units.

In the absolute case, ngtsc assumes (and still does) that all referenced
types are available through the entrypoint from which an @NgModule was
imported. This commit adds support for relative imports, in which case
ngtsc will use relative path resolution to determine the imports.

PR Close #25080
IgorMinar pushed a commit that referenced this pull request Jul 26, 2018
ngtsc used to have a custom ts.CompilerHost which delegated to the plain
ts.CompilerHost. There's no need for this wrapper class and it causes
issues with CLI integration, so delete it.

PR Close #25080
IgorMinar pushed a commit that referenced this pull request Jul 26, 2018
compile_strategy() is used to decide whether to build Angular code
using ngc (legacy) or ngtsc (local). In order for g3 BUILD rules
to switch properly and allow testing of Ivy in g3, they need to
import this function.

This commit removes the _ prefix which allows the function to be
imported.

PR Close #25080
IgorMinar pushed a commit that referenced this pull request Jul 26, 2018
)

loadNgStructureAsync() for ngtsc has a bug where it returns a
Promise<Promise[]> instead of awaiting the entire array of Promises.

This commit uses Promise.all() to await the whole set.

PR Close #25080
IgorMinar pushed a commit that referenced this pull request Jul 26, 2018
This commit replaces the "not implemented" error when calling
listLazyRoutes() with an empty result, which will allow testing
in the CLI before listLazyRoutes() is implemented.

PR Close #25080
alexeagle pushed a commit to alexeagle/angular that referenced this pull request Sep 18, 2018
…r#25080)

compile_strategy() is used to decide whether to build Angular code
using ngc (legacy) or ngtsc (local). In order for g3 BUILD rules
to switch properly and allow testing of Ivy in g3, they need to
import this function.

This commit removes the _ prefix which allows the function to be
imported.

PR Close angular#25080
FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this pull request Jan 3, 2019
@ContentChild[ren] and @ViewChild[ren] can contain a forwardRef() to a
type. This commit allows ngtsc to unwrap the forward reference and
deal with the node inside.

It includes two modes of support for forward reference resolution -
a foreign function resolver which understands deeply nested forward
references in expressions that are being statically evaluated, and
an unwrapForwardRef() function which deals only with top-level nodes.

Both will be useful in the future, but for now only unwrapForwardRef()
is used.

PR Close angular#25080
FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this pull request Jan 3, 2019
When ngtsc encounters a reference to a type (for example, a Component
type listed in an NgModule declarations array), it traces the import
of that type and attempts to determine the best way to refer to it.

In the event the type is defined in the same file where a reference
is being generated, the identifier of the type is used. If the type
was imported, ngtsc has a choice. It can use the identifier from the
original import, or it can write a new import to the module where the
type came from.

ngtsc has a bug currently when it elects to rely on the user's import.
When writing a .d.ts file, the user's import may have been elided as
the type was not referred to from the type side of the program. Thus,
in .d.ts files ngtsc must always assume the import may not exist, and
generate a new one.

In .js output the import is guaranteed to still exist, so it's
preferable for ngtsc to continue using the existing import if one is
available.

This commit changes how @angular/compiler writes type definitions, and
allows it to use a different expression to write a type definition than
is used to write the value. This allows ngtsc to specify that types in
type definitions should always be imported. A corresponding change to
the staticallyResolve() Reference system allows the choice of which
type of import to use when generating an Expression from a Reference.

PR Close angular#25080
FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this pull request Jan 3, 2019
There is a bug in the existing handling for cross-file references.
Suppose there are two files, module.ts and component.ts.

component.ts declares two components, one of which uses the other.
In the Ivy model, this means the component will get a directives:
reference to the other in its defineComponent call.

That reference is generated by looking at the declared components
of the module (in module.ts). However, the way ngtsc tracks this
reference, it ends up comparing the identifier of the component
in module.ts with the component.ts file, detecting they're not in
the same file, and generating a relative import.

This commit changes ngtsc to track all identifiers of a reference,
including the one by which it is declared. This allows toExpression()
to correctly decide that a local reference is okay in component.ts.

PR Close angular#25080
FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this pull request Jan 3, 2019
ngtsc used to assume that all .d.ts dependencies (that is, third party
packages) were imported via an absolute module path. It turns out this
assumption isn't valid; some build tools allow relative imports of
other compilation units.

In the absolute case, ngtsc assumes (and still does) that all referenced
types are available through the entrypoint from which an @NgModule was
imported. This commit adds support for relative imports, in which case
ngtsc will use relative path resolution to determine the imports.

PR Close angular#25080
FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this pull request Jan 3, 2019
ngtsc used to have a custom ts.CompilerHost which delegated to the plain
ts.CompilerHost. There's no need for this wrapper class and it causes
issues with CLI integration, so delete it.

PR Close angular#25080
FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this pull request Jan 3, 2019
…r#25080)

compile_strategy() is used to decide whether to build Angular code
using ngc (legacy) or ngtsc (local). In order for g3 BUILD rules
to switch properly and allow testing of Ivy in g3, they need to
import this function.

This commit removes the _ prefix which allows the function to be
imported.

PR Close angular#25080
FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this pull request Jan 3, 2019
…ular#25080)

loadNgStructureAsync() for ngtsc has a bug where it returns a
Promise<Promise[]> instead of awaiting the entire array of Promises.

This commit uses Promise.all() to await the whole set.

PR Close angular#25080
FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this pull request Jan 3, 2019
This commit replaces the "not implemented" error when calling
listLazyRoutes() with an empty result, which will allow testing
in the CLI before listLazyRoutes() is implemented.

PR Close angular#25080
@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 Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants