Skip to content

Conversation

devversion
Copy link
Member

@devversion devversion commented Feb 11, 2020

The undecorated-classes-with-decorated-fields migration has been
introduced with 904a201, but misses logic for decorating derived classes
of undecorated classes which use Angular features. Example scenario:

export abstract class MyBaseClass {
  @input() someInput = true;
}

export abstract class BaseClassTwo extends MyBaseClass {}

@component(...)
export class MyButton extends BaseClassTwo {}

Both abstract classes would need to be migrated. Previously, the migration
only added @Directive() to MyBaseClass, but with this change, it also
decorates BaseClassTwo.

This is necessary because the Angular Compiler requires BaseClassTwo to
have a directive definition when it flattens the directive metadata for
MyButton in order to perform type checking. Technically, not decorating
BaseClassTwo does not break at runtime because the inherit definition feature
walks up the prototype chain. Though we want to enforce consistent use of
@Directive to simplify the mental model. See the migration guide for motivation.

Fixes #34376.

Note: It should be easier and less verbose to to review the commits individually.

@devversion devversion added action: discuss action: review The PR is still awaiting reviews from at least one requested reviewer area: core Issues related to the framework runtime target: patch This PR is targeted for the next patch release labels Feb 11, 2020
@ngbot ngbot bot added this to the needsTriage milestone Feb 11, 2020
@devversion devversion force-pushed the fix/migration-improvements branch from 3c485da to 2a6e547 Compare February 13, 2020 18:36
@devversion devversion marked this pull request as ready for review February 13, 2020 19:02
@devversion devversion force-pushed the fix/migration-improvements branch 3 times, most recently from 1c406ad to ea27239 Compare February 14, 2020 17:59
Copy link
Member

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

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

A couple of nits, but otherwise LGTM.

Moves the `findBaseClassDeclarations` method into the shared
schematic utilities. This method will be useful for future
migrations, and for planned changes to the
`undecorated-classes-with-decorated-fields` migration.
The import manager has been created for both the `missing-injectable`
and `undecorated-classes-with-di` migration. Both initial PRs brought
in the manager class, so the manager is duplicated in the schematics.

In order to reduce this duplication, and to expose the manager to other
schematics/migrations, we move it into the shared schematic utils.
…ot decorate derived classes

The `undecorated-classes-with-decorated-fields` migration has been
introduced with 904a201, but misses
logic for decorating derived classes of undecorated classes which use
Angular features. Example scenario:

```ts
export abstract class MyBaseClass {
  @input() someInput = true;
}

export abstract class BaseClassTwo extends MyBaseClass {}

@component(...)
export class MyButton extends BaseClassTwo {}
```

Both abstract classes would need to be migrated. Previously, the migration
only added `@Directive()` to `MyBaseClass`, but with this change, it
also decorates `BaseClassTwo`.

This is necessary because the Angular Compiler requires `BaseClassTwo` to
have a directive definition when it flattens the directive metadata for
`MyButton` in order to perform type checking. Technically, not decorating
`BaseClassTwo` does not break at runtime.

We basically want to enforce consistent use of `@Directive` to simplify the
mental model. [See the migration guide](https://angular.io/guide/migration-undecorated-classes#migrating-classes-that-use-field-decorators).

Fixes angular#34376.
…lds migration

We don't have an integration test for the `undecorated-classes-with-decorated-fields
migration. For consistency and to cover for the latest changes, we add
it to the `ng update` integration test.
…act classes

In version 10, undecorated base classes that use Angular features need
to be decorated explicitly with `@Directive()`. Additionally, derived
classes of abstract directives need to be decorated.

The migration already handles this for undecorated classes that are
not explicitly decorated, but since in V9, abstract directives can be
used, we also need to handle this for explicitly decorated abstract
directives. e.g.

```
@directive()
export class Base {...}

// needs to be decorated by migration when updating from v9 to v10
export class Wrapped extends Base {}

@component(...)
export class Cmp extends Wrapped {}
```
@devversion devversion force-pushed the fix/migration-improvements branch from ea27239 to 304c0df Compare February 19, 2020 18:05
@devversion
Copy link
Member Author

@alxhub A similar discussion came up for this in the ngcc channel. It looks like it's unclear whether intermediary classes (as shown in the PR description) need to be decorated or not. It might be good to have a look at that discussion, so that we can have a consistent solution for both ngcc and ng update.

@devversion devversion requested review from josephperrott and removed request for AndrewKushnir March 24, 2020 22:53
@devversion devversion assigned josephperrott and unassigned kara, alxhub and crisbeto Mar 24, 2020
Copy link
Member

@josephperrott josephperrott left a comment

Choose a reason for hiding this comment

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

LGTM

Reviewed-for: integration-tests

@josephperrott josephperrott removed the request for review from IgorMinar March 24, 2020 23:07
@pullapprove pullapprove bot requested a review from IgorMinar March 24, 2020 23:07
Copy link
Member

@josephperrott josephperrott left a comment

Choose a reason for hiding this comment

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

LGTM

Reviewed-for: dev-infra

@devversion devversion added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Mar 25, 2020
@devversion devversion removed the request for review from IgorMinar March 25, 2020 14:34
@devversion devversion added action: presubmit The PR is in need of a google3 presubmit merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note labels Mar 30, 2020
@devversion
Copy link
Member Author

Caretaker: Can you please run presubmit for this? I'm unsure whether schematic code is synced into g3. If it is not, then we should update the bot to exclude the folder.

@kara
Copy link
Contributor

kara commented Apr 1, 2020

presubmit

@kara kara removed the action: presubmit The PR is in need of a google3 presubmit label Apr 2, 2020
@kara kara closed this in 8e55a11 Apr 2, 2020
kara pushed a commit that referenced this pull request Apr 2, 2020
The import manager has been created for both the `missing-injectable`
and `undecorated-classes-with-di` migration. Both initial PRs brought
in the manager class, so the manager is duplicated in the schematics.

In order to reduce this duplication, and to expose the manager to other
schematics/migrations, we move it into the shared schematic utils.

PR Close #35339
kara pushed a commit that referenced this pull request Apr 2, 2020
…ot decorate derived classes (#35339)

The `undecorated-classes-with-decorated-fields` migration has been
introduced with 904a201, but misses
logic for decorating derived classes of undecorated classes which use
Angular features. Example scenario:

```ts
export abstract class MyBaseClass {
  @input() someInput = true;
}

export abstract class BaseClassTwo extends MyBaseClass {}

@component(...)
export class MyButton extends BaseClassTwo {}
```

Both abstract classes would need to be migrated. Previously, the migration
only added `@Directive()` to `MyBaseClass`, but with this change, it
also decorates `BaseClassTwo`.

This is necessary because the Angular Compiler requires `BaseClassTwo` to
have a directive definition when it flattens the directive metadata for
`MyButton` in order to perform type checking. Technically, not decorating
`BaseClassTwo` does not break at runtime.

We basically want to enforce consistent use of `@Directive` to simplify the
mental model. [See the migration guide](https://angular.io/guide/migration-undecorated-classes#migrating-classes-that-use-field-decorators).

Fixes #34376.

PR Close #35339
kara pushed a commit that referenced this pull request Apr 2, 2020
…lds migration (#35339)

We don't have an integration test for the `undecorated-classes-with-decorated-fields
migration. For consistency and to cover for the latest changes, we add
it to the `ng update` integration test.

PR Close #35339
kara pushed a commit that referenced this pull request Apr 2, 2020
…act classes (#35339)

In version 10, undecorated base classes that use Angular features need
to be decorated explicitly with `@Directive()`. Additionally, derived
classes of abstract directives need to be decorated.

The migration already handles this for undecorated classes that are
not explicitly decorated, but since in V9, abstract directives can be
used, we also need to handle this for explicitly decorated abstract
directives. e.g.

```
@directive()
export class Base {...}

// needs to be decorated by migration when updating from v9 to v10
export class Wrapped extends Base {}

@component(...)
export class Cmp extends Wrapped {}
```

PR Close #35339
kara pushed a commit that referenced this pull request Apr 2, 2020
…35339)

Moves the `findBaseClassDeclarations` method into the shared
schematic utilities. This method will be useful for future
migrations, and for planned changes to the
`undecorated-classes-with-decorated-fields` migration.

PR Close #35339
kara pushed a commit that referenced this pull request Apr 2, 2020
The import manager has been created for both the `missing-injectable`
and `undecorated-classes-with-di` migration. Both initial PRs brought
in the manager class, so the manager is duplicated in the schematics.

In order to reduce this duplication, and to expose the manager to other
schematics/migrations, we move it into the shared schematic utils.

PR Close #35339
kara pushed a commit that referenced this pull request Apr 2, 2020
…ot decorate derived classes (#35339)

The `undecorated-classes-with-decorated-fields` migration has been
introduced with 904a201, but misses
logic for decorating derived classes of undecorated classes which use
Angular features. Example scenario:

```ts
export abstract class MyBaseClass {
  @input() someInput = true;
}

export abstract class BaseClassTwo extends MyBaseClass {}

@component(...)
export class MyButton extends BaseClassTwo {}
```

Both abstract classes would need to be migrated. Previously, the migration
only added `@Directive()` to `MyBaseClass`, but with this change, it
also decorates `BaseClassTwo`.

This is necessary because the Angular Compiler requires `BaseClassTwo` to
have a directive definition when it flattens the directive metadata for
`MyButton` in order to perform type checking. Technically, not decorating
`BaseClassTwo` does not break at runtime.

We basically want to enforce consistent use of `@Directive` to simplify the
mental model. [See the migration guide](https://angular.io/guide/migration-undecorated-classes#migrating-classes-that-use-field-decorators).

Fixes #34376.

PR Close #35339
kara pushed a commit that referenced this pull request Apr 2, 2020
…lds migration (#35339)

We don't have an integration test for the `undecorated-classes-with-decorated-fields
migration. For consistency and to cover for the latest changes, we add
it to the `ng update` integration test.

PR Close #35339
kara pushed a commit that referenced this pull request Apr 2, 2020
…act classes (#35339)

In version 10, undecorated base classes that use Angular features need
to be decorated explicitly with `@Directive()`. Additionally, derived
classes of abstract directives need to be decorated.

The migration already handles this for undecorated classes that are
not explicitly decorated, but since in V9, abstract directives can be
used, we also need to handle this for explicitly decorated abstract
directives. e.g.

```
@directive()
export class Base {...}

// needs to be decorated by migration when updating from v9 to v10
export class Wrapped extends Base {}

@component(...)
export class Cmp extends Wrapped {}
```

PR Close #35339
@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 May 3, 2020
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 area: core Issues related to the framework runtime cla: yes merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migration autofix not adding @Directive to intermediary component abstract classes
7 participants