UNPKG

json-string-mapper

Version:

transform json string to key value pair map

1,376 lines (1,352 loc) 72.1 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.jsonStringMapper = global.jsonStringMapper || {}))); }(this, (function (exports) { 'use strict'; /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ function isPresent(obj) { return obj != null; } function isBlank(obj) { return obj == null; } var NumberWrapper = (function () { function NumberWrapper() { } NumberWrapper.parseIntAutoRadix = function (text) { var result = parseInt(text); if (isNaN(result)) { throw new Error('Invalid integer literal when parsing ' + text); } return result; }; NumberWrapper.isNumeric = function (value) { return !isNaN(value - parseFloat(value)); }; return NumberWrapper; }()); // JS has NaN !== NaN function escapeRegExp(s) { return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var __extends = (undefined && undefined.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var ParserError = (function () { function ParserError(message, input, errLocation, ctxLocation) { this.input = input; this.errLocation = errLocation; this.ctxLocation = ctxLocation; this.message = "Parser Error: " + message + " " + errLocation + " [" + input + "] in " + ctxLocation; } return ParserError; }()); var ParseSpan = (function () { function ParseSpan(start, end) { this.start = start; this.end = end; } return ParseSpan; }()); var AST = (function () { function AST(span) { this.span = span; } AST.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return null; }; AST.prototype.toString = function () { return 'AST'; }; return AST; }()); /** * Represents a quoted expression of the form: * * quote = prefix `:` uninterpretedExpression * prefix = identifier * uninterpretedExpression = arbitrary string * * A quoted expression is meant to be pre-processed by an AST transformer that * converts it into another AST that no longer contains quoted expressions. * It is meant to allow third-party developers to extend Angular template * expression language. The `uninterpretedExpression` part of the quote is * therefore not interpreted by the Angular's own expression parser. */ var Quote = (function (_super) { __extends(Quote, _super); function Quote(span, prefix, uninterpretedExpression, location) { var _this = _super.call(this, span) || this; _this.prefix = prefix; _this.uninterpretedExpression = uninterpretedExpression; _this.location = location; return _this; } Quote.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitQuote(this, context); }; Quote.prototype.toString = function () { return 'Quote'; }; return Quote; }(AST)); var EmptyExpr = (function (_super) { __extends(EmptyExpr, _super); function EmptyExpr() { return _super !== null && _super.apply(this, arguments) || this; } EmptyExpr.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } // do nothing }; return EmptyExpr; }(AST)); var ImplicitReceiver = (function (_super) { __extends(ImplicitReceiver, _super); function ImplicitReceiver() { return _super !== null && _super.apply(this, arguments) || this; } ImplicitReceiver.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitImplicitReceiver(this, context); }; return ImplicitReceiver; }(AST)); /** * Multiple expressions separated by a semicolon. */ var Chain = (function (_super) { __extends(Chain, _super); function Chain(span, expressions) { var _this = _super.call(this, span) || this; _this.expressions = expressions; return _this; } Chain.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitChain(this, context); }; return Chain; }(AST)); var Conditional = (function (_super) { __extends(Conditional, _super); function Conditional(span, condition, trueExp, falseExp) { var _this = _super.call(this, span) || this; _this.condition = condition; _this.trueExp = trueExp; _this.falseExp = falseExp; return _this; } Conditional.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitConditional(this, context); }; return Conditional; }(AST)); var PropertyRead = (function (_super) { __extends(PropertyRead, _super); function PropertyRead(span, receiver, name) { var _this = _super.call(this, span) || this; _this.receiver = receiver; _this.name = name; return _this; } PropertyRead.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitPropertyRead(this, context); }; return PropertyRead; }(AST)); var PropertyWrite = (function (_super) { __extends(PropertyWrite, _super); function PropertyWrite(span, receiver, name, value) { var _this = _super.call(this, span) || this; _this.receiver = receiver; _this.name = name; _this.value = value; return _this; } PropertyWrite.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitPropertyWrite(this, context); }; return PropertyWrite; }(AST)); var SafePropertyRead = (function (_super) { __extends(SafePropertyRead, _super); function SafePropertyRead(span, receiver, name) { var _this = _super.call(this, span) || this; _this.receiver = receiver; _this.name = name; return _this; } SafePropertyRead.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitSafePropertyRead(this, context); }; return SafePropertyRead; }(AST)); var KeyedRead = (function (_super) { __extends(KeyedRead, _super); function KeyedRead(span, obj, key) { var _this = _super.call(this, span) || this; _this.obj = obj; _this.key = key; return _this; } KeyedRead.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitKeyedRead(this, context); }; return KeyedRead; }(AST)); var KeyedWrite = (function (_super) { __extends(KeyedWrite, _super); function KeyedWrite(span, obj, key, value) { var _this = _super.call(this, span) || this; _this.obj = obj; _this.key = key; _this.value = value; return _this; } KeyedWrite.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitKeyedWrite(this, context); }; return KeyedWrite; }(AST)); var BindingPipe = (function (_super) { __extends(BindingPipe, _super); function BindingPipe(span, exp, name, args) { var _this = _super.call(this, span) || this; _this.exp = exp; _this.name = name; _this.args = args; return _this; } BindingPipe.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitPipe(this, context); }; return BindingPipe; }(AST)); var LiteralPrimitive = (function (_super) { __extends(LiteralPrimitive, _super); function LiteralPrimitive(span, value) { var _this = _super.call(this, span) || this; _this.value = value; return _this; } LiteralPrimitive.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitLiteralPrimitive(this, context); }; return LiteralPrimitive; }(AST)); var LiteralArray = (function (_super) { __extends(LiteralArray, _super); function LiteralArray(span, expressions) { var _this = _super.call(this, span) || this; _this.expressions = expressions; return _this; } LiteralArray.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitLiteralArray(this, context); }; return LiteralArray; }(AST)); var LiteralMap = (function (_super) { __extends(LiteralMap, _super); function LiteralMap(span, keys, values) { var _this = _super.call(this, span) || this; _this.keys = keys; _this.values = values; return _this; } LiteralMap.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitLiteralMap(this, context); }; return LiteralMap; }(AST)); var Interpolation = (function (_super) { __extends(Interpolation, _super); function Interpolation(span, strings, expressions) { var _this = _super.call(this, span) || this; _this.strings = strings; _this.expressions = expressions; return _this; } Interpolation.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitInterpolation(this, context); }; return Interpolation; }(AST)); var Binary = (function (_super) { __extends(Binary, _super); function Binary(span, operation, left, right) { var _this = _super.call(this, span) || this; _this.operation = operation; _this.left = left; _this.right = right; return _this; } Binary.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitBinary(this, context); }; return Binary; }(AST)); var PrefixNot = (function (_super) { __extends(PrefixNot, _super); function PrefixNot(span, expression) { var _this = _super.call(this, span) || this; _this.expression = expression; return _this; } PrefixNot.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitPrefixNot(this, context); }; return PrefixNot; }(AST)); var MethodCall = (function (_super) { __extends(MethodCall, _super); function MethodCall(span, receiver, name, args) { var _this = _super.call(this, span) || this; _this.receiver = receiver; _this.name = name; _this.args = args; return _this; } MethodCall.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitMethodCall(this, context); }; return MethodCall; }(AST)); var SafeMethodCall = (function (_super) { __extends(SafeMethodCall, _super); function SafeMethodCall(span, receiver, name, args) { var _this = _super.call(this, span) || this; _this.receiver = receiver; _this.name = name; _this.args = args; return _this; } SafeMethodCall.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitSafeMethodCall(this, context); }; return SafeMethodCall; }(AST)); var FunctionCall = (function (_super) { __extends(FunctionCall, _super); function FunctionCall(span, target, args) { var _this = _super.call(this, span) || this; _this.target = target; _this.args = args; return _this; } FunctionCall.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return visitor.visitFunctionCall(this, context); }; return FunctionCall; }(AST)); var ASTWithSource = (function (_super) { __extends(ASTWithSource, _super); function ASTWithSource(ast, source, location, errors) { var _this = _super.call(this, new ParseSpan(0, isBlank(source) ? 0 : source.length)) || this; _this.ast = ast; _this.source = source; _this.location = location; _this.errors = errors; return _this; } ASTWithSource.prototype.visit = function (visitor, context) { if (context === void 0) { context = null; } return this.ast.visit(visitor, context); }; ASTWithSource.prototype.toString = function () { return this.source + " in " + this.location; }; return ASTWithSource; }(AST)); var TemplateBinding = (function () { function TemplateBinding(span, key, keyIsVar, name, expression) { this.span = span; this.key = key; this.keyIsVar = keyIsVar; this.name = name; this.expression = expression; } return TemplateBinding; }()); var RecursiveAstVisitor = (function () { function RecursiveAstVisitor() { } RecursiveAstVisitor.prototype.visitBinary = function (ast, context) { ast.left.visit(this); ast.right.visit(this); return null; }; RecursiveAstVisitor.prototype.visitChain = function (ast, context) { return this.visitAll(ast.expressions, context); }; RecursiveAstVisitor.prototype.visitConditional = function (ast, context) { ast.condition.visit(this); ast.trueExp.visit(this); ast.falseExp.visit(this); return null; }; RecursiveAstVisitor.prototype.visitPipe = function (ast, context) { ast.exp.visit(this); this.visitAll(ast.args, context); return null; }; RecursiveAstVisitor.prototype.visitFunctionCall = function (ast, context) { ast.target.visit(this); this.visitAll(ast.args, context); return null; }; RecursiveAstVisitor.prototype.visitImplicitReceiver = function (ast, context) { return null; }; RecursiveAstVisitor.prototype.visitInterpolation = function (ast, context) { return this.visitAll(ast.expressions, context); }; RecursiveAstVisitor.prototype.visitKeyedRead = function (ast, context) { ast.obj.visit(this); ast.key.visit(this); return null; }; RecursiveAstVisitor.prototype.visitKeyedWrite = function (ast, context) { ast.obj.visit(this); ast.key.visit(this); ast.value.visit(this); return null; }; RecursiveAstVisitor.prototype.visitLiteralArray = function (ast, context) { return this.visitAll(ast.expressions, context); }; RecursiveAstVisitor.prototype.visitLiteralMap = function (ast, context) { return this.visitAll(ast.values, context); }; RecursiveAstVisitor.prototype.visitLiteralPrimitive = function (ast, context) { return null; }; RecursiveAstVisitor.prototype.visitMethodCall = function (ast, context) { ast.receiver.visit(this); return this.visitAll(ast.args, context); }; RecursiveAstVisitor.prototype.visitPrefixNot = function (ast, context) { ast.expression.visit(this); return null; }; RecursiveAstVisitor.prototype.visitPropertyRead = function (ast, context) { ast.receiver.visit(this); return null; }; RecursiveAstVisitor.prototype.visitPropertyWrite = function (ast, context) { ast.receiver.visit(this); ast.value.visit(this); return null; }; RecursiveAstVisitor.prototype.visitSafePropertyRead = function (ast, context) { ast.receiver.visit(this); return null; }; RecursiveAstVisitor.prototype.visitSafeMethodCall = function (ast, context) { ast.receiver.visit(this); return this.visitAll(ast.args, context); }; RecursiveAstVisitor.prototype.visitAll = function (asts, context) { var _this = this; asts.forEach(function (ast) { return ast.visit(_this, context); }); return null; }; RecursiveAstVisitor.prototype.visitQuote = function (ast, context) { return null; }; return RecursiveAstVisitor; }()); /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var $EOF = 0; var $TAB = 9; var $LF = 10; var $VTAB = 11; var $FF = 12; var $CR = 13; var $SPACE = 32; var $BANG = 33; var $DQ = 34; var $HASH = 35; var $$ = 36; var $PERCENT = 37; var $AMPERSAND = 38; var $SQ = 39; var $LPAREN = 40; var $RPAREN = 41; var $STAR = 42; var $PLUS = 43; var $COMMA = 44; var $MINUS = 45; var $PERIOD = 46; var $SLASH = 47; var $COLON = 58; var $SEMICOLON = 59; var $LT = 60; var $EQ = 61; var $GT = 62; var $QUESTION = 63; var $0 = 48; var $9 = 57; var $A = 65; var $E = 69; var $Z = 90; var $LBRACKET = 91; var $BACKSLASH = 92; var $RBRACKET = 93; var $CARET = 94; var $_ = 95; var $a = 97; var $e = 101; var $f = 102; var $n = 110; var $r = 114; var $t = 116; var $u = 117; var $v = 118; var $z = 122; var $LBRACE = 123; var $BAR = 124; var $RBRACE = 125; var $NBSP = 160; var $BT = 96; function isWhitespace(code) { return (code >= $TAB && code <= $SPACE) || (code == $NBSP); } function isDigit(code) { return $0 <= code && code <= $9; } function isAsciiLetter(code) { return code >= $a && code <= $z || code >= $A && code <= $Z; } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var isDevMode = function () { return false; }; var INTERPOLATION_BLACKLIST_REGEXPS = [ /^\s*$/, /[<>]/, /^[{}]$/, /&(#|[a-z])/i, /^\/\//, ]; function assertInterpolationSymbols(identifier, value) { if (isPresent(value) && !(Array.isArray(value) && value.length == 2)) { throw new Error("Expected '" + identifier + "' to be an array, [start, end]."); } else if (isDevMode() && !isBlank(value)) { var start_1 = value[0]; var end_1 = value[1]; // black list checking INTERPOLATION_BLACKLIST_REGEXPS.forEach(function (regexp) { if (regexp.test(start_1) || regexp.test(end_1)) { throw new Error("['" + start_1 + "', '" + end_1 + "'] contains unusable interpolation symbol."); } }); } } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var InterpolationConfig = (function () { function InterpolationConfig(start, end) { this.start = start; this.end = end; } InterpolationConfig.fromArray = function (markers) { if (!markers) { return DEFAULT_INTERPOLATION_CONFIG; } assertInterpolationSymbols('interpolation', markers); return new InterpolationConfig(markers[0], markers[1]); }; return InterpolationConfig; }()); var DEFAULT_INTERPOLATION_CONFIG = new InterpolationConfig('{{', '}}'); /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var TokenType; (function (TokenType) { TokenType[TokenType["Character"] = 0] = "Character"; TokenType[TokenType["Identifier"] = 1] = "Identifier"; TokenType[TokenType["Keyword"] = 2] = "Keyword"; TokenType[TokenType["String"] = 3] = "String"; TokenType[TokenType["Operator"] = 4] = "Operator"; TokenType[TokenType["Number"] = 5] = "Number"; TokenType[TokenType["Error"] = 6] = "Error"; })(TokenType || (TokenType = {})); var KEYWORDS = ['var', 'let', 'null', 'undefined', 'true', 'false', 'if', 'else', 'this']; var Lexer = (function () { function Lexer() { } Lexer.prototype.tokenize = function (text) { var scanner = new _Scanner(text); var tokens = []; var token = scanner.scanToken(); while (token != null) { tokens.push(token); token = scanner.scanToken(); } return tokens; }; return Lexer; }()); var Token = (function () { function Token(index, type, numValue, strValue) { this.index = index; this.type = type; this.numValue = numValue; this.strValue = strValue; } Token.prototype.isCharacter = function (code) { return this.type == TokenType.Character && this.numValue == code; }; Token.prototype.isNumber = function () { return this.type == TokenType.Number; }; Token.prototype.isString = function () { return this.type == TokenType.String; }; Token.prototype.isOperator = function (operater) { return this.type == TokenType.Operator && this.strValue == operater; }; Token.prototype.isIdentifier = function () { return this.type == TokenType.Identifier; }; Token.prototype.isKeyword = function () { return this.type == TokenType.Keyword; }; Token.prototype.isKeywordLet = function () { return this.type == TokenType.Keyword && this.strValue == 'let'; }; Token.prototype.isKeywordNull = function () { return this.type == TokenType.Keyword && this.strValue == 'null'; }; Token.prototype.isKeywordUndefined = function () { return this.type == TokenType.Keyword && this.strValue == 'undefined'; }; Token.prototype.isKeywordTrue = function () { return this.type == TokenType.Keyword && this.strValue == 'true'; }; Token.prototype.isKeywordFalse = function () { return this.type == TokenType.Keyword && this.strValue == 'false'; }; Token.prototype.isKeywordThis = function () { return this.type == TokenType.Keyword && this.strValue == 'this'; }; Token.prototype.isError = function () { return this.type == TokenType.Error; }; Token.prototype.toNumber = function () { return this.type == TokenType.Number ? this.numValue : -1; }; Token.prototype.toString = function () { switch (this.type) { case TokenType.Character: case TokenType.Identifier: case TokenType.Keyword: case TokenType.Operator: case TokenType.String: case TokenType.Error: return this.strValue; case TokenType.Number: return this.numValue.toString(); default: return null; } }; return Token; }()); function newCharacterToken(index, code) { return new Token(index, TokenType.Character, code, String.fromCharCode(code)); } function newIdentifierToken(index, text) { return new Token(index, TokenType.Identifier, 0, text); } function newKeywordToken(index, text) { return new Token(index, TokenType.Keyword, 0, text); } function newOperatorToken(index, text) { return new Token(index, TokenType.Operator, 0, text); } function newStringToken(index, text) { return new Token(index, TokenType.String, 0, text); } function newNumberToken(index, n) { return new Token(index, TokenType.Number, n, ''); } function newErrorToken(index, message) { return new Token(index, TokenType.Error, 0, message); } var EOF = new Token(-1, TokenType.Character, 0, ''); var _Scanner = (function () { function _Scanner(input) { this.input = input; this.peek = 0; this.index = -1; this.length = input.length; this.advance(); } _Scanner.prototype.advance = function () { this.peek = ++this.index >= this.length ? $EOF : this.input.charCodeAt(this.index); }; _Scanner.prototype.scanToken = function () { var input = this.input, length = this.length; var peek = this.peek, index = this.index; // Skip whitespace. while (peek <= $SPACE) { if (++index >= length) { peek = $EOF; break; } else { peek = input.charCodeAt(index); } } this.peek = peek; this.index = index; if (index >= length) { return null; } // Handle identifiers and numbers. if (isIdentifierStart(peek)) return this.scanIdentifier(); if (isDigit(peek)) return this.scanNumber(index); var start = index; switch (peek) { case $PERIOD: this.advance(); return isDigit(this.peek) ? this.scanNumber(start) : newCharacterToken(start, $PERIOD); case $LPAREN: case $RPAREN: case $LBRACE: case $RBRACE: case $LBRACKET: case $RBRACKET: case $COMMA: case $COLON: case $SEMICOLON: return this.scanCharacter(start, peek); case $SQ: case $DQ: return this.scanString(); case $HASH: case $PLUS: case $MINUS: case $STAR: case $SLASH: case $PERCENT: case $CARET: return this.scanOperator(start, String.fromCharCode(peek)); case $QUESTION: return this.scanComplexOperator(start, '?', $PERIOD, '.'); case $LT: case $GT: return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '='); case $BANG: case $EQ: return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '=', $EQ, '='); case $AMPERSAND: return this.scanComplexOperator(start, '&', $AMPERSAND, '&'); case $BAR: return this.scanComplexOperator(start, '|', $BAR, '|'); case $NBSP: while (isWhitespace(this.peek)) this.advance(); return this.scanToken(); } this.advance(); return this.error("Unexpected character [" + String.fromCharCode(peek) + "]", 0); }; _Scanner.prototype.scanCharacter = function (start, code) { this.advance(); return newCharacterToken(start, code); }; _Scanner.prototype.scanOperator = function (start, str) { this.advance(); return newOperatorToken(start, str); }; /** * Tokenize a 2/3 char long operator * * @param start start index in the expression * @param one first symbol (always part of the operator) * @param twoCode code point for the second symbol * @param two second symbol (part of the operator when the second code point matches) * @param threeCode code point for the third symbol * @param three third symbol (part of the operator when provided and matches source expression) * @returns {Token} */ _Scanner.prototype.scanComplexOperator = function (start, one, twoCode, two, threeCode, three) { this.advance(); var str = one; if (this.peek == twoCode) { this.advance(); str += two; } if (threeCode != null && this.peek == threeCode) { this.advance(); str += three; } return newOperatorToken(start, str); }; _Scanner.prototype.scanIdentifier = function () { var start = this.index; this.advance(); while (isIdentifierPart(this.peek)) this.advance(); var str = this.input.substring(start, this.index); return KEYWORDS.indexOf(str) > -1 ? newKeywordToken(start, str) : newIdentifierToken(start, str); }; _Scanner.prototype.scanNumber = function (start) { var simple = (this.index === start); this.advance(); // Skip initial digit. while (true) { if (isDigit(this.peek)) { // Do nothing. } else if (this.peek == $PERIOD) { simple = false; } else if (isExponentStart(this.peek)) { this.advance(); if (isExponentSign(this.peek)) this.advance(); if (!isDigit(this.peek)) return this.error('Invalid exponent', -1); simple = false; } else { break; } this.advance(); } var str = this.input.substring(start, this.index); var value = simple ? NumberWrapper.parseIntAutoRadix(str) : parseFloat(str); return newNumberToken(start, value); }; _Scanner.prototype.scanString = function () { var start = this.index; var quote = this.peek; this.advance(); // Skip initial quote. var buffer = ''; var marker = this.index; var input = this.input; while (this.peek != quote) { if (this.peek == $BACKSLASH) { buffer += input.substring(marker, this.index); this.advance(); var unescapedCode = void 0; // Workaround for TS2.1-introduced type strictness this.peek = this.peek; if (this.peek == $u) { // 4 character hex code for unicode character. var hex = input.substring(this.index + 1, this.index + 5); if (/^[0-9a-f]+$/i.test(hex)) { unescapedCode = parseInt(hex, 16); } else { return this.error("Invalid unicode escape [\\u" + hex + "]", 0); } for (var i = 0; i < 5; i++) { this.advance(); } } else { unescapedCode = unescape(this.peek); this.advance(); } buffer += String.fromCharCode(unescapedCode); marker = this.index; } else if (this.peek == $EOF) { return this.error('Unterminated quote', 0); } else { this.advance(); } } var last = input.substring(marker, this.index); this.advance(); // Skip terminating quote. return newStringToken(start, buffer + last); }; _Scanner.prototype.error = function (message, offset) { var position = this.index + offset; return newErrorToken(position, "Lexer Error: " + message + " at column " + position + " in expression [" + this.input + "]"); }; return _Scanner; }()); function isIdentifierStart(code) { return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || (code == $_) || (code == $$); } function isIdentifier(input) { 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) { return isAsciiLetter(code) || isDigit(code) || (code == $_) || (code == $$); } function isExponentStart(code) { return code == $e || code == $E; } function isExponentSign(code) { return code == $MINUS || code == $PLUS; } function isQuote(code) { return code === $SQ || code === $DQ || code === $BT; } function unescape(code) { switch (code) { case $n: return $LF; case $f: return $FF; case $r: return $CR; case $t: return $TAB; case $v: return $VTAB; default: return code; } } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var SplitInterpolation = (function () { function SplitInterpolation(strings, expressions, offsets) { this.strings = strings; this.expressions = expressions; this.offsets = offsets; } return SplitInterpolation; }()); var TemplateBindingParseResult = (function () { function TemplateBindingParseResult(templateBindings, warnings, errors) { this.templateBindings = templateBindings; this.warnings = warnings; this.errors = errors; } return TemplateBindingParseResult; }()); function _createInterpolateRegExp(config) { var pattern = escapeRegExp(config.start) + '([\\s\\S]*?)' + escapeRegExp(config.end); return new RegExp(pattern, 'g'); } var Parser = (function () { function Parser(_lexer) { this._lexer = _lexer; this.errors = []; } Parser.prototype.parseAction = function (input, location, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } this._checkNoInterpolation(input, location, interpolationConfig); var sourceToLex = this._stripComments(input); var tokens = this._lexer.tokenize(this._stripComments(input)); var ast = new _ParseAST(input, location, tokens, sourceToLex.length, true, this.errors, input.length - sourceToLex.length) .parseChain(); return new ASTWithSource(ast, input, location, this.errors); }; Parser.prototype.parseBinding = function (input, location, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } var ast = this._parseBindingAst(input, location, interpolationConfig); return new ASTWithSource(ast, input, location, this.errors); }; Parser.prototype.parseSimpleBinding = function (input, location, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } var ast = this._parseBindingAst(input, location, interpolationConfig); var errors = SimpleExpressionChecker.check(ast); if (errors.length > 0) { this._reportError("Host binding expression cannot contain " + errors.join(' '), input, location); } return new ASTWithSource(ast, input, location, this.errors); }; Parser.prototype._reportError = function (message, input, errLocation, ctxLocation) { this.errors.push(new ParserError(message, input, errLocation, ctxLocation)); }; Parser.prototype._parseBindingAst = function (input, location, interpolationConfig) { // Quotes expressions use 3rd-party expression language. We don't want to use // our lexer or parser for that, so we check for that ahead of time. var quote = this._parseQuote(input, location); if (isPresent(quote)) { return quote; } this._checkNoInterpolation(input, location, interpolationConfig); var sourceToLex = this._stripComments(input); var tokens = this._lexer.tokenize(sourceToLex); return new _ParseAST(input, location, tokens, sourceToLex.length, false, this.errors, input.length - sourceToLex.length) .parseChain(); }; Parser.prototype._parseQuote = function (input, location) { if (isBlank(input)) return null; var prefixSeparatorIndex = input.indexOf(':'); if (prefixSeparatorIndex == -1) return null; var prefix = input.substring(0, prefixSeparatorIndex).trim(); if (!isIdentifier(prefix)) return null; var uninterpretedExpression = input.substring(prefixSeparatorIndex + 1); return new Quote(new ParseSpan(0, input.length), prefix, uninterpretedExpression, location); }; Parser.prototype.parseTemplateBindings = function (prefixToken, input, location) { var tokens = this._lexer.tokenize(input); if (prefixToken) { // Prefix the tokens with the tokens from prefixToken but have them take no space (0 index). var prefixTokens = this._lexer.tokenize(prefixToken).map(function (t) { t.index = 0; return t; }); tokens.unshift.apply(tokens, prefixTokens); } return new _ParseAST(input, location, tokens, input.length, false, this.errors, 0) .parseTemplateBindings(); }; Parser.prototype.parseInterpolation = function (input, location, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } var split = this.splitInterpolation(input, location, interpolationConfig); if (split == null) return null; var expressions = []; for (var i = 0; i < split.expressions.length; ++i) { var expressionText = split.expressions[i]; var sourceToLex = this._stripComments(expressionText); var tokens = this._lexer.tokenize(this._stripComments(split.expressions[i])); var ast = new _ParseAST(input, location, tokens, sourceToLex.length, false, this.errors, split.offsets[i] + (expressionText.length - sourceToLex.length)) .parseChain(); expressions.push(ast); } return new ASTWithSource(new Interpolation(new ParseSpan(0, isBlank(input) ? 0 : input.length), split.strings, expressions), input, location, this.errors); }; Parser.prototype.splitInterpolation = function (input, location, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } var regexp = _createInterpolateRegExp(interpolationConfig); var parts = input.split(regexp); if (parts.length <= 1) { return null; } var strings = []; var expressions = []; var offsets = []; var offset = 0; for (var i = 0; i < parts.length; i++) { var part = parts[i]; if (i % 2 === 0) { // fixed string strings.push(part); offset += part.length; } else if (part.trim().length > 0) { offset += interpolationConfig.start.length; expressions.push(part); offsets.push(offset); offset += part.length + interpolationConfig.end.length; } else { this._reportError('Blank expressions are not allowed in interpolated strings', input, "at column " + this._findInterpolationErrorColumn(parts, i, interpolationConfig) + " in", location); expressions.push('$implict'); offsets.push(offset); } } return new SplitInterpolation(strings, expressions, offsets); }; Parser.prototype.wrapLiteralPrimitive = function (input, location) { return new ASTWithSource(new LiteralPrimitive(new ParseSpan(0, isBlank(input) ? 0 : input.length), input), input, location, this.errors); }; Parser.prototype._stripComments = function (input) { var i = this._commentStart(input); return isPresent(i) ? input.substring(0, i).trim() : input; }; Parser.prototype._commentStart = function (input) { var outerQuote = null; for (var i = 0; i < input.length - 1; i++) { var char = input.charCodeAt(i); var nextChar = input.charCodeAt(i + 1); if (char === $SLASH && nextChar == $SLASH && isBlank(outerQuote)) return i; if (outerQuote === char) { outerQuote = null; } else if (isBlank(outerQuote) && isQuote(char)) { outerQuote = char; } } return null; }; Parser.prototype._checkNoInterpolation = function (input, location, interpolationConfig) { var regexp = _createInterpolateRegExp(interpolationConfig); var parts = input.split(regexp); if (parts.length > 1) { this._reportError("Got interpolation (" + interpolationConfig.start + interpolationConfig.end + ") where expression was expected", input, "at column " + this._findInterpolationErrorColumn(parts, 1, interpolationConfig) + " in", location); } }; Parser.prototype._findInterpolationErrorColumn = function (parts, partInErrIdx, interpolationConfig) { var errLocation = ''; for (var j = 0; j < partInErrIdx; j++) { errLocation += j % 2 === 0 ? parts[j] : "" + interpolationConfig.start + parts[j] + interpolationConfig.end; } return errLocation.length; }; return Parser; }()); var _ParseAST = (function () { function _ParseAST(input, location, tokens, inputLength, parseAction, errors, offset) { this.input = input; this.location = location; this.tokens = tokens; this.inputLength = inputLength; this.parseAction = parseAction; this.errors = errors; this.offset = offset; this.rparensExpected = 0; this.rbracketsExpected = 0; this.rbracesExpected = 0; this.index = 0; } _ParseAST.prototype.peek = function (offset) { var i = this.index + offset; return i < this.tokens.length ? this.tokens[i] : EOF; }; Object.defineProperty(_ParseAST.prototype, "next", { get: function () { return this.peek(0); }, enumerable: true, configurable: true }); Object.defineProperty(_ParseAST.prototype, "inputIndex", { get: function () { return (this.index < this.tokens.length) ? this.next.index + this.offset : this.inputLength + this.offset; }, enumerable: true, configurable: true }); _ParseAST.prototype.span = function (start) { return new ParseSpan(start, this.inputIndex); }; _ParseAST.prototype.advance = function () { this.index++; }; _ParseAST.prototype.optionalCharacter = function (code) { if (this.next.isCharacter(code)) { this.advance(); return true; } else { return false; } }; _ParseAST.prototype.peekKeywordLet = function () { return this.next.isKeywordLet(); }; _ParseAST.prototype.expectCharacter = function (code) { if (this.optionalCharacter(code)) return; this.error("Missing expected " + String.fromCharCode(code)); }; _ParseAST.prototype.optionalOperator = function (op) { if (this.next.isOperator(op)) { this.advance(); return true; } else { return false; } }; _ParseAST.prototype.expectOperator = function (operator) { if (this.optionalOperator(operator)) return; this.error("Missing expected operator " + operator); }; _ParseAST.prototype.expectIdentifierOrKeyword = function () { var n = this.next; if (!n.isIdentifier() && !n.isKeyword()) { this.error("Unexpected token " + n + ", expected identifier or keyword"); return ''; } this.advance(); return n.toString(); }; _ParseAST.prototype.expectIdentifierOrKeywordOrString = function () { var n = this.next; if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) { this.error("Unexpected token " + n + ", expected identifier, keyword, or string"); return ''; } this.advance(); return n.toString(); }; _ParseAST.prototype.parseChain = function () { var exprs = []; var start = this.inputIndex; while (this.index < this.tokens.length) { var expr = this.parsePipe(); exprs.push(expr); if (this.optionalCharacter($SEMICOLON)) { if (!this.parseAction) { this.error('Binding expression cannot contain chained expression'); } while (this.optionalCharacter($SEMICOLON)) { } // read all semicolons } else if (this.index < this.tokens.length) { this.error("Unexpected token '" + this.next + "'"); } } if (exprs.length == 0) return new EmptyExpr(this.span(start)); if (exprs.length == 1) return exprs[0]; return new Chain(this.span(start), exprs); }; _ParseAST.prototype.parsePipe = function () { var result = this.parseExpression(); if (this.optionalOperator('|')) { if (this.parseAction) { this.error('Cannot have a pipe in an action expression'); } do { var name_1 = this.expectIdentifierOrKeyword(); var args = []; while (this.optionalCharacter($COLON)) { args.push(this.parseExpression()); } result = new BindingPipe(this.span(result.span.start), result, name_1, args); } while (this.optionalOperator('|')); } return result; }; _ParseAST.prototype.parseExpression = function () { return this.parseConditional(); }; _ParseAST.prototype.parseConditional = function () { var start = this.inputIndex; var result = this.parseLogicalOr(); if (this.optionalOperator('?')) { var yes = this.parsePipe(); var no = void 0; if (!this.optionalCharacter($COLON)) { var end = this.inputIndex; var expression = this.input.substring(start, end); this.error("Conditional expression " + expression + " requires all 3 expressions"); no = new EmptyExpr(this.span(start)); } else { no = this.parsePipe(); } return new Conditional(this.span(start), result, yes, no); } else { return result; } }; _ParseAST.prototype.parseLogicalOr = function () { // '||' var result = this.parseLogicalAnd(); while (this.optionalOperator('||')) { var right = this.parseLogicalAnd(); result = new Binary(this.span(result.span.start), '||', result, right); } return result; }; _ParseAST.prototype.parseLogicalAnd = function () { // '&&' var result = this.parseEquality(); while (this.optionalOperator('&&')) { var right = this.parseEquality(); result = new Binary(this.span(result.span.start), '&&', result, right); } return result; }; _ParseAST.prototype.parseEquality = function () { // '==','!=','===','!==' var result = this.parseRelational(); while (this.next.type == TokenType.Operator) { var operator = this.next.strValue; switch (operator) { case '==': case '===': case '!=': case '!==': this.advance(); var right = this.parseRelational(); result = new Binary(this.span(result.span.start), operator, result, right); continue; } break; } return result; }; _ParseAST.prototype.parseRelational = function () { // '<', '>', '<=', '>=' var result = this.parseAdditive(); while (this.next.type == TokenType.Operator) { var operator = this.next.strValue; switch (operator) { case '<': case '>': case '<=': case '>=': this.advance(); var right = this.parseAdditive(); result = new Binary(this.span(result.span.start), operator, result, right); continue; } break; } return result; }; _ParseAST.prototype.parseAdditive = function () { // '+', '-' var result = this.parseMultiplicative(); while (this.next.type == TokenType.Operator) { var operator = this.next.strValue; switch (operator) { case '+': case '-': this.advance(); var right = this.parseMultiplicative(); result = new Binary(this.span(result.span.start), operator, result, right); continue; } break; } return result; }; _ParseAST.prototype.parseMultiplicative = f