Skip to content

Commit

Permalink
feat(schematics): add createEffect migration schematic (#2136)
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver authored and brandonroberts committed Oct 8, 2019
1 parent de07805 commit 9eb1bd5
Show file tree
Hide file tree
Showing 22 changed files with 916 additions and 176 deletions.
81 changes: 59 additions & 22 deletions modules/data/schematics-core/utility/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
NoopChange,
createReplaceChange,
ReplaceChange,
RemoveChange,
createRemoveChange,
} from './change';
import { Path } from '@angular-devkit/core';

Expand Down Expand Up @@ -650,7 +652,7 @@ export function replaceImport(
importFrom: string,
importAsIs: string,
importToBe: string
): ReplaceChange[] {
): (ReplaceChange | RemoveChange)[] {
const imports = sourceFile.statements
.filter(ts.isImportDeclaration)
.filter(
Expand All @@ -663,32 +665,67 @@ export function replaceImport(
return [];
}

const changes = imports
.map(p => (p.importClause!.namedBindings! as ts.NamedImports).elements)
.reduce((imports, curr) => imports.concat(curr), [] as ts.ImportSpecifier[])
.map(specifier => {
if (!ts.isImportSpecifier(specifier)) {
return { hit: false };
const importText = (specifier: ts.ImportSpecifier) => {
if (specifier.name.text) {
return specifier.name.text;
}

// if import is renamed
if (specifier.propertyName && specifier.propertyName.text) {
return specifier.propertyName.text;
}

return '';
};

const changes = imports.map(p => {
const importSpecifiers = (p.importClause!.namedBindings! as ts.NamedImports)
.elements;

const isAlreadyImported = importSpecifiers
.map(importText)
.includes(importToBe);

const importChanges = importSpecifiers.map((specifier, index) => {
const text = importText(specifier);

// import is not the one we're looking for, can be skipped
if (text !== importAsIs) {
return undefined;
}

if (specifier.name.text === importAsIs) {
return { hit: true, specifier, text: specifier.name.text };
// identifier has not been imported, simply replace the old text with the new text
if (!isAlreadyImported) {
return createReplaceChange(
sourceFile,
specifier!,
importAsIs,
importToBe
);
}

// if import is renamed
if (
specifier.propertyName &&
specifier.propertyName.text === importAsIs
) {
return { hit: true, specifier, text: specifier.propertyName.text };
const nextIdentifier = importSpecifiers[index + 1];
// identifer is not the last, also clean up the comma
if (nextIdentifier) {
return createRemoveChange(
sourceFile,
specifier,
specifier.getStart(sourceFile),
nextIdentifier.getStart(sourceFile)
);
}

return { hit: false };
})
.filter(({ hit }) => hit)
.map(({ specifier, text }) =>
createReplaceChange(sourceFile, specifier!, text!, importToBe)
);
// there are no imports following, just remove it
return createRemoveChange(
sourceFile,
specifier,
specifier.getStart(sourceFile),
specifier.getEnd()
);
});

return importChanges.filter(Boolean) as (ReplaceChange | RemoveChange)[];
});

return changes;
return changes.reduce((imports, curr) => imports.concat(curr), []);
}
9 changes: 9 additions & 0 deletions modules/data/schematics-core/utility/change.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ export function createReplaceChange(
);
}

export function createRemoveChange(
sourceFile: ts.SourceFile,
node: ts.Node,
from = node.getStart(sourceFile),
to = node.getEnd()
): RemoveChange {
return new RemoveChange(sourceFile.fileName, from, to);
}

export function createChangeRecorder(
tree: Tree,
path: string,
Expand Down
81 changes: 59 additions & 22 deletions modules/effects/schematics-core/utility/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
NoopChange,
createReplaceChange,
ReplaceChange,
RemoveChange,
createRemoveChange,
} from './change';
import { Path } from '@angular-devkit/core';

Expand Down Expand Up @@ -650,7 +652,7 @@ export function replaceImport(
importFrom: string,
importAsIs: string,
importToBe: string
): ReplaceChange[] {
): (ReplaceChange | RemoveChange)[] {
const imports = sourceFile.statements
.filter(ts.isImportDeclaration)
.filter(
Expand All @@ -663,32 +665,67 @@ export function replaceImport(
return [];
}

const changes = imports
.map(p => (p.importClause!.namedBindings! as ts.NamedImports).elements)
.reduce((imports, curr) => imports.concat(curr), [] as ts.ImportSpecifier[])
.map(specifier => {
if (!ts.isImportSpecifier(specifier)) {
return { hit: false };
const importText = (specifier: ts.ImportSpecifier) => {
if (specifier.name.text) {
return specifier.name.text;
}

// if import is renamed
if (specifier.propertyName && specifier.propertyName.text) {
return specifier.propertyName.text;
}

return '';
};

const changes = imports.map(p => {
const importSpecifiers = (p.importClause!.namedBindings! as ts.NamedImports)
.elements;

const isAlreadyImported = importSpecifiers
.map(importText)
.includes(importToBe);

const importChanges = importSpecifiers.map((specifier, index) => {
const text = importText(specifier);

// import is not the one we're looking for, can be skipped
if (text !== importAsIs) {
return undefined;
}

if (specifier.name.text === importAsIs) {
return { hit: true, specifier, text: specifier.name.text };
// identifier has not been imported, simply replace the old text with the new text
if (!isAlreadyImported) {
return createReplaceChange(
sourceFile,
specifier!,
importAsIs,
importToBe
);
}

// if import is renamed
if (
specifier.propertyName &&
specifier.propertyName.text === importAsIs
) {
return { hit: true, specifier, text: specifier.propertyName.text };
const nextIdentifier = importSpecifiers[index + 1];
// identifer is not the last, also clean up the comma
if (nextIdentifier) {
return createRemoveChange(
sourceFile,
specifier,
specifier.getStart(sourceFile),
nextIdentifier.getStart(sourceFile)
);
}

return { hit: false };
})
.filter(({ hit }) => hit)
.map(({ specifier, text }) =>
createReplaceChange(sourceFile, specifier!, text!, importToBe)
);
// there are no imports following, just remove it
return createRemoveChange(
sourceFile,
specifier,
specifier.getStart(sourceFile),
specifier.getEnd()
);
});

return importChanges.filter(Boolean) as (ReplaceChange | RemoveChange)[];
});

return changes;
return changes.reduce((imports, curr) => imports.concat(curr), []);
}
9 changes: 9 additions & 0 deletions modules/effects/schematics-core/utility/change.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ export function createReplaceChange(
);
}

export function createRemoveChange(
sourceFile: ts.SourceFile,
node: ts.Node,
from = node.getStart(sourceFile),
to = node.getEnd()
): RemoveChange {
return new RemoveChange(sourceFile.fileName, from, to);
}

export function createChangeRecorder(
tree: Tree,
path: string,
Expand Down
81 changes: 59 additions & 22 deletions modules/entity/schematics-core/utility/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
NoopChange,
createReplaceChange,
ReplaceChange,
RemoveChange,
createRemoveChange,
} from './change';
import { Path } from '@angular-devkit/core';

Expand Down Expand Up @@ -650,7 +652,7 @@ export function replaceImport(
importFrom: string,
importAsIs: string,
importToBe: string
): ReplaceChange[] {
): (ReplaceChange | RemoveChange)[] {
const imports = sourceFile.statements
.filter(ts.isImportDeclaration)
.filter(
Expand All @@ -663,32 +665,67 @@ export function replaceImport(
return [];
}

const changes = imports
.map(p => (p.importClause!.namedBindings! as ts.NamedImports).elements)
.reduce((imports, curr) => imports.concat(curr), [] as ts.ImportSpecifier[])
.map(specifier => {
if (!ts.isImportSpecifier(specifier)) {
return { hit: false };
const importText = (specifier: ts.ImportSpecifier) => {
if (specifier.name.text) {
return specifier.name.text;
}

// if import is renamed
if (specifier.propertyName && specifier.propertyName.text) {
return specifier.propertyName.text;
}

return '';
};

const changes = imports.map(p => {
const importSpecifiers = (p.importClause!.namedBindings! as ts.NamedImports)
.elements;

const isAlreadyImported = importSpecifiers
.map(importText)
.includes(importToBe);

const importChanges = importSpecifiers.map((specifier, index) => {
const text = importText(specifier);

// import is not the one we're looking for, can be skipped
if (text !== importAsIs) {
return undefined;
}

if (specifier.name.text === importAsIs) {
return { hit: true, specifier, text: specifier.name.text };
// identifier has not been imported, simply replace the old text with the new text
if (!isAlreadyImported) {
return createReplaceChange(
sourceFile,
specifier!,
importAsIs,
importToBe
);
}

// if import is renamed
if (
specifier.propertyName &&
specifier.propertyName.text === importAsIs
) {
return { hit: true, specifier, text: specifier.propertyName.text };
const nextIdentifier = importSpecifiers[index + 1];
// identifer is not the last, also clean up the comma
if (nextIdentifier) {
return createRemoveChange(
sourceFile,
specifier,
specifier.getStart(sourceFile),
nextIdentifier.getStart(sourceFile)
);
}

return { hit: false };
})
.filter(({ hit }) => hit)
.map(({ specifier, text }) =>
createReplaceChange(sourceFile, specifier!, text!, importToBe)
);
// there are no imports following, just remove it
return createRemoveChange(
sourceFile,
specifier,
specifier.getStart(sourceFile),
specifier.getEnd()
);
});

return importChanges.filter(Boolean) as (ReplaceChange | RemoveChange)[];
});

return changes;
return changes.reduce((imports, curr) => imports.concat(curr), []);
}
9 changes: 9 additions & 0 deletions modules/entity/schematics-core/utility/change.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ export function createReplaceChange(
);
}

export function createRemoveChange(
sourceFile: ts.SourceFile,
node: ts.Node,
from = node.getStart(sourceFile),
to = node.getEnd()
): RemoveChange {
return new RemoveChange(sourceFile.fileName, from, to);
}

export function createChangeRecorder(
tree: Tree,
path: string,
Expand Down
Loading

0 comments on commit 9eb1bd5

Please sign in to comment.