refactor(compiler-cli): visit inline declarations with implementations differently (#39267)
Some inline declarations are of the form: ``` exports.<name> = <implementation>; ``` In this case the declaration `node` is `exports.<name>`. When interpreting such inline declarations we actually want to visit the `implementation` expression rather than visiting the declaration `node`. This commit adds `implementation?: ts.Expression` to the `InlineDeclaration` type and updates the interpreter to visit these expressions as described above. PR Close #39267
This commit is contained in:
parent
eb9eebbb45
commit
ac0016cd82
|
@ -11,7 +11,7 @@ import * as ts from 'typescript';
|
|||
import {Reference} from '../../imports';
|
||||
import {OwningModule} from '../../imports/src/references';
|
||||
import {DependencyTracker} from '../../incremental/api';
|
||||
import {Declaration, DeclarationNode, EnumMember, FunctionDefinition, isConcreteDeclaration, ReflectionHost, SpecialDeclarationKind} from '../../reflection';
|
||||
import {Declaration, DeclarationKind, DeclarationNode, EnumMember, FunctionDefinition, isConcreteDeclaration, ReflectionHost, SpecialDeclarationKind} from '../../reflection';
|
||||
import {isDeclaration} from '../../util/src/typescript';
|
||||
|
||||
import {ArrayConcatBuiltinFn, ArraySliceBuiltinFn} from './builtin';
|
||||
|
@ -231,7 +231,7 @@ export class StaticInterpreter {
|
|||
return this.getResolvedEnum(decl.node, decl.identity.enumMembers, context);
|
||||
}
|
||||
const declContext = {...context, ...joinModuleContext(context, node, decl)};
|
||||
const result = this.visitDeclaration(decl.node, declContext);
|
||||
const result = this.visitAmbiguousDeclaration(decl, declContext);
|
||||
if (result instanceof Reference) {
|
||||
// Only record identifiers to non-synthetic references. Synthetic references may not have the
|
||||
// same value at runtime as they do at compile time, so it's not legal to refer to them by the
|
||||
|
@ -337,10 +337,18 @@ export class StaticInterpreter {
|
|||
};
|
||||
|
||||
// Visit both concrete and inline declarations.
|
||||
return this.visitDeclaration(decl.node, declContext);
|
||||
return this.visitAmbiguousDeclaration(decl, declContext);
|
||||
});
|
||||
}
|
||||
|
||||
private visitAmbiguousDeclaration(decl: Declaration, declContext: Context) {
|
||||
return decl.kind === DeclarationKind.Inline && decl.implementation !== undefined ?
|
||||
// Inline declarations with an `implementation` should be visited as expressions
|
||||
this.visitExpression(decl.implementation, declContext) :
|
||||
// Otherwise just visit the declaration `node`
|
||||
this.visitDeclaration(decl.node, declContext);
|
||||
}
|
||||
|
||||
private accessHelper(node: ts.Node, lhs: ResolvedValue, rhs: string|number, context: Context):
|
||||
ResolvedValue {
|
||||
const strIndex = `${rhs}`;
|
||||
|
|
|
@ -625,6 +625,7 @@ export interface DownleveledEnum {
|
|||
export interface InlineDeclaration extends
|
||||
BaseDeclaration<Exclude<DeclarationNode, ts.Declaration>> {
|
||||
kind: DeclarationKind.Inline;
|
||||
implementation?: ts.Expression;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue