Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 2e03aed

Browse files
fpipitagkalpak
authored andcommitted
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
1 parent 199d888 commit 2e03aed

File tree

2 files changed

+71
-10
lines changed

2 files changed

+71
-10
lines changed

src/ng/parse.js

+27-10
Original file line numberDiff line numberDiff line change
@@ -1644,11 +1644,26 @@ Parser.prototype = {
16441644
constructor: Parser,
16451645

16461646
parse: function(text) {
1647-
var ast = this.ast.ast(text);
1648-
var fn = this.astCompiler.compile(ast);
1649-
fn.literal = isLiteral(ast);
1650-
fn.constant = isConstant(ast);
1647+
var ast = this.getAst(text);
1648+
var fn = this.astCompiler.compile(ast.ast);
1649+
fn.literal = isLiteral(ast.ast);
1650+
fn.constant = isConstant(ast.ast);
1651+
fn.oneTime = ast.oneTime;
16511652
return fn;
1653+
},
1654+
1655+
getAst: function(exp) {
1656+
var oneTime = false;
1657+
exp = exp.trim();
1658+
1659+
if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
1660+
oneTime = true;
1661+
exp = exp.substring(2);
1662+
}
1663+
return {
1664+
ast: this.ast.ast(exp),
1665+
oneTime: oneTime
1666+
};
16521667
}
16531668
};
16541669

@@ -1771,10 +1786,11 @@ function $ParseProvider() {
17711786
isIdentifierStart: isFunction(identStart) && identStart,
17721787
isIdentifierContinue: isFunction(identContinue) && identContinue
17731788
};
1789+
$parse.$$getAst = $$getAst;
17741790
return $parse;
17751791

17761792
function $parse(exp, interceptorFn) {
1777-
var parsedExpression, oneTime, cacheKey;
1793+
var parsedExpression, cacheKey;
17781794

17791795
switch (typeof exp) {
17801796
case 'string':
@@ -1784,14 +1800,9 @@ function $ParseProvider() {
17841800
parsedExpression = cache[cacheKey];
17851801

17861802
if (!parsedExpression) {
1787-
if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
1788-
oneTime = true;
1789-
exp = exp.substring(2);
1790-
}
17911803
var lexer = new Lexer($parseOptions);
17921804
var parser = new Parser(lexer, $filter, $parseOptions);
17931805
parsedExpression = parser.parse(exp);
1794-
parsedExpression.oneTime = !!oneTime;
17951806

17961807
cache[cacheKey] = addWatchDelegate(parsedExpression);
17971808
}
@@ -1805,6 +1816,12 @@ function $ParseProvider() {
18051816
}
18061817
}
18071818

1819+
function $$getAst(exp) {
1820+
var lexer = new Lexer($parseOptions);
1821+
var parser = new Parser(lexer, $filter, $parseOptions);
1822+
return parser.getAst(exp).ast;
1823+
}
1824+
18081825
function expressionInputDirtyCheck(newValue, oldValueOfValue, compareObjectIdentity) {
18091826

18101827
if (newValue == null || oldValueOfValue == null) { // null/undefined

test/ng/parseSpec.js

+44
Original file line numberDiff line numberDiff line change
@@ -4245,4 +4245,48 @@ describe('parser', function() {
42454245
});
42464246
});
42474247
});
4248+
4249+
describe('hidden/unsupported features', function() {
4250+
describe('$$getAst()', function() {
4251+
it('should be a method exposed on the `$parse` service', inject(function($parse) {
4252+
expect(isFunction($parse.$$getAst)).toBeTruthy();
4253+
}));
4254+
4255+
it('should accept a string expression argument and return the corresponding AST', inject(function($parse) {
4256+
var ast = $parse.$$getAst('foo.bar');
4257+
expect(ast).toEqual({
4258+
type: 'Program',
4259+
body: [
4260+
{
4261+
type: 'ExpressionStatement',
4262+
expression: {
4263+
type: 'MemberExpression',
4264+
object: { type: 'Identifier', name: 'foo' },
4265+
property: { type: 'Identifier', name: 'bar' },
4266+
computed: false
4267+
}
4268+
}
4269+
]
4270+
});
4271+
}));
4272+
4273+
it('should parse one time binding expressions', inject(function($parse) {
4274+
var ast = $parse.$$getAst('::foo.bar');
4275+
expect(ast).toEqual({
4276+
type: 'Program',
4277+
body: [
4278+
{
4279+
type: 'ExpressionStatement',
4280+
expression: {
4281+
type: 'MemberExpression',
4282+
object: { type: 'Identifier', name: 'foo' },
4283+
property: { type: 'Identifier', name: 'bar' },
4284+
computed: false
4285+
}
4286+
}
4287+
]
4288+
});
4289+
}));
4290+
});
4291+
});
42484292
});

0 commit comments

Comments
 (0)