From fc4c9baf665f1fca9dd6b49118db91a67f4c8fa3 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 9 Aug 2024 13:13:34 +0000 Subject: [PATCH] refactor(migrations): use import manager in signal input migration (#57318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of fiddling manually with the imports, which worked well, but comes at a cost of complexity— we are now using the canonical import manager. This simplifies deletion, insertion and updating of imports. Notably, our import manager is not super great at preserving whitespaces right now, but we assume a formatter runs over migrated code anyway. PR Close #57318 --- .../src/convert-input/convert_to_signal.ts | 12 ++-- .../src/input_detection/input_decorator.ts | 3 - .../src/passes/10_apply_import_manager.ts | 59 ++++++++++++++++++ .../passes/6_migrate_input_declarations.ts | 60 ++---------------- .../passes/9_migrate_ts_type_references.ts | 38 +----------- .../signal-migration/src/phase_migrate.ts | 15 ++++- .../signal-migration/test/golden.txt | 52 ++++++++-------- .../test/golden_best_effort.txt | 62 +++++++++---------- 8 files changed, 142 insertions(+), 159 deletions(-) create mode 100644 packages/core/schematics/migrations/signal-migration/src/passes/10_apply_import_manager.ts diff --git a/packages/core/schematics/migrations/signal-migration/src/convert-input/convert_to_signal.ts b/packages/core/schematics/migrations/signal-migration/src/convert-input/convert_to_signal.ts index e9c0c107feb..2d6866a94c1 100644 --- a/packages/core/schematics/migrations/signal-migration/src/convert-input/convert_to_signal.ts +++ b/packages/core/schematics/migrations/signal-migration/src/convert-input/convert_to_signal.ts @@ -12,6 +12,7 @@ import ts from 'typescript'; import {MigrationHost} from '../migration_host'; import {ConvertInputPreparation} from './prepare_and_check'; import {DecoratorInputTransform} from '../../../../../../compiler-cli/src/ngtsc/metadata'; +import {ImportManager} from '../../../../../../compiler-cli/src/ngtsc/translator'; const printer = ts.createPrinter({newLine: ts.NewLineKind.LineFeed}); @@ -26,6 +27,7 @@ export function convertToSignalInput( node: ts.PropertyDeclaration, {resolvedMetadata: metadata, resolvedType, isResolvedTypeCheckable}: ConvertInputPreparation, checker: ts.TypeChecker, + importManager: ImportManager, ): string { let initialValue = node.initializer; let optionsLiteral: ts.ObjectLiteralExpression | null = null; @@ -89,11 +91,11 @@ export function convertToSignalInput( inputArgs.push(optionsLiteral); } - const inputFnRef = - metadata.inputDecoratorRef !== null && ts.isPropertyAccessExpression(metadata.inputDecoratorRef) - ? ts.factory.createPropertyAccessExpression(metadata.inputDecoratorRef.expression, 'input') - : ts.factory.createIdentifier('input'); - + const inputFnRef = importManager.addImport({ + exportModuleSpecifier: '@angular/core', + exportSymbolName: 'input', + requestedFile: node.getSourceFile(), + }); const inputInitializerFn = metadata.required ? ts.factory.createPropertyAccessExpression(inputFnRef, 'required') : inputFnRef; diff --git a/packages/core/schematics/migrations/signal-migration/src/input_detection/input_decorator.ts b/packages/core/schematics/migrations/signal-migration/src/input_detection/input_decorator.ts index 71fa372df70..53ef015f0d6 100644 --- a/packages/core/schematics/migrations/signal-migration/src/input_detection/input_decorator.ts +++ b/packages/core/schematics/migrations/signal-migration/src/input_detection/input_decorator.ts @@ -34,7 +34,6 @@ import {InputNode, isInputContainerNode} from '../input_detection/input_node'; /** Metadata extracted of an input declaration (in `.ts` or `.d.ts` files). */ export interface ExtractedInput extends InputMapping { inSourceFile: boolean; - inputDecoratorRef: DecoratorIdentifier | null; } /** Attempts to extract metadata of a potential TypeScript `@Input()` declaration. */ @@ -87,7 +86,6 @@ function extractDtsInput(node: ts.Node, metadataReader: DtsMetadataReader): Extr ? null : { ...inputMapping, - inputDecoratorRef: null, inSourceFile: false, }; } @@ -152,7 +150,6 @@ function extractSourceCodeInput( isSignal: false, inSourceFile: true, transform: transformResult, - inputDecoratorRef: inputDecorator.identifier, }; } diff --git a/packages/core/schematics/migrations/signal-migration/src/passes/10_apply_import_manager.ts b/packages/core/schematics/migrations/signal-migration/src/passes/10_apply_import_manager.ts new file mode 100644 index 00000000000..bef09475eea --- /dev/null +++ b/packages/core/schematics/migrations/signal-migration/src/passes/10_apply_import_manager.ts @@ -0,0 +1,59 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import ts from 'typescript'; +import {ImportManager} from '../../../../../../compiler-cli/src/ngtsc/translator'; +import {Replacement} from '../replacement'; +import {MigrationResult} from '../result'; + +/** + * Phase that applies all changes recorded by the import manager in + * previous migrate phases. + */ +export function pass10_applyImportManager( + importManager: ImportManager, + result: MigrationResult, + sourceFiles: readonly ts.SourceFile[], +) { + const {newImports, updatedImports, deletedImports} = importManager.finalize(); + const printer = ts.createPrinter({}); + const pathToFile = new Map(sourceFiles.map((s) => [s.fileName, s])); + + // Capture new imports + newImports.forEach((newImports, fileName) => { + newImports.forEach((newImport) => { + const printedImport = printer.printNode( + ts.EmitHint.Unspecified, + newImport, + pathToFile.get(fileName)!, + ); + result.addReplacement(fileName, new Replacement(0, 0, `${printedImport}\n`)); + }); + }); + + // Capture updated imports + for (const [oldBindings, newBindings] of updatedImports.entries()) { + const printedBindings = printer.printNode( + ts.EmitHint.Unspecified, + newBindings, + oldBindings.getSourceFile(), + ); + result.addReplacement( + oldBindings.getSourceFile().fileName, + new Replacement(oldBindings.getStart(), oldBindings.getEnd(), printedBindings), + ); + } + + // Update removed imports + for (const removedImport of deletedImports) { + result.addReplacement( + removedImport.getSourceFile().fileName, + new Replacement(removedImport.getStart(), removedImport.getEnd(), ''), + ); + } +} diff --git a/packages/core/schematics/migrations/signal-migration/src/passes/6_migrate_input_declarations.ts b/packages/core/schematics/migrations/signal-migration/src/passes/6_migrate_input_declarations.ts index 544f1595ded..f37bce93d98 100644 --- a/packages/core/schematics/migrations/signal-migration/src/passes/6_migrate_input_declarations.ts +++ b/packages/core/schematics/migrations/signal-migration/src/passes/6_migrate_input_declarations.ts @@ -13,6 +13,7 @@ import {convertToSignalInput} from '../convert-input/convert_to_signal'; import assert from 'assert'; import {MigrationHost} from '../migration_host'; import {KnownInputs} from '../input_detection/known_inputs'; +import {ImportManager} from '../../../../../../compiler-cli/src/ngtsc/translator'; /** * Phase that migrates `@Input()` declarations to signal inputs and @@ -23,6 +24,7 @@ export function pass6__migrateInputDeclarations( checker: ts.TypeChecker, result: MigrationResult, knownInputs: KnownInputs, + importManager: ImportManager, ) { let filesWithMigratedInputs = new Set(); let filesWithIncompatibleInputs = new WeakSet(); @@ -44,65 +46,15 @@ export function pass6__migrateInputDeclarations( new Replacement( input.node.getStart(), input.node.getEnd(), - convertToSignalInput(host, input.node, metadata, checker), + convertToSignalInput(host, input.node, metadata, checker, importManager), ), ); } - // TODO: Consider using import manager for conflicts. but also in `convert_to_signal` then. - for (const file of filesWithMigratedInputs) { - const specifiers = result.inputDecoratorSpecifiers.get(file); - assert(specifiers !== undefined, `No imports in source file of input: ${file.fileName}`); - - const decoratorInputSpecifier = specifiers.find((s) => s.kind === 'decorator-input-import'); - assert(decoratorInputSpecifier, 'Expected at least one import to "Input"'); - - const signalInputSpecifier = specifiers.find((s) => s.kind === 'signal-input-import'); - - if (filesWithIncompatibleInputs.has(file)) { - // add `input`, but not remove `Input`. Both are needed still. - if (signalInputSpecifier === undefined) { - result.addReplacement( - file.fileName, - new Replacement( - decoratorInputSpecifier.node.getEnd(), - decoratorInputSpecifier.node.getEnd(), - ', input', - ), - ); - } - } else { - // replace `Input` with `input`. All migrated in this file. - if (signalInputSpecifier === undefined) { - result.addReplacement( - file.fileName, - new Replacement( - decoratorInputSpecifier.node.getStart(), - decoratorInputSpecifier.node.getEnd(), - 'input', - ), - ); - } else { - const elements = decoratorInputSpecifier.node.parent.elements; - const indexOfSpecifier = elements.findIndex((c) => c === decoratorInputSpecifier.node); - - let start = decoratorInputSpecifier.node.getStart(); - let end = decoratorInputSpecifier.node.getEnd(); - - // Either collapse (the comman between specifiers) with the preceding element, - // or with the following if present. - if (indexOfSpecifier > 0) { - start = elements[indexOfSpecifier - 1].getEnd(); - } else { - if (elements.length > indexOfSpecifier + 1) { - end = elements[indexOfSpecifier + 1].getStart(); - } - } - - // We already have `input` in source code. Remove `Input` completely. - result.addReplacement(file.fileName, new Replacement(start, end, '')); - } + // All inputs were migrated, so we can safely remove the `Input` symbol. + if (!filesWithIncompatibleInputs.has(file)) { + importManager.removeImport(file, 'Input', '@angular/core'); } } } diff --git a/packages/core/schematics/migrations/signal-migration/src/passes/9_migrate_ts_type_references.ts b/packages/core/schematics/migrations/signal-migration/src/passes/9_migrate_ts_type_references.ts index 79a1fe29ce5..4cccdbe433b 100644 --- a/packages/core/schematics/migrations/signal-migration/src/passes/9_migrate_ts_type_references.ts +++ b/packages/core/schematics/migrations/signal-migration/src/passes/9_migrate_ts_type_references.ts @@ -23,10 +23,9 @@ import {ImportManager} from '../../../../../../compiler-cli/src/ngtsc/translator export function pass9__migrateTypeScriptTypeReferences( result: MigrationResult, knownInputs: KnownInputs, + importManager: ImportManager, ) { const seenTypeNodes = new WeakSet(); - const fileNamesToFiles = new Map(); - const importManager = new ImportManager(); for (const reference of result.references) { // This pass only deals with TS input class type references. @@ -50,7 +49,6 @@ export function pass9__migrateTypeScriptTypeReferences( const firstArg = reference.from.node.typeArguments[0]; const sf = firstArg.getSourceFile(); - fileNamesToFiles.set(sf.fileName, sf); const unwrapImportExpr = importManager.addImport({ exportModuleSpecifier: 'google3/javascript/angular2/testing/catalyst', exportSymbolName: 'UnwrapSignalInputs', @@ -70,39 +68,5 @@ export function pass9__migrateTypeScriptTypeReferences( new Replacement(firstArg.getEnd(), firstArg.getEnd(), '>'), ); } - - // TODO: Formalize import manager support across phases. - const {newImports, updatedImports} = importManager.finalize(); - - // Capture new imports - newImports.forEach((newImports, fileName) => { - newImports.forEach((newImport) => { - result.addReplacement( - fileName, - new Replacement( - 0, - 0, - ts - .createPrinter() - .printNode(ts.EmitHint.Unspecified, newImport, fileNamesToFiles.get(fileName)!) + - '\n', - ), - ); - }); - }); - - // Capture updated imports - for (const [oldBindings, newBindings] of updatedImports.entries()) { - result.addReplacement( - oldBindings.getSourceFile().fileName, - new Replacement( - oldBindings.getStart(), - oldBindings.getEnd(), - ts - .createPrinter() - .printNode(ts.EmitHint.Unspecified, newBindings, oldBindings.getSourceFile()), - ), - ); - } } } diff --git a/packages/core/schematics/migrations/signal-migration/src/phase_migrate.ts b/packages/core/schematics/migrations/signal-migration/src/phase_migrate.ts index c37bb9f1cd2..70ca1c8b16f 100644 --- a/packages/core/schematics/migrations/signal-migration/src/phase_migrate.ts +++ b/packages/core/schematics/migrations/signal-migration/src/phase_migrate.ts @@ -15,6 +15,8 @@ import {pass7__migrateTemplateReferences} from './passes/7_migrate_template_refe import {pass8__migrateHostBindings} from './passes/8_migrate_host_bindings'; import {pass9__migrateTypeScriptTypeReferences} from './passes/9_migrate_ts_type_references'; import {MigrationResult} from './result'; +import {pass10_applyImportManager} from './passes/10_apply_import_manager'; +import {ImportManager} from '../../../../../compiler-cli/src/ngtsc/translator'; /** * Executes the migration phase. @@ -29,12 +31,19 @@ export function executeMigrationPhase( host: MigrationHost, knownInputs: KnownInputs, result: MigrationResult, - {typeChecker}: AnalysisProgramInfo, + {typeChecker, sourceFiles}: AnalysisProgramInfo, ) { + const importManager = new ImportManager({ + // For the purpose of this migration, we always use `input` and don't alias + // it to e.g. `input_1`. + generateUniqueIdentifier: () => null, + }); + // Migrate passes. pass5__migrateTypeScriptReferences(result, typeChecker, knownInputs); - pass6__migrateInputDeclarations(host, typeChecker, result, knownInputs); + pass6__migrateInputDeclarations(host, typeChecker, result, knownInputs, importManager); pass7__migrateTemplateReferences(host, result, knownInputs); pass8__migrateHostBindings(result, knownInputs); - pass9__migrateTypeScriptTypeReferences(result, knownInputs); + pass9__migrateTypeScriptTypeReferences(result, knownInputs, importManager); + pass10_applyImportManager(importManager, result, sourceFiles); } diff --git a/packages/core/schematics/migrations/signal-migration/test/golden.txt b/packages/core/schematics/migrations/signal-migration/test/golden.txt index ab8e180bc59..0e0fb8d1d46 100644 --- a/packages/core/schematics/migrations/signal-migration/test/golden.txt +++ b/packages/core/schematics/migrations/signal-migration/test/golden.txt @@ -2,7 +2,7 @@ // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; @@ -27,7 +27,7 @@ it('should work', () => { // tslint:disable -import {Directive, Input, input} from '@angular/core'; +import { Directive, Input, input } from '@angular/core'; class BaseNonAngular { disabled: string = ''; @@ -78,7 +78,7 @@ class BothInputImported { import { UnwrapSignalInputs } from "google3/javascript/angular2/testing/catalyst"; // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; // angular2/testing/catalyst // ^^ this allows the advisor to even consider this file. @@ -101,7 +101,7 @@ it('should work', () => { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: ` @@ -173,7 +173,7 @@ class DerivedExternal extends Base2 { // tslint:disable -import {input, Directive, Component} from '@angular/core'; +import { Directive, Component, input } from '@angular/core'; // Material form field test case @@ -222,7 +222,7 @@ export class MatFormFieldTest { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class ExistingSignalImport { signalInput = input(); @@ -254,7 +254,7 @@ export class WithGetters { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: '', @@ -307,7 +307,7 @@ class HostBindingsShared2 { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; const complex = 'some global variable'; @@ -356,7 +356,7 @@ class MyComp { // tslint:disable -import {Component, Input, input} from '@angular/core'; +import { Component, Input, input } from '@angular/core'; interface Vehicle {} interface Car extends Vehicle { @@ -492,7 +492,7 @@ x.incompatible = null; // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({template: ''}) class IndexAccessInput { @@ -549,7 +549,7 @@ describe('bla', () => { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: ` @@ -564,7 +564,7 @@ export class InlineTmpl { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class MyTestCmp { someInput = input.required(); @@ -610,7 +610,7 @@ export class ManualInstantiation { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; export class TestCmp { shared = input<{ @@ -632,7 +632,7 @@ export class TestCmp { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; interface Config { bla?: string; @@ -652,7 +652,7 @@ export class NestedTemplatePropAccess { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({}) export class ObjectExpansion { @@ -684,7 +684,7 @@ function assertValidLoadingInput(dir: AppComponent) { // tslint:disable -import {Directive, input} from '@angular/core'; +import { Directive, input } from '@angular/core'; @Directive() class OptionalInput { @@ -729,7 +729,7 @@ export const COMPLEX_VAR = { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; import {COMPLEX_VAR} from './required-no-explicit-type-extra'; export const CONST = {field: true}; @@ -746,7 +746,7 @@ export class RequiredNoExplicitType { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class Required { simpleInput = input.required(); @@ -755,7 +755,7 @@ class Required { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; export class TestCmp { shared = input(false); @@ -777,7 +777,7 @@ export class TestCmp { // tslint:disable -import {input, Directive, Component} from '@angular/core'; +import { Directive, Component, input } from '@angular/core'; @Directive() class SomeDir { @@ -882,7 +882,7 @@ export class MyComp { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: ` @@ -900,7 +900,7 @@ export class TemplateObjectShorthand { // tslint:disable -import {Component, Input, input} from '@angular/core'; +import { Component, Input, input } from '@angular/core'; @Component({ template: ` @@ -922,7 +922,7 @@ class TwoWayBinding { // tslint:disable -import {Input, input} from '@angular/core'; +import { Input, input } from '@angular/core'; import {COMPLEX_VAR} from './required-no-explicit-type-extra'; function x(v: string | undefined): string | undefined { @@ -946,7 +946,7 @@ export class TransformFunctions { // tslint:disable -import {Directive, input} from '@angular/core'; +import { Directive, input } from '@angular/core'; // see: button-base Material. @@ -959,7 +959,7 @@ class TransformIncompatibleTypes { // tslint:disable -import {Input, input} from '@angular/core'; +import { Input, input } from '@angular/core'; export class WithSettersAndGetters { @Input() @@ -1001,7 +1001,7 @@ class WithGettersExternalRef { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class WithJsdoc { /** diff --git a/packages/core/schematics/migrations/signal-migration/test/golden_best_effort.txt b/packages/core/schematics/migrations/signal-migration/test/golden_best_effort.txt index f2a7760d4d0..f6a75c14f90 100644 --- a/packages/core/schematics/migrations/signal-migration/test/golden_best_effort.txt +++ b/packages/core/schematics/migrations/signal-migration/test/golden_best_effort.txt @@ -2,7 +2,7 @@ // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; @@ -27,7 +27,7 @@ it('should work', () => { // tslint:disable -import {Directive, input} from '@angular/core'; +import { Directive, input } from '@angular/core'; class BaseNonAngular { disabled: string = ''; @@ -61,7 +61,7 @@ class Sub3 implements BaseNonAngularInterface { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class BothInputImported { decoratorInput = input(true); @@ -78,7 +78,7 @@ class BothInputImported { import { UnwrapSignalInputs } from "google3/javascript/angular2/testing/catalyst"; // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; // angular2/testing/catalyst // ^^ this allows the advisor to even consider this file. @@ -101,7 +101,7 @@ it('should work', () => { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: ` @@ -128,7 +128,7 @@ class Option { // tslint:disable -import {input, Directive} from '@angular/core'; +import { Directive, input } from '@angular/core'; @Directive() class Base { @@ -148,7 +148,7 @@ export class Base2 { // tslint:disable -import {input, Directive} from '@angular/core'; +import { Directive, input } from '@angular/core'; @Directive() class Base { @@ -173,7 +173,7 @@ class DerivedExternal extends Base2 { // tslint:disable -import {input, Directive, Component} from '@angular/core'; +import { Directive, Component, input } from '@angular/core'; // Material form field test case @@ -222,7 +222,7 @@ export class MatFormFieldTest { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class ExistingSignalImport { signalInput = input(); @@ -254,7 +254,7 @@ export class WithGetters { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: '', @@ -307,7 +307,7 @@ class HostBindingsShared2 { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; const complex = 'some global variable'; @@ -356,7 +356,7 @@ class MyComp { // tslint:disable -import {Component, Input, input} from '@angular/core'; +import { Component, Input, input } from '@angular/core'; interface Vehicle {} interface Car extends Vehicle { @@ -492,7 +492,7 @@ x.incompatible = null; // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({template: ''}) class IndexAccessInput { @@ -549,7 +549,7 @@ describe('bla', () => { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: ` @@ -564,7 +564,7 @@ export class InlineTmpl { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class MyTestCmp { someInput = input.required(); @@ -610,7 +610,7 @@ export class ManualInstantiation { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; export class TestCmp { shared = input<{ @@ -632,7 +632,7 @@ export class TestCmp { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; interface Config { bla?: string; @@ -652,7 +652,7 @@ export class NestedTemplatePropAccess { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({}) export class ObjectExpansion { @@ -684,7 +684,7 @@ function assertValidLoadingInput(dir: AppComponent) { // tslint:disable -import {Directive, input} from '@angular/core'; +import { Directive, input } from '@angular/core'; @Directive() class OptionalInput { @@ -694,7 +694,7 @@ class OptionalInput { // tslint:disable -import {Component, Directive, QueryList, input} from '@angular/core'; +import { Component, Directive, QueryList, input } from '@angular/core'; @Component({ template: ` @@ -729,7 +729,7 @@ export const COMPLEX_VAR = { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; import {COMPLEX_VAR} from './required-no-explicit-type-extra'; export const CONST = {field: true}; @@ -746,7 +746,7 @@ export class RequiredNoExplicitType { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class Required { simpleInput = input.required(); @@ -755,7 +755,7 @@ class Required { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; export class TestCmp { shared = input(false); @@ -777,7 +777,7 @@ export class TestCmp { // tslint:disable -import {input, Directive, Component} from '@angular/core'; +import { Directive, Component, input } from '@angular/core'; @Directive() class SomeDir { @@ -846,7 +846,7 @@ spyOn(new MyComp(), 'myInput').and.returnValue(); // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: ` @@ -882,7 +882,7 @@ export class MyComp { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: ` @@ -900,7 +900,7 @@ export class TemplateObjectShorthand { // tslint:disable -import {Component, input} from '@angular/core'; +import { Component, input } from '@angular/core'; @Component({ template: ` @@ -922,7 +922,7 @@ class TwoWayBinding { // tslint:disable -import {Input, input} from '@angular/core'; +import { Input, input } from '@angular/core'; import {COMPLEX_VAR} from './required-no-explicit-type-extra'; function x(v: string | undefined): string | undefined { @@ -946,7 +946,7 @@ export class TransformFunctions { // tslint:disable -import {Directive, input} from '@angular/core'; +import { Directive, input } from '@angular/core'; // see: button-base Material. @@ -959,7 +959,7 @@ class TransformIncompatibleTypes { // tslint:disable -import {Input, input} from '@angular/core'; +import { Input, input } from '@angular/core'; export class WithSettersAndGetters { @Input() @@ -1001,7 +1001,7 @@ class WithGettersExternalRef { // tslint:disable -import {input} from '@angular/core'; +import { input } from '@angular/core'; class WithJsdoc { /**