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;
|
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 {
|
private getRequiredProperty(propertyName: string): TExpression {
|
||||||
if (!this.obj.has(propertyName)) {
|
if (!this.obj.has(propertyName)) {
|
||||||
throw new FatalLinkerError(
|
throw new FatalLinkerError(
|
||||||
@ -136,7 +148,15 @@ export class AstObject<TExpression> {
|
|||||||
* access to the underlying value of the wrapped expression.
|
* access to the underlying value of the wrapped expression.
|
||||||
*/
|
*/
|
||||||
export class AstValue<TExpression> {
|
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?
|
* 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('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', () => {
|
describe('isNumber', () => {
|
||||||
it('should return true if the value is a number', () => {
|
it('should return true if the value is a number', () => {
|
||||||
expect(new AstValue(factory.createLiteral(42), host).isNumber()).toEqual(true);
|
expect(new AstValue(factory.createLiteral(42), host).isNumber()).toEqual(true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user