Skip to content

Commit c5d4695

Browse files
committed
Refactor
1 parent 09399e1 commit c5d4695

File tree

6 files changed

+243
-186
lines changed

6 files changed

+243
-186
lines changed

src/transform-visitor.ts

Lines changed: 25 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,43 @@ import * as angular from '@angular/compiler';
22
import type * as babel from '@babel/types';
33

44
import { type Transformer } from './transform-ast.ts';
5+
import { visitCall, visitSafeCall } from './transforms/transform-call.ts';
6+
import {
7+
visitKeyedRead,
8+
visitPropertyRead,
9+
visitSafeKeyedRead,
10+
visitSafePropertyRead,
11+
} from './transforms/transform-member-expression.ts';
12+
import {
13+
visitPrefixNot,
14+
visitTypeofExpression,
15+
visitUnary,
16+
visitVoidExpression,
17+
} from './transforms/transform-unary-expression.ts';
518
import type {
619
NGChainedExpression,
720
NGNode,
821
NGPipeExpression,
922
RawNGSpan,
1023
} from './types.ts';
1124

12-
function isParenthesized(node: NGNode) {
13-
return Boolean(node.extra?.parenthesized);
14-
}
15-
16-
function isOptionalObjectOrCallee(node: NGNode): boolean {
17-
if (node.type === 'TSNonNullExpression' && !isParenthesized(node)) {
18-
return isOptionalObjectOrCallee(node.expression);
19-
}
20-
21-
return (
22-
(node.type === 'OptionalCallExpression' ||
23-
node.type === 'OptionalMemberExpression') &&
24-
!isParenthesized(node)
25-
);
26-
}
27-
2825
type AstVisitor = Required<
2926
Omit<angular.AstVisitor, 'visit' | 'visitASTWithSource'>
3027
>;
3128

3229
export const transformVisitor: AstVisitor = {
33-
visitUnary(node: angular.Unary, transformer: Transformer) {
34-
return transformer.createNode<babel.UnaryExpression>({
35-
type: 'UnaryExpression',
36-
prefix: true,
37-
argument: transformer.transformChild<babel.Expression>(node.expr),
38-
operator: node.operator as '-' | '+',
39-
});
40-
},
30+
visitCall,
31+
visitSafeCall,
32+
33+
visitKeyedRead,
34+
visitPropertyRead,
35+
visitSafeKeyedRead,
36+
visitSafePropertyRead,
37+
38+
visitPrefixNot,
39+
visitTypeofExpression,
40+
visitVoidExpression,
41+
visitUnary,
4142

4243
visitBinary(node: angular.Binary, transformer: Transformer) {
4344
const { operation: operator } = node;
@@ -219,48 +220,6 @@ export const transformVisitor: AstVisitor = {
219220
});
220221
},
221222

222-
visitPrefixNot(node: angular.PrefixNot, transformer: Transformer) {
223-
return transformer.createNode<babel.UnaryExpression>(
224-
{
225-
type: 'UnaryExpression',
226-
prefix: true,
227-
operator: '!',
228-
argument: transformer.transformChild<babel.Expression>(node.expression),
229-
},
230-
node.sourceSpan,
231-
);
232-
},
233-
234-
visitTypeofExpression(
235-
node: angular.TypeofExpression,
236-
transformer: Transformer,
237-
) {
238-
return transformer.createNode<babel.UnaryExpression>(
239-
{
240-
type: 'UnaryExpression',
241-
prefix: true,
242-
operator: 'typeof',
243-
argument: transformer.transformChild<babel.Expression>(node.expression),
244-
},
245-
node.sourceSpan,
246-
);
247-
},
248-
249-
visitVoidExpression(
250-
node: angular.TypeofExpression,
251-
transformer: Transformer,
252-
) {
253-
return transformer.createNode<babel.UnaryExpression>(
254-
{
255-
type: 'UnaryExpression',
256-
prefix: true,
257-
operator: 'void',
258-
argument: transformer.transformChild<babel.Expression>(node.expression),
259-
},
260-
node.sourceSpan,
261-
);
262-
},
263-
264223
visitTaggedTemplateLiteral(
265224
node: angular.TaggedTemplateLiteral,
266225
transformer: Transformer,
@@ -314,36 +273,6 @@ export const transformVisitor: AstVisitor = {
314273
return transformer.transformChild(node.expression);
315274
},
316275

317-
visitKeyedRead(node: angular.KeyedRead, transformer: Transformer) {
318-
return transformMemberExpression(node, transformer, { computed: true });
319-
},
320-
321-
visitSafeKeyedRead(node: angular.SafeKeyedRead, transformer: Transformer) {
322-
return transformMemberExpression(node, transformer, {
323-
computed: true,
324-
optional: true,
325-
});
326-
},
327-
328-
visitPropertyRead(node: angular.PropertyRead, transformer: Transformer) {
329-
return transformMemberExpression(node, transformer);
330-
},
331-
332-
visitSafePropertyRead(
333-
node: angular.SafePropertyRead,
334-
transformer: Transformer,
335-
) {
336-
return transformMemberExpression(node, transformer, { optional: true });
337-
},
338-
339-
visitCall(node: angular.Call, transformer: Transformer) {
340-
return transformCall(node, transformer);
341-
},
342-
343-
visitSafeCall(node: angular.SafeCall, transformer: Transformer) {
344-
return transformCall(node, transformer, { optional: true });
345-
},
346-
347276
visitInterpolation(node: angular.Interpolation, transformer: Transformer) {
348277
const { expressions } = node;
349278

@@ -357,85 +286,3 @@ export const transformVisitor: AstVisitor = {
357286

358287
visitImplicitReceiver() {},
359288
};
360-
361-
function transformCall(
362-
node: angular.Call | angular.SafeCall,
363-
transformer: Transformer,
364-
{ optional = false } = {},
365-
) {
366-
const arguments_ = transformer.transformChildren<babel.Expression>(node.args);
367-
const callee = transformer.transformChild<babel.Expression>(node.receiver);
368-
const isOptionalReceiver = isOptionalObjectOrCallee(callee);
369-
const nodeType =
370-
optional || isOptionalReceiver
371-
? 'OptionalCallExpression'
372-
: 'CallExpression';
373-
return transformer.createNode<
374-
babel.CallExpression | babel.OptionalCallExpression
375-
>({
376-
type: nodeType,
377-
callee,
378-
arguments: arguments_,
379-
...(nodeType === 'OptionalCallExpression' ? { optional } : undefined),
380-
});
381-
}
382-
383-
function transformMemberExpression(
384-
node:
385-
| angular.KeyedRead
386-
| angular.SafeKeyedRead
387-
| angular.PropertyRead
388-
| angular.SafePropertyRead,
389-
transformer: Transformer,
390-
) {
391-
const { receiver } = node;
392-
const object = transformer.transformChild<babel.Expression>(receiver);
393-
const computed =
394-
node instanceof angular.KeyedRead || node instanceof angular.SafeKeyedRead;
395-
const optional =
396-
node instanceof angular.SafeKeyedRead ||
397-
node instanceof angular.SafePropertyRead;
398-
399-
let property;
400-
if (computed) {
401-
property = transformer.transformChild<babel.Expression>(node.key);
402-
} else {
403-
property = transformer.createNode<babel.Identifier>(
404-
{ type: 'Identifier', name: node.name },
405-
node.nameSpan,
406-
object ? [] : transformer.ancestors,
407-
);
408-
}
409-
410-
if (!object) {
411-
return property;
412-
}
413-
414-
const isOptionalObject = isOptionalObjectOrCallee(object);
415-
416-
if (optional || isOptionalObject) {
417-
return transformer.createNode<babel.OptionalMemberExpression>({
418-
type: 'OptionalMemberExpression',
419-
optional: optional || !isOptionalObject,
420-
computed,
421-
property,
422-
object,
423-
});
424-
}
425-
426-
if (computed) {
427-
return transformer.createNode<babel.MemberExpressionComputed>({
428-
type: 'MemberExpression',
429-
property,
430-
object,
431-
computed: true,
432-
});
433-
}
434-
435-
return transformer.createNode<babel.MemberExpressionNonComputed>({
436-
type: 'MemberExpression',
437-
object,
438-
property: property as babel.MemberExpressionNonComputed['property'],
439-
computed: false,
440-
});
441-
}

src/transform.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,7 @@ function transformAstResult({
1010
text,
1111
comments,
1212
}: AstParseResult) {
13-
try {
14-
return Object.assign(transformNode(ast, text), { comments });
15-
} catch {
16-
console.log({
17-
ast,
18-
es: transformNode(ast, text),
19-
});
20-
}
13+
return Object.assign(transformNode(ast, text), { comments });
2114
}
2215

2316
function transformMicrosyntaxResult({

src/transforms/transform-call.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { type Call, type SafeCall } from '@angular/compiler';
2+
import type * as babel from '@babel/types';
3+
4+
import { type Transformer } from '../transform-ast.ts';
5+
import { isOptionalObjectOrCallee } from './utilities.ts';
6+
7+
const callOptions = { optional: false } as const;
8+
const safeCallOptions = { optional: true } as const;
9+
10+
type VisitorCall = {
11+
node: Call;
12+
options: typeof callOptions;
13+
};
14+
type VisitorSafeCall = {
15+
node: SafeCall;
16+
options: typeof safeCallOptions;
17+
};
18+
19+
const transformCall =
20+
<Visitor extends VisitorCall | VisitorSafeCall>({
21+
optional,
22+
}: Visitor['options']) =>
23+
(node: Visitor['node'], transformer: Transformer) => {
24+
const arguments_ = transformer.transformChildren<babel.Expression>(
25+
node.args,
26+
);
27+
const callee = transformer.transformChild<babel.Expression>(node.receiver);
28+
const isOptionalReceiver = isOptionalObjectOrCallee(callee);
29+
const nodeType =
30+
optional || isOptionalReceiver
31+
? 'OptionalCallExpression'
32+
: 'CallExpression';
33+
return transformer.createNode<
34+
babel.CallExpression | babel.OptionalCallExpression
35+
>({
36+
type: nodeType,
37+
callee,
38+
arguments: arguments_,
39+
...(nodeType === 'OptionalCallExpression' ? { optional } : undefined),
40+
});
41+
};
42+
43+
export const visitCall = transformCall<VisitorCall>(callOptions);
44+
export const visitSafeCall = transformCall<VisitorSafeCall>(safeCallOptions);

0 commit comments

Comments
 (0)