parent
1bec4f6c61
commit
b90de66535
|
@ -395,6 +395,18 @@ function isIdentifierStart(code: number): boolean {
|
||||||
return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || (code == $_) || (code == $$);
|
return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || (code == $_) || (code == $$);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isIdentifier(input: string): boolean {
|
||||||
|
if (input.length == 0) return false;
|
||||||
|
var scanner = new _Scanner(input);
|
||||||
|
if (!isIdentifierStart(scanner.peek)) return false;
|
||||||
|
scanner.advance();
|
||||||
|
while (scanner.peek !== $EOF) {
|
||||||
|
if (!isIdentifierPart(scanner.peek)) return false;
|
||||||
|
scanner.advance();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function isIdentifierPart(code: number): boolean {
|
function isIdentifierPart(code: number): boolean {
|
||||||
return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || ($0 <= code && code <= $9) ||
|
return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || ($0 <= code && code <= $9) ||
|
||||||
(code == $_) || (code == $$);
|
(code == $_) || (code == $$);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {
|
import {
|
||||||
Lexer,
|
Lexer,
|
||||||
EOF,
|
EOF,
|
||||||
|
isIdentifier,
|
||||||
Token,
|
Token,
|
||||||
$PERIOD,
|
$PERIOD,
|
||||||
$COLON,
|
$COLON,
|
||||||
|
@ -105,15 +106,10 @@ export class Parser {
|
||||||
if (isBlank(input)) return null;
|
if (isBlank(input)) return null;
|
||||||
var prefixSeparatorIndex = input.indexOf(':');
|
var prefixSeparatorIndex = input.indexOf(':');
|
||||||
if (prefixSeparatorIndex == -1) return null;
|
if (prefixSeparatorIndex == -1) return null;
|
||||||
var prefix = input.substring(0, prefixSeparatorIndex);
|
var prefix = input.substring(0, prefixSeparatorIndex).trim();
|
||||||
|
if (!isIdentifier(prefix)) return null;
|
||||||
var uninterpretedExpression = input.substring(prefixSeparatorIndex + 1);
|
var uninterpretedExpression = input.substring(prefixSeparatorIndex + 1);
|
||||||
|
return new Quote(prefix, uninterpretedExpression, location);
|
||||||
// while we do not interpret the expression, we do interpret the prefix
|
|
||||||
var prefixTokens = this._lexer.tokenize(prefix);
|
|
||||||
|
|
||||||
// quote prefix must be a single legal identifier
|
|
||||||
if (prefixTokens.length != 1 || !prefixTokens[0].isIdentifier()) return null;
|
|
||||||
return new Quote(prefixTokens[0].strValue, uninterpretedExpression, location);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseTemplateBindings(input: string, location: any): TemplateBinding[] {
|
parseTemplateBindings(input: string, location: any): TemplateBinding[] {
|
||||||
|
|
|
@ -233,6 +233,9 @@ export function main() {
|
||||||
|
|
||||||
it('should parse quoted expressions', () => { checkBinding('a:b', 'a:b'); });
|
it('should parse quoted expressions', () => { checkBinding('a:b', 'a:b'); });
|
||||||
|
|
||||||
|
it('should not crash when prefix part is not tokenizable',
|
||||||
|
() => { checkBinding('"a:b"', '"a:b"'); });
|
||||||
|
|
||||||
it('should ignore whitespace around quote prefix', () => { checkBinding(' a :b', 'a:b'); });
|
it('should ignore whitespace around quote prefix', () => { checkBinding(' a :b', 'a:b'); });
|
||||||
|
|
||||||
it('should refuse prefixes that are not single identifiers', () => {
|
it('should refuse prefixes that are not single identifiers', () => {
|
||||||
|
|
Loading…
Reference in New Issue