Skip to content

Commit

Permalink
fix(parser): only strip comments if not in string literals
Browse files Browse the repository at this point in the history
  • Loading branch information
kara committed Apr 14, 2016
1 parent 7912dc7 commit ca30d95
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
6 changes: 5 additions & 1 deletion modules/angular2/src/compiler/expression_parser/lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export const $BACKSLASH = 92;
export const $RBRACKET = 93;
const $CARET = 94;
const $_ = 95;

export const $BT = 96;
const $a = 97, $e = 101, $f = 102, $n = 110, $r = 114, $t = 116, $u = 117, $v = 118, $z = 122;

export const $LBRACE = 123;
Expand Down Expand Up @@ -415,6 +415,10 @@ function isExponentSign(code: number): boolean {
return code == $MINUS || code == $PLUS;
}

export function isQuote(code: number): boolean {
return code === $SQ || code === $DQ || code === $BT;
}

function unescape(code: number): number {
switch (code) {
case $n:
Expand Down
26 changes: 23 additions & 3 deletions modules/angular2/src/compiler/expression_parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Lexer,
EOF,
isIdentifier,
isQuote,
Token,
$PERIOD,
$COLON,
Expand All @@ -16,7 +17,8 @@ import {
$LBRACE,
$RBRACE,
$LPAREN,
$RPAREN
$RPAREN,
$SLASH
} from './lexer';
import {
AST,
Expand Down Expand Up @@ -49,7 +51,6 @@ import {
var _implicitReceiver = new ImplicitReceiver();
// TODO(tbosch): Cannot make this const/final right now because of the transpiler...
var INTERPOLATION_REGEXP = /\{\{([\s\S]*?)\}\}/g;
var COMMENT_REGEX = /[^:]\/\//g;

class ParseException extends BaseException {
constructor(message: string, input: string, errLocation: string, ctxLocation?: any) {
Expand Down Expand Up @@ -160,7 +161,26 @@ export class Parser {
}

private _stripComments(input: string): string {
return StringWrapper.split(input, COMMENT_REGEX)[0].trim();
let i = this._commentStart(input);
return isPresent(i) ? input.substring(0, i).trim() : input;
}

private _commentStart(input: string): number {
let quoteStack = [];
for (var i = 0; i < input.length - 1; i++) {
let char = StringWrapper.charCodeAt(input, i);
let nextChar = StringWrapper.charCodeAt(input, i + 1);
let top = ListWrapper.last(quoteStack);

if (char === $SLASH && nextChar == $SLASH && quoteStack.length === 0) return i;

if (top === char) {
quoteStack.pop();
} else if (isQuote(char)) {
quoteStack.push(char);
}
}
return null;
}

private _checkNoInterpolation(input: string, location: any): void {
Expand Down
27 changes: 20 additions & 7 deletions modules/angular2/test/compiler/expression_parser/parser_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export function main() {

it('should ignore comments in expressions', () => { checkAction('a //comment', 'a'); });

it('should retain // in URLs',
it('should retain // in string literals',
() => { checkAction(`"http://www.google.com"`, `"http://www.google.com"`); });

it('should parse an empty string', () => { checkAction(''); });
Expand Down Expand Up @@ -277,8 +277,10 @@ export function main() {

it('should ignore comments in bindings', () => { checkBinding('a //comment', 'a'); });

it('should retain // in URLs',
it('should retain // in string literals',
() => { checkBinding(`"http://www.google.com"`, `"http://www.google.com"`); });

it('should retain // in : microsyntax', () => { checkBinding('one:a//b', 'one:a//b'); });
});

describe('parseTemplateBindings', () => {
Expand Down Expand Up @@ -435,12 +437,23 @@ export function main() {
checkInterpolation(`{{ 'foo' +\n 'bar' +\r 'baz' }}`, `{{ "foo" + "bar" + "baz" }}`);
});

it('should ignore comments in interpolation expressions',
() => { checkInterpolation('{{a //comment}}', '{{ a }}'); });
describe("comments", () => {
it('should ignore comments in interpolation expressions',
() => { checkInterpolation('{{a //comment}}', '{{ a }}'); });

it('should retain // in single quote strings', () => {
checkInterpolation(`{{ 'http://www.google.com' }}`, `{{ "http://www.google.com" }}`);
});

it('should retain // in double quote strings', () => {
checkInterpolation(`{{ "http://www.google.com" }}`, `{{ "http://www.google.com" }}`);
});

it('should ignore comments after string literals',
() => { checkInterpolation(`{{ "a//b" //comment }}`, `{{ "a//b" }}`); });

})

it('should retain // in URLs', () => {
checkInterpolation(`{{ "http://www.google.com" }}`, `{{ "http://www.google.com" }}`);
});
});

describe("parseSimpleBinding", () => {
Expand Down

0 comments on commit ca30d95

Please sign in to comment.