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:
Francesco Pipita
2017-10-07 18:27:20 +02:00
committed by George Kalpakas
parent 199d888b84
commit 2e03aedc85
2 changed files with 71 additions and 10 deletions
+27 -10
View File
@@ -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
+44
View File
@@ -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
}
}
]
});
}));
});
});
});