forked from rollup/rollup
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVariableDeclarator.ts
101 lines (93 loc) · 3.41 KB
/
VariableDeclarator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import type MagicString from 'magic-string';
import { BLANK } from '../../utils/blank';
import { isReassignedExportsMember } from '../../utils/reassignedExportsMember';
import {
findFirstOccurrenceOutsideComment,
findNonWhiteSpace,
type RenderOptions
} from '../../utils/renderHelpers';
import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import type { ObjectPath } from '../utils/PathTracker';
import { UNDEFINED_EXPRESSION } from '../values';
import ClassExpression from './ClassExpression';
import Identifier from './Identifier';
import * as NodeType from './NodeType';
import { type ExpressionNode, type IncludeChildren, NodeBase } from './shared/Node';
import type { PatternNode } from './shared/Pattern';
import type { VariableKind } from './shared/VariableKinds';
export default class VariableDeclarator extends NodeBase {
declare id: PatternNode;
declare init: ExpressionNode | null;
declare type: NodeType.tVariableDeclarator;
declare isUsingDeclaration: boolean;
declareDeclarator(kind: VariableKind, isUsingDeclaration: boolean): void {
this.isUsingDeclaration = isUsingDeclaration;
this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
}
deoptimizePath(path: ObjectPath): void {
this.id.deoptimizePath(path);
}
hasEffects(context: HasEffectsContext): boolean {
if (!this.deoptimized) this.applyDeoptimizations();
const initEffect = this.init?.hasEffects(context);
this.id.markDeclarationReached();
return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
}
include(context: InclusionContext, includeChildrenRecursively: IncludeChildren): void {
const { deoptimized, id, init } = this;
if (!deoptimized) this.applyDeoptimizations();
this.included = true;
init?.include(context, includeChildrenRecursively);
id.markDeclarationReached();
if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
id.include(context, includeChildrenRecursively);
}
}
removeAnnotations(code: MagicString) {
this.init?.removeAnnotations(code);
}
render(code: MagicString, options: RenderOptions): void {
const {
exportNamesByVariable,
snippets: { _, getPropertyAccess }
} = options;
const { end, id, init, start } = this;
const renderId = id.included || this.isUsingDeclaration;
if (renderId) {
id.render(code, options);
} else {
const operatorPos = findFirstOccurrenceOutsideComment(code.original, '=', id.end);
code.remove(start, findNonWhiteSpace(code.original, operatorPos + 1));
}
if (init) {
if (id instanceof Identifier && init instanceof ClassExpression && !init.id) {
const renderedVariable = id.variable!.getName(getPropertyAccess);
if (renderedVariable !== id.name) {
code.appendLeft(init.start + 5, ` ${id.name}`);
}
}
init.render(
code,
options,
renderId ? BLANK : { renderedSurroundingElement: NodeType.ExpressionStatement }
);
} else if (
id instanceof Identifier &&
isReassignedExportsMember(id.variable!, exportNamesByVariable)
) {
code.appendLeft(end, `${_}=${_}void 0`);
}
}
protected applyDeoptimizations() {
this.deoptimized = true;
const { id, init } = this;
if (init && id instanceof Identifier && init instanceof ClassExpression && !init.id) {
const { name, variable } = id;
for (const accessedVariable of init.scope.accessedOutsideVariables.values()) {
if (accessedVariable !== variable) {
accessedVariable.forbidName(name);
}
}
}
}
}