Skip to content

Commit f9b4b79

Browse files
committed
Clean up index.ts and parse-helper.ts
1 parent d1f595f commit f9b4b79

11 files changed

Lines changed: 268 additions & 221 deletions

File tree

transforms/ember-object/index.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
import { getOptions } from 'codemod-cli';
22
import type { Transform } from 'jscodeshift';
33
import path from 'path';
4-
import type { Options } from '../helpers/options';
4+
import type { UserOptions } from '../helpers/options';
55
import { DEFAULT_OPTIONS } from '../helpers/options';
6-
import { replaceEmberObjectExpressions } from '../helpers/parse-helper';
6+
import maybeTransformEmberObjects from '../helpers/transform';
77
import { isRecord, verified } from '../helpers/util/types';
88

9-
const transformer: Transform = function (file, api) {
10-
const extension = path.extname(file.path);
11-
9+
const transformer: Transform = function (
10+
{ source, path: filePath },
11+
{ jscodeshift: j }
12+
) {
13+
const extension = path.extname(filePath);
1214
if (!['.js', '.ts'].includes(extension.toLowerCase())) {
1315
// do nothing on non-js/ts files
1416
return;
1517
}
1618

17-
const j = api.jscodeshift;
18-
const options = {
19+
const userOptions: UserOptions = {
1920
...DEFAULT_OPTIONS,
20-
...verified<Partial<Options>>(getOptions(), isRecord),
21+
...verified<Partial<UserOptions>>(getOptions(), isRecord),
2122
};
22-
let { source } = file;
23-
2423
const root = j(source);
24+
const replaced = maybeTransformEmberObjects(j, root, filePath, userOptions);
2525

26-
const replaced = replaceEmberObjectExpressions(j, root, file.path, options);
2726
if (replaced) {
2827
source = root.toSource({
29-
quote: options.quotes ?? options.quote,
28+
quote: userOptions.quotes ?? userOptions.quote,
3029
});
3130
}
31+
3232
return source;
3333
};
3434

transforms/helpers/decorator-info.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,27 @@ import type { ImportSpecifier } from 'jscodeshift';
22
import { assert } from './util/types';
33
import { METHOD_DECORATORS } from './util/index';
44

5-
export interface DecoratorInfo {
5+
export interface DecoratorImportInfo {
66
name: 'unobserves' | 'off' | 'className' | 'attribute' | string;
77
importedName?: 'computed' | string;
88
isImportedAs?: boolean;
99
isMetaDecorator?: boolean;
1010
isMethodDecorator?: boolean;
1111
localName?: string;
1212
}
13-
14-
export type ImportPropDecoratorMap = Record<string, DecoratorInfo>;
13+
export type DecoratorImportInfoMap = Map<
14+
/** local name */ string,
15+
DecoratorImportInfo
16+
>;
1517

1618
/**
1719
* Return the decorator name for the specifier if any, using the importPropDecoratorMap from
1820
* `DECORATOR_PATHS` config (defined util.js)
1921
*/
20-
export function getDecoratorInfo(
22+
export function getDecoratorImportInfo(
2123
specifier: ImportSpecifier,
2224
importPropDecoratorMap: Record<string, string> | undefined
23-
): DecoratorInfo {
25+
): DecoratorImportInfo {
2426
const localName = specifier.local?.name;
2527
const importedName = specifier.imported.name;
2628
const isImportedAs = importedName !== localName;

transforms/helpers/eo-prop/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Property } from 'jscodeshift';
2-
import type { ImportPropDecoratorMap } from '../decorator-info';
2+
import type { DecoratorImportInfoMap } from '../decorator-info';
33
import type { RuntimeData } from '../runtime-data';
44
import { assert } from '../util/types';
55
import EOActionsObjectProp, {
@@ -41,13 +41,13 @@ export interface EOProps {
4141
export default function makeEOProp(
4242
eoProp: Property,
4343
runtimeData: RuntimeData | undefined,
44-
importedDecoratedProps: ImportPropDecoratorMap
44+
existingDecoratorImportInfos: DecoratorImportInfoMap
4545
): EOProp {
4646
if (isCallExpressionProperty(eoProp)) {
4747
return new EOCallExpressionProp(
4848
eoProp,
4949
runtimeData,
50-
importedDecoratedProps
50+
existingDecoratorImportInfos
5151
);
5252
} else if (isFunctionExpressionProperty(eoProp)) {
5353
return new EOFunctionExpressionProp(eoProp, runtimeData);

transforms/helpers/eo-prop/private/abstract.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Property } from 'jscodeshift';
2-
import type { DecoratorInfo } from '../../decorator-info';
2+
import type { DecoratorImportInfo } from '../../decorator-info';
33
import type { RuntimeData } from '../../runtime-data';
44
import { getPropName } from '../../util/index';
55

@@ -19,7 +19,7 @@ export default abstract class AbstractEOProp<
1919
> {
2020
readonly _prop: P;
2121

22-
protected readonly decorators: DecoratorInfo[] = [];
22+
protected readonly decorators: DecoratorImportInfo[] = [];
2323
readonly decoratorArgs: EODecoratorArgs = {};
2424

2525
/** Runtime Data */

transforms/helpers/eo-prop/private/call-expression.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { CallExpression, Identifier, Property } from 'jscodeshift';
2-
import type { ImportPropDecoratorMap } from '../../decorator-info';
2+
import type { DecoratorImportInfoMap } from '../../decorator-info';
33
import type { RuntimeData } from '../../runtime-data';
44
import { assert, isString, verified } from '../../util/types';
55
import AbstractEOProp from './abstract';
@@ -46,7 +46,7 @@ export default class EOCallExpressionProp extends AbstractEOProp<
4646
constructor(
4747
eoProp: CallExpressionProperty,
4848
runtimeData: RuntimeData | undefined,
49-
importedDecoratedProps: ImportPropDecoratorMap
49+
existingDecoratorImportInfos: DecoratorImportInfoMap
5050
) {
5151
super(eoProp, runtimeData);
5252

@@ -64,9 +64,11 @@ export default class EOCallExpressionProp extends AbstractEOProp<
6464
this.modifiers = modifiers.reverse();
6565
this.modifiers.shift();
6666

67-
const decoratorInfo = importedDecoratedProps[this.calleeName];
68-
if (decoratorInfo) {
69-
this.decorators.push(decoratorInfo);
67+
const decoratorImportInfo = existingDecoratorImportInfos.get(
68+
this.calleeName
69+
);
70+
if (decoratorImportInfo) {
71+
this.decorators.push(decoratorImportInfo);
7072
} else if (this.isComputed) {
7173
this.decorators.push({ name: this.calleeName });
7274
}

transforms/helpers/import-helper.ts

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import type {
55
ImportSpecifier,
66
JSCodeshift,
77
} from 'jscodeshift';
8-
import type { ImportPropDecoratorMap } from './decorator-info';
9-
import { getDecoratorInfo } from './decorator-info';
10-
import { DEFAULT_OPTIONS } from './options';
8+
import type { DecoratorImportInfoMap } from './decorator-info';
9+
import { getDecoratorImportInfo } from './decorator-info';
10+
import type { Options } from './options';
1111
import {
1212
createEmberDecoratorSpecifiers,
1313
createImportDeclaration,
@@ -99,8 +99,8 @@ function createNewImportDeclarations(
9999
root: Collection<unknown>,
100100
decoratorsToImport: string[],
101101
/** Already imported paths */
102-
decoratorPathsToIgnore: string[] = [],
103-
options = DEFAULT_OPTIONS
102+
decoratorPathsToIgnore: string[],
103+
options: Options
104104
): void {
105105
const firstDeclaration = getFirstDeclaration(j, root);
106106

@@ -263,8 +263,8 @@ function getExistingImportForPath(
263263
export function createDecoratorImportDeclarations(
264264
j: JSCodeshift,
265265
root: Collection<unknown>,
266-
decoratorsToImport: string[] = [],
267-
options = DEFAULT_OPTIONS
266+
decoratorsToImport: string[],
267+
options: Options
268268
): void {
269269
// Iterate through existing imports, extract the already imported specifiers
270270
const decoratorPathSpecifierMap = getDecoratorPathSpecifiers(
@@ -304,13 +304,40 @@ export function createDecoratorImportDeclarations(
304304
);
305305
}
306306

307-
/** Get decorated props from `import` statements */
308-
export function getImportedDecoratedProps(
307+
/**
308+
* Get decorator import info from `import` statements
309+
*
310+
* e.g. For these imports:
311+
* `import { observer as watcher, computed } from '@ember/object';`
312+
*
313+
* The returned value will be:
314+
* ```
315+
* {
316+
* watcher: {
317+
* name: "watcher",
318+
* importedName: "observer",
319+
* isImportedAs: true,
320+
* isMetaDecorator: false,
321+
* isMethodDecorator: true,
322+
* localName: "watcher",
323+
* },
324+
* computed: {
325+
* name: "computed",
326+
* importedName: "computed",
327+
* isImportedAs: false,
328+
* isMetaDecorator: false,
329+
* isMethodDecorator: false,
330+
* localName: "computed",
331+
* }
332+
* }
333+
* ```
334+
*/
335+
export function getDecoratorImportInfos(
309336
j: JSCodeshift,
310337
root: Collection<unknown>
311-
): ImportPropDecoratorMap {
338+
): DecoratorImportInfoMap {
312339
const existingDecoratorImports = getExistingDecoratorImports(j, root);
313-
const importedDecorators: ImportPropDecoratorMap = {};
340+
const decoratorImportInfo: DecoratorImportInfoMap = new Map();
314341

315342
for (const decoratorImport of existingDecoratorImports) {
316343
const { importPropDecoratorMap } = defined(
@@ -325,13 +352,13 @@ export function getImportedDecoratedProps(
325352
if (isSpecifierDecorator(specifier, importPropDecoratorMap)) {
326353
const localName = specifier.local?.name;
327354
assert(localName, 'expected localName');
328-
importedDecorators[localName] = getDecoratorInfo(
329-
specifier,
330-
importPropDecoratorMap
355+
decoratorImportInfo.set(
356+
localName,
357+
getDecoratorImportInfo(specifier, importPropDecoratorMap)
331358
);
332359
}
333360
}
334361
}
335362

336-
return importedDecorators;
363+
return decoratorImportInfo;
337364
}

transforms/helpers/options.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { RuntimeData } from './runtime-data';
22

3-
export interface Options {
3+
export interface UserOptions {
44
/** Enable/disable transformation using decorators */
55
decorators: boolean;
66
/** Enable/disable transformation using class fields */
@@ -12,11 +12,16 @@ export interface Options {
1212
quotes?: 'single' | 'double';
1313
/** Apply transformation to only passed type. */
1414
type?: 'services' | 'routes' | 'components' | 'controllers';
15+
}
16+
17+
export interface PrivateOptions {
1518
/** @private */
16-
runtimeData?: RuntimeData | undefined;
19+
runtimeData: RuntimeData | undefined;
1720
}
1821

19-
export const DEFAULT_OPTIONS: Options = {
22+
export type Options = UserOptions & PrivateOptions;
23+
24+
export const DEFAULT_OPTIONS: UserOptions = {
2025
decorators: true,
2126
classFields: true,
2227
classicDecorator: true,

0 commit comments

Comments
 (0)