refactor(compiler-cli): extend AST object and value helpers (#39518)
This introduces `AstObject.toMap` as an alternative to `AstObject .toLiteral`, and adds `AstValue.getSymbolName` to query the symbol name of a value using the encapsulated AST host. PR Close #39518
This commit is contained in:
parent
2d79780384
commit
4eda87c86c
|
@ -122,6 +122,18 @@ export class AstObject<TExpression> {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the AstObject to a JavaScript Map, mapping each property value (as an
|
||||
* `AstValue`) to the generic type (`T`) via the `mapper` function.
|
||||
*/
|
||||
toMap<T>(mapper: (value: AstValue<TExpression>) => T): Map<string, T> {
|
||||
const result = new Map<string, T>();
|
||||
for (const [key, expression] of this.obj) {
|
||||
result.set(key, mapper(new AstValue(expression, this.host)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private getRequiredProperty(propertyName: string): TExpression {
|
||||
if (!this.obj.has(propertyName)) {
|
||||
throw new FatalLinkerError(
|
||||
|
@ -136,7 +148,15 @@ export class AstObject<TExpression> {
|
|||
* access to the underlying value of the wrapped expression.
|
||||
*/
|
||||
export class AstValue<TExpression> {
|
||||
constructor(private expression: TExpression, private host: AstHost<TExpression>) {}
|
||||
constructor(readonly expression: TExpression, private host: AstHost<TExpression>) {}
|
||||
|
||||
/**
|
||||
* Get the name of the symbol represented by the given expression node, or `null` if it is not a
|
||||
* symbol.
|
||||
*/
|
||||
getSymbolName(): string|null {
|
||||
return this.host.getSymbolName(this.expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this value a number?
|
||||
|
|
|
@ -141,9 +141,37 @@ describe('AstObject', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('toMap()', () => {
|
||||
it('should convert the AstObject to a Map with each property mapped', () => {
|
||||
expect(obj.toMap(value => value.getOpaque())).toEqual(new Map([
|
||||
['a', obj.getOpaque('a')],
|
||||
['b', obj.getOpaque('b')],
|
||||
['c', obj.getOpaque('c')],
|
||||
['d', obj.getOpaque('d')],
|
||||
['e', obj.getOpaque('e')],
|
||||
]));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('AstValue', () => {
|
||||
describe('getSymbolName', () => {
|
||||
it('should return the name of an identifier', () => {
|
||||
expect(new AstValue(factory.createIdentifier('Foo'), host).getSymbolName()).toEqual('Foo');
|
||||
});
|
||||
|
||||
it('should return the name of a property access', () => {
|
||||
const propertyAccess = factory.createPropertyAccess(
|
||||
factory.createIdentifier('Foo'), factory.createIdentifier('Bar'));
|
||||
expect(new AstValue(propertyAccess, host).getSymbolName()).toEqual('Bar');
|
||||
});
|
||||
|
||||
it('should return null if no symbol name is available', () => {
|
||||
expect(new AstValue(factory.createLiteral('a'), host).getSymbolName()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNumber', () => {
|
||||
it('should return true if the value is a number', () => {
|
||||
expect(new AstValue(factory.createLiteral(42), host).isNumber()).toEqual(true);
|
||||
|
|
Loading…
Reference in New Issue