fix(ivy): evaluate external declaration usages as dynamic (#30247)
Previously, ngtsc would fail to evaluate expressions that access properties from e.g. the `window` object. This resulted in hard to debug error messages as no indication on where the problem originated was present in the output. This commit cleans up the handling of unknown property accesses, such that evaluating such expressions no longer fail but instead result in a `DynamicValue`. Fixes #30226 PR Close #30247
This commit is contained in:
parent
3f7e823b80
commit
1b613c3ebf
|
@ -32,7 +32,8 @@ export const enum DynamicValueReason {
|
|||
|
||||
/**
|
||||
* An external reference could not be resolved to a value which can be evaluated.
|
||||
* (E.g. a call expression for a function declared in `.d.ts`.)
|
||||
* For example a call expression for a function declared in `.d.ts`, or accessing native globals
|
||||
* such as `window`.
|
||||
*/
|
||||
EXTERNAL_REFERENCE,
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import * as ts from 'typescript';
|
|||
import {Reference} from '../../imports';
|
||||
import {OwningModule} from '../../imports/src/references';
|
||||
import {Declaration, ReflectionHost} from '../../reflection';
|
||||
import {isDeclaration} from '../../util/src/typescript';
|
||||
|
||||
import {ArrayConcatBuiltinFn, ArraySliceBuiltinFn} from './builtin';
|
||||
import {DynamicValue} from './dynamic';
|
||||
|
@ -361,12 +362,15 @@ export class StaticInterpreter {
|
|||
}
|
||||
}
|
||||
return value;
|
||||
} else if (isDeclaration(ref)) {
|
||||
return DynamicValue.fromDynamicInput(
|
||||
node, DynamicValue.fromExternalReference(ref, lhs as Reference<ts.Declaration>));
|
||||
}
|
||||
} else if (lhs instanceof DynamicValue) {
|
||||
return DynamicValue.fromDynamicInput(node, lhs);
|
||||
} else {
|
||||
throw new Error(`Invalid dot property access: ${lhs} dot ${rhs}`);
|
||||
}
|
||||
|
||||
return DynamicValue.fromUnknown(node);
|
||||
}
|
||||
|
||||
private visitCallExpression(node: ts.CallExpression, context: Context): ResolvedValue {
|
||||
|
|
|
@ -122,6 +122,20 @@ describe('ngtsc metadata', () => {
|
|||
expect(evaluate(`const x = 3;`, '!!x')).toEqual(true);
|
||||
});
|
||||
|
||||
it('resolves access from external variable declarations as dynamic value', () => {
|
||||
const value = evaluate('declare const window: any;', 'window.location');
|
||||
if (!(value instanceof DynamicValue)) {
|
||||
return fail(`Should have resolved to a DynamicValue`);
|
||||
}
|
||||
expect(value.isFromDynamicInput()).toEqual(true);
|
||||
expect(value.node.getText()).toEqual('window.location');
|
||||
if (!(value.reason instanceof DynamicValue)) {
|
||||
return fail(`Should have a DynamicValue as reason`);
|
||||
}
|
||||
expect(value.reason.isFromExternalReference()).toEqual(true);
|
||||
expect(value.reason.node.getText()).toEqual('window: any');
|
||||
});
|
||||
|
||||
it('imports work', () => {
|
||||
const {program} = makeProgram([
|
||||
{name: 'second.ts', contents: 'export function foo(bar) { return bar; }'},
|
||||
|
|
Loading…
Reference in New Issue