feat(compiler): adds support for quoted object keys in the parser
This commit is contained in:
parent
7ae8ad6aab
commit
798947efa4
|
@ -170,7 +170,7 @@ class _BuiltinAstConverter extends cdAst.AstTransformer {
|
||||||
visitLiteralMap(ast: cdAst.LiteralMap, context: any): any {
|
visitLiteralMap(ast: cdAst.LiteralMap, context: any): any {
|
||||||
const args = ast.values.map(ast => ast.visit(this, context));
|
const args = ast.values.map(ast => ast.visit(this, context));
|
||||||
return new BuiltinFunctionCall(
|
return new BuiltinFunctionCall(
|
||||||
ast.span, args, this._converterFactory.createLiteralMapConverter(ast.keys));
|
ast.span, args, this._converterFactory.createLiteralMapConverter(ast.keys.map(k => k.key)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,8 +136,12 @@ export class LiteralArray extends AST {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LiteralMapKey = {
|
||||||
|
key: string; quoted: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export class LiteralMap extends AST {
|
export class LiteralMap extends AST {
|
||||||
constructor(span: ParseSpan, public keys: any[], public values: any[]) { super(span); }
|
constructor(span: ParseSpan, public keys: LiteralMapKey[], public values: any[]) { super(span); }
|
||||||
visit(visitor: AstVisitor, context: any = null): any {
|
visit(visitor: AstVisitor, context: any = null): any {
|
||||||
return visitor.visitLiteralMap(this, context);
|
return visitor.visitLiteralMap(this, context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,9 @@ import {CompilerInjectable} from '../injectable';
|
||||||
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../ml_parser/interpolation_config';
|
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../ml_parser/interpolation_config';
|
||||||
import {escapeRegExp} from '../util';
|
import {escapeRegExp} from '../util';
|
||||||
|
|
||||||
import {AST, ASTWithSource, AstVisitor, Binary, BindingPipe, Chain, Conditional, EmptyExpr, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, NonNullAssert, ParseSpan, ParserError, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead, TemplateBinding} from './ast';
|
import {AST, ASTWithSource, AstVisitor, Binary, BindingPipe, Chain, Conditional, EmptyExpr, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralMapKey, LiteralPrimitive, MethodCall, NonNullAssert, ParseSpan, ParserError, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead, TemplateBinding} from './ast';
|
||||||
import {EOF, Lexer, Token, TokenType, isIdentifier, isQuote} from './lexer';
|
import {EOF, Lexer, Token, TokenType, isIdentifier, isQuote} from './lexer';
|
||||||
|
|
||||||
|
|
||||||
export class SplitInterpolation {
|
export class SplitInterpolation {
|
||||||
constructor(public strings: string[], public expressions: string[], public offsets: number[]) {}
|
constructor(public strings: string[], public expressions: string[], public offsets: number[]) {}
|
||||||
}
|
}
|
||||||
|
@ -605,15 +604,16 @@ export class _ParseAST {
|
||||||
}
|
}
|
||||||
|
|
||||||
parseLiteralMap(): LiteralMap {
|
parseLiteralMap(): LiteralMap {
|
||||||
const keys: string[] = [];
|
const keys: LiteralMapKey[] = [];
|
||||||
const values: AST[] = [];
|
const values: AST[] = [];
|
||||||
const start = this.inputIndex;
|
const start = this.inputIndex;
|
||||||
this.expectCharacter(chars.$LBRACE);
|
this.expectCharacter(chars.$LBRACE);
|
||||||
if (!this.optionalCharacter(chars.$RBRACE)) {
|
if (!this.optionalCharacter(chars.$RBRACE)) {
|
||||||
this.rbracesExpected++;
|
this.rbracesExpected++;
|
||||||
do {
|
do {
|
||||||
|
const quoted = this.next.isString();
|
||||||
const key = this.expectIdentifierOrKeywordOrString();
|
const key = this.expectIdentifierOrKeywordOrString();
|
||||||
keys.push(key);
|
keys.push({key, quoted});
|
||||||
this.expectCharacter(chars.$COLON);
|
this.expectCharacter(chars.$COLON);
|
||||||
values.push(this.parsePipe());
|
values.push(this.parsePipe());
|
||||||
} while (this.optionalCharacter(chars.$COMMA));
|
} while (this.optionalCharacter(chars.$COMMA));
|
||||||
|
|
|
@ -165,7 +165,7 @@ export function main() {
|
||||||
|
|
||||||
it('should parse map', () => {
|
it('should parse map', () => {
|
||||||
checkAction('{}');
|
checkAction('{}');
|
||||||
checkAction('{a: 1}[2]');
|
checkAction('{a: 1, "b": 2}[2]');
|
||||||
checkAction('{}["a"]');
|
checkAction('{}["a"]');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ export function main() {
|
||||||
checkBinding('a(b | c)', 'a((b | c))');
|
checkBinding('a(b | c)', 'a((b | c))');
|
||||||
checkBinding('a.b(c.d(e) | f)', 'a.b((c.d(e) | f))');
|
checkBinding('a.b(c.d(e) | f)', 'a.b((c.d(e) | f))');
|
||||||
checkBinding('[1, 2, 3] | a', '([1, 2, 3] | a)');
|
checkBinding('[1, 2, 3] | a', '([1, 2, 3] | a)');
|
||||||
checkBinding('{a: 1} | b', '({a: 1} | b)');
|
checkBinding('{a: 1, "b": 2} | c', '({a: 1, "b": 2} | c)');
|
||||||
checkBinding('a[b] | c', '(a[b] | c)');
|
checkBinding('a[b] | c', '(a[b] | c)');
|
||||||
checkBinding('a?.b | c', '(a?.b | c)');
|
checkBinding('a?.b | c', '(a?.b | c)');
|
||||||
checkBinding('true | a', '(true | a)');
|
checkBinding('true | a', '(true | a)');
|
||||||
|
|
|
@ -124,7 +124,9 @@ class Unparser implements AstVisitor {
|
||||||
for (let i = 0; i < ast.keys.length; i++) {
|
for (let i = 0; i < ast.keys.length; i++) {
|
||||||
if (!isFirst) this._expression += ', ';
|
if (!isFirst) this._expression += ', ';
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
this._expression += `${ast.keys[i]}: `;
|
const key = ast.keys[i];
|
||||||
|
this._expression += key.quoted ? JSON.stringify(key.key) : key.key;
|
||||||
|
this._expression += ': ';
|
||||||
this._visit(ast.values[i]);
|
this._visit(ast.values[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue