feat($parse): add a hidden interface to retrieve an expression's AST
This PR adds a new private method to the `$parse` service, `$$getAst`, which takes an Angular expression as its only argument and returns the computed AST. This feature is not meant to be part of the public API and might be subject to changes, so use it with caution. Closes #16253 Closes #16260
This commit is contained in:
committed by
George Kalpakas
parent
199d888b84
commit
2e03aedc85
+27
-10
@@ -1644,11 +1644,26 @@ Parser.prototype = {
|
||||
constructor: Parser,
|
||||
|
||||
parse: function(text) {
|
||||
var ast = this.ast.ast(text);
|
||||
var fn = this.astCompiler.compile(ast);
|
||||
fn.literal = isLiteral(ast);
|
||||
fn.constant = isConstant(ast);
|
||||
var ast = this.getAst(text);
|
||||
var fn = this.astCompiler.compile(ast.ast);
|
||||
fn.literal = isLiteral(ast.ast);
|
||||
fn.constant = isConstant(ast.ast);
|
||||
fn.oneTime = ast.oneTime;
|
||||
return fn;
|
||||
},
|
||||
|
||||
getAst: function(exp) {
|
||||
var oneTime = false;
|
||||
exp = exp.trim();
|
||||
|
||||
if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
|
||||
oneTime = true;
|
||||
exp = exp.substring(2);
|
||||
}
|
||||
return {
|
||||
ast: this.ast.ast(exp),
|
||||
oneTime: oneTime
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1771,10 +1786,11 @@ function $ParseProvider() {
|
||||
isIdentifierStart: isFunction(identStart) && identStart,
|
||||
isIdentifierContinue: isFunction(identContinue) && identContinue
|
||||
};
|
||||
$parse.$$getAst = $$getAst;
|
||||
return $parse;
|
||||
|
||||
function $parse(exp, interceptorFn) {
|
||||
var parsedExpression, oneTime, cacheKey;
|
||||
var parsedExpression, cacheKey;
|
||||
|
||||
switch (typeof exp) {
|
||||
case 'string':
|
||||
@@ -1784,14 +1800,9 @@ function $ParseProvider() {
|
||||
parsedExpression = cache[cacheKey];
|
||||
|
||||
if (!parsedExpression) {
|
||||
if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
|
||||
oneTime = true;
|
||||
exp = exp.substring(2);
|
||||
}
|
||||
var lexer = new Lexer($parseOptions);
|
||||
var parser = new Parser(lexer, $filter, $parseOptions);
|
||||
parsedExpression = parser.parse(exp);
|
||||
parsedExpression.oneTime = !!oneTime;
|
||||
|
||||
cache[cacheKey] = addWatchDelegate(parsedExpression);
|
||||
}
|
||||
@@ -1805,6 +1816,12 @@ function $ParseProvider() {
|
||||
}
|
||||
}
|
||||
|
||||
function $$getAst(exp) {
|
||||
var lexer = new Lexer($parseOptions);
|
||||
var parser = new Parser(lexer, $filter, $parseOptions);
|
||||
return parser.getAst(exp).ast;
|
||||
}
|
||||
|
||||
function expressionInputDirtyCheck(newValue, oldValueOfValue, compareObjectIdentity) {
|
||||
|
||||
if (newValue == null || oldValueOfValue == null) { // null/undefined
|
||||
|
||||
@@ -4245,4 +4245,48 @@ describe('parser', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('hidden/unsupported features', function() {
|
||||
describe('$$getAst()', function() {
|
||||
it('should be a method exposed on the `$parse` service', inject(function($parse) {
|
||||
expect(isFunction($parse.$$getAst)).toBeTruthy();
|
||||
}));
|
||||
|
||||
it('should accept a string expression argument and return the corresponding AST', inject(function($parse) {
|
||||
var ast = $parse.$$getAst('foo.bar');
|
||||
expect(ast).toEqual({
|
||||
type: 'Program',
|
||||
body: [
|
||||
{
|
||||
type: 'ExpressionStatement',
|
||||
expression: {
|
||||
type: 'MemberExpression',
|
||||
object: { type: 'Identifier', name: 'foo' },
|
||||
property: { type: 'Identifier', name: 'bar' },
|
||||
computed: false
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}));
|
||||
|
||||
it('should parse one time binding expressions', inject(function($parse) {
|
||||
var ast = $parse.$$getAst('::foo.bar');
|
||||
expect(ast).toEqual({
|
||||
type: 'Program',
|
||||
body: [
|
||||
{
|
||||
type: 'ExpressionStatement',
|
||||
expression: {
|
||||
type: 'MemberExpression',
|
||||
object: { type: 'Identifier', name: 'foo' },
|
||||
property: { type: 'Identifier', name: 'bar' },
|
||||
computed: false
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user