UNPKG

ngast

Version:

Parsing tools for Angular. The project is an abstraction over the Angular compiler which provides friendly interface.

1,181 lines (1,175 loc) 165 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/compiler-cli/src/ngtsc/transform'), require('typescript'), require('assert'), require('@angular/compiler'), require('@angular/compiler-cli'), require('@angular/compiler-cli/src/ngtsc/core'), require('@angular/compiler-cli/src/ngtsc/annotations'), require('@angular/compiler-cli/src/ngtsc/file_system'), require('@angular/compiler-cli/src/ngtsc/reflection'), require('@angular/compiler-cli/src/ngtsc/partial_evaluator'), require('@angular/compiler-cli/src/ngtsc/incremental'), require('@angular/compiler-cli/src/ngtsc/imports'), require('@angular/compiler-cli/src/ngtsc/metadata'), require('@angular/compiler-cli/src/ngtsc/scope'), require('@angular/compiler-cli/src/ngtsc/util/src/typescript'), require('@angular/compiler-cli/src/ngtsc/routing'), require('@angular/compiler-cli/src/ngtsc/cycles'), require('@angular/compiler-cli/src/ngtsc/resource'), require('@angular/compiler-cli/src/ngtsc/entry_point'), require('@angular/compiler-cli/src/ngtsc/perf'), require('@angular/compiler-cli/src/ngtsc/modulewithproviders'), require('@angular/compiler-cli/src/ngtsc/diagnostics'), require('path')) : typeof define === 'function' && define.amd ? define(['exports', '@angular/compiler-cli/src/ngtsc/transform', 'typescript', 'assert', '@angular/compiler', '@angular/compiler-cli', '@angular/compiler-cli/src/ngtsc/core', '@angular/compiler-cli/src/ngtsc/annotations', '@angular/compiler-cli/src/ngtsc/file_system', '@angular/compiler-cli/src/ngtsc/reflection', '@angular/compiler-cli/src/ngtsc/partial_evaluator', '@angular/compiler-cli/src/ngtsc/incremental', '@angular/compiler-cli/src/ngtsc/imports', '@angular/compiler-cli/src/ngtsc/metadata', '@angular/compiler-cli/src/ngtsc/scope', '@angular/compiler-cli/src/ngtsc/util/src/typescript', '@angular/compiler-cli/src/ngtsc/routing', '@angular/compiler-cli/src/ngtsc/cycles', '@angular/compiler-cli/src/ngtsc/resource', '@angular/compiler-cli/src/ngtsc/entry_point', '@angular/compiler-cli/src/ngtsc/perf', '@angular/compiler-cli/src/ngtsc/modulewithproviders', '@angular/compiler-cli/src/ngtsc/diagnostics', 'path'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ngast = {}, global.transform, global.typescript, global.assert, global.compiler, global.compilerCli, global.core, global.annotations, global.file_system, global.reflection, global.partial_evaluator, global.incremental, global.imports, global.metadata, global.scope, global.typescript$1, global.routing, global.cycles, global.resource, global.entry_point, global.perf, global.modulewithproviders, global.diagnostics, global.path)); }(this, (function (exports, transform, typescript, assert, compiler, compilerCli, core, annotations, file_system, reflection, partial_evaluator, incremental, imports, metadata, scope, typescript$1, routing, cycles, resource, entry_point, perf, modulewithproviders, diagnostics, path) { 'use strict'; var handlerName = { 'NgModule': 'NgModuleDecoratorHandler', 'Pipe': 'PipeDecoratorHandler', 'Injectable': 'InjectableDecoratorHandler', 'Directive': 'DirectiveDecoratorHandler', 'Component': 'ComponentDecoratorHandler' }; var filterByHandler = function (annotation) { return function (trait) { return trait.handler.name === handlerName[annotation]; }; }; var isAnalysed = function (trait) { return (trait === null || trait === void 0 ? void 0 : trait.state) === transform.TraitState.Analyzed || (trait === null || trait === void 0 ? void 0 : trait.state) === transform.TraitState.Resolved; }; var Symbol$1 = /** @class */ (function () { function Symbol(workspace, node) { this.workspace = workspace; this.node = node; } Object.defineProperty(Symbol.prototype, "name", { /** Name of the class */ get: function () { return this.node.name.getText(); }, enumerable: false, configurable: true }); Object.defineProperty(Symbol.prototype, "path", { /** Path where the class is declared */ get: function () { if (!this._path) { this._path = this.node.getSourceFile().fileName; } return this._path; }, enumerable: false, configurable: true }); Object.defineProperty(Symbol.prototype, "diagnostics", { /** Logs from @angular/compiler when something got wrong */ get: function () { var _a; return ((_a = this.trait) === null || _a === void 0 ? void 0 : _a.state) === transform.TraitState.Analyzed ? this.trait.analysisDiagnostics : null; }, enumerable: false, configurable: true }); Object.defineProperty(Symbol.prototype, "isAnalysed", { /** Check if the ClassDeclaration has been analyzed by the trait compiler */ get: function () { return isAnalysed(this.trait); }, enumerable: false, configurable: true }); Object.defineProperty(Symbol.prototype, "record", { /** The record of the ClassDeclaration in the trait compiler */ get: function () { return this.workspace.traitCompiler.recordFor(this.node); }, enumerable: false, configurable: true }); Object.defineProperty(Symbol.prototype, "analysis", { /** The result of the analysis. Specific per annotation */ get: function () { var _a; this.ensureAnalysis(); if (((_a = this.trait) === null || _a === void 0 ? void 0 : _a.state) === transform.TraitState.Analyzed) { var message = "An error occurred during analysis of \"" + this.name + "\": "; var error = this.diagnostics; throw new Error(message + error); } // As we analyzed the node above it should be ok... if (isAnalysed(this.trait)) { return this.trait.analysis; } else { throw new Error("Analysis for node " + this.name + " couldn't be completed"); } }, enumerable: false, configurable: true }); Object.defineProperty(Symbol.prototype, "trait", { get: function () { var _a; if (!this._trait) { this._trait = (_a = this.record) === null || _a === void 0 ? void 0 : _a.traits.find(filterByHandler(this.annotation)); } return this._trait; }, enumerable: false, configurable: true }); /** Analyse this specific ClassDeclaration */ Symbol.prototype.analyse = function () { this.workspace.traitCompiler.analyzeNode(this.node); this.workspace.traitCompiler.resolveNode(this.node); // @question should we record NgModule Scope dependencies here ??? }; Symbol.prototype.ensureAnalysis = function () { if (!this.record) { this.analyse(); } }; return Symbol; }()); var annotationNames = ['NgModule', 'Pipe', 'Injectable', 'Directive', 'Component']; var annotationTheta = { 'ɵmod': 'NgModule', 'ɵdir': 'Directive', 'ɵinj': 'Injectable', 'ɵpipe': 'Pipe', 'ɵcmp': 'Component', }; function getDecoratorName(decorator) { var expression = decorator.expression; return typescript.isCallExpression(expression) && expression.expression.getText(); } /** Verify if class is decorated with an annotation */ function hasLocalAnnotation(node, name) { var _a; return (_a = node.decorators) === null || _a === void 0 ? void 0 : _a.some(function (decorator) { return getDecoratorName(decorator) === name; }); } /** Vrify if the dts class has the static annotation */ function hasDtsAnnotation(members, name) { return members === null || members === void 0 ? void 0 : members.some(function (m) { return m.isStatic && m.name in annotationTheta; }); } /** Get the name of the annotation of the local class if any */ function getLocalAnnotation(decorators) { return decorators === null || decorators === void 0 ? void 0 : decorators.map(getDecoratorName).find(function (name) { return annotationNames.includes(name); }); } /** Ge the name of the annotation of a dts class if any */ function getDtsAnnotation(members) { var member = members === null || members === void 0 ? void 0 : members.find(function (m) { return m.isStatic && m.name in annotationTheta; }); return member ? annotationTheta[member.name] : undefined; } function assertDeps(deps, name) { if (!deps || deps === 'invalid') { throw new assert.AssertionError({ message: "Invalid depenancies in \"" + name + "\"." }); } } var exists = function (value) { return !!(value !== null && value !== void 0 ? value : false); }; /** * @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 $EQ = 61; var $GT = 62; var $QUESTION = 63; var $0 = 48; var $9 = 57; var $A = 65; var $Z = 90; var $LBRACKET = 91; var $BACKSLASH = 92; var $RBRACKET = 93; var $CARET = 94; var $_ = 95; var $a = 97; var $z = 122; var $LBRACE = 123; var $RBRACE = 125; var $NBSP = 160; var $PIPE = 124; var $TILDA = 126; var $AT = 64; 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 ParseLocation = /** @class */ (function () { function ParseLocation(file, offset, line, col) { this.file = file; this.offset = offset; this.line = line; this.col = col; } ParseLocation.prototype.toString = function () { return this.offset != null ? this.file.url + "@" + this.line + ":" + this.col : this.file.url; }; ParseLocation.prototype.moveBy = function (delta) { var source = this.file.content; var len = source.length; var offset = this.offset; var line = this.line; var col = this.col; while (offset > 0 && delta < 0) { offset--; delta++; var ch = source.charCodeAt(offset); if (ch == $LF) { line--; var priorLine = source.substr(0, offset - 1).lastIndexOf(String.fromCharCode($LF)); col = priorLine > 0 ? offset - priorLine : offset; } else { col--; } } while (offset < len && delta > 0) { var ch = source.charCodeAt(offset); offset++; delta--; if (ch == $LF) { line++; col = 0; } else { col++; } } return new ParseLocation(this.file, offset, line, col); }; // Return the source around the location // Up to `maxChars` or `maxLines` on each side of the location ParseLocation.prototype.getContext = function (maxChars, maxLines) { var content = this.file.content; var startOffset = this.offset; if (startOffset != null) { if (startOffset > content.length - 1) { startOffset = content.length - 1; } var endOffset = startOffset; var ctxChars = 0; var ctxLines = 0; while (ctxChars < maxChars && startOffset > 0) { startOffset--; ctxChars++; if (content[startOffset] == '\n') { if (++ctxLines == maxLines) { break; } } } ctxChars = 0; ctxLines = 0; while (ctxChars < maxChars && endOffset < content.length - 1) { endOffset++; ctxChars++; if (content[endOffset] == '\n') { if (++ctxLines == maxLines) { break; } } } return { before: content.substring(startOffset, this.offset), after: content.substring(this.offset, endOffset + 1), }; } return null; }; return ParseLocation; }()); var ParseSourceFile = /** @class */ (function () { function ParseSourceFile(content, url) { this.content = content; this.url = url; } return ParseSourceFile; }()); var ParseSourceSpan = /** @class */ (function () { function ParseSourceSpan(start, end, details) { if (details === void 0) { details = null; } this.start = start; this.end = end; this.details = details; } ParseSourceSpan.prototype.toString = function () { return this.start.file.content.substring(this.start.offset, this.end.offset); }; return ParseSourceSpan; }()); var ParseErrorLevel; (function (ParseErrorLevel) { ParseErrorLevel[ParseErrorLevel["WARNING"] = 0] = "WARNING"; ParseErrorLevel[ParseErrorLevel["ERROR"] = 1] = "ERROR"; })(ParseErrorLevel || (ParseErrorLevel = {})); var ParseError = /** @class */ (function () { function ParseError(span, msg, level) { if (level === void 0) { level = ParseErrorLevel.ERROR; } this.span = span; this.msg = msg; this.level = level; } ParseError.prototype.toString = function () { var ctx = this.span.start.getContext(100, 3); var contextStr = ctx ? " (\"" + ctx.before + "[" + ParseErrorLevel[this.level] + " ->]" + ctx.after + "\")" : ''; var details = this.span.details ? ", " + this.span.details : ''; return "" + this.msg + contextStr + ": " + this.span.start + details; }; return ParseError; }()); /** * @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 CssTokenType; (function (CssTokenType) { CssTokenType[CssTokenType["EOF"] = 0] = "EOF"; CssTokenType[CssTokenType["String"] = 1] = "String"; CssTokenType[CssTokenType["Comment"] = 2] = "Comment"; CssTokenType[CssTokenType["Identifier"] = 3] = "Identifier"; CssTokenType[CssTokenType["Number"] = 4] = "Number"; CssTokenType[CssTokenType["IdentifierOrNumber"] = 5] = "IdentifierOrNumber"; CssTokenType[CssTokenType["AtKeyword"] = 6] = "AtKeyword"; CssTokenType[CssTokenType["Character"] = 7] = "Character"; CssTokenType[CssTokenType["Whitespace"] = 8] = "Whitespace"; CssTokenType[CssTokenType["Invalid"] = 9] = "Invalid"; })(CssTokenType || (CssTokenType = {})); var CssLexerMode; (function (CssLexerMode) { CssLexerMode[CssLexerMode["ALL"] = 0] = "ALL"; CssLexerMode[CssLexerMode["ALL_TRACK_WS"] = 1] = "ALL_TRACK_WS"; CssLexerMode[CssLexerMode["SELECTOR"] = 2] = "SELECTOR"; CssLexerMode[CssLexerMode["PSEUDO_SELECTOR"] = 3] = "PSEUDO_SELECTOR"; CssLexerMode[CssLexerMode["PSEUDO_SELECTOR_WITH_ARGUMENTS"] = 4] = "PSEUDO_SELECTOR_WITH_ARGUMENTS"; CssLexerMode[CssLexerMode["ATTRIBUTE_SELECTOR"] = 5] = "ATTRIBUTE_SELECTOR"; CssLexerMode[CssLexerMode["AT_RULE_QUERY"] = 6] = "AT_RULE_QUERY"; CssLexerMode[CssLexerMode["MEDIA_QUERY"] = 7] = "MEDIA_QUERY"; CssLexerMode[CssLexerMode["BLOCK"] = 8] = "BLOCK"; CssLexerMode[CssLexerMode["KEYFRAME_BLOCK"] = 9] = "KEYFRAME_BLOCK"; CssLexerMode[CssLexerMode["STYLE_BLOCK"] = 10] = "STYLE_BLOCK"; CssLexerMode[CssLexerMode["STYLE_VALUE"] = 11] = "STYLE_VALUE"; CssLexerMode[CssLexerMode["STYLE_VALUE_FUNCTION"] = 12] = "STYLE_VALUE_FUNCTION"; CssLexerMode[CssLexerMode["STYLE_CALC_FUNCTION"] = 13] = "STYLE_CALC_FUNCTION"; })(CssLexerMode || (CssLexerMode = {})); var LexedCssResult = /** @class */ (function () { function LexedCssResult(error, token) { this.error = error; this.token = token; } return LexedCssResult; }()); function generateErrorMessage(input, message, errorValue, index, row, column) { return message + " at column " + row + ":" + column + " in expression [" + findProblemCode(input, errorValue, index, column) + ']'; } function findProblemCode(input, errorValue, index, column) { var endOfProblemLine = index; var current = charCode(input, index); while (current > 0 && !isNewline(current)) { current = charCode(input, ++endOfProblemLine); } var choppedString = input.substring(0, endOfProblemLine); var pointerPadding = ''; for (var i = 0; i < column; i++) { pointerPadding += ' '; } var pointerString = ''; for (var i = 0; i < errorValue.length; i++) { pointerString += '^'; } return choppedString + '\n' + pointerPadding + pointerString + '\n'; } var CssToken = /** @class */ (function () { function CssToken(index, column, line, type, strValue) { this.index = index; this.column = column; this.line = line; this.type = type; this.strValue = strValue; this.numValue = charCode(strValue, 0); } return CssToken; }()); var CssLexer = /** @class */ (function () { function CssLexer() { } CssLexer.prototype.scan = function (text, trackComments) { if (trackComments === void 0) { trackComments = false; } return new CssScanner(text, trackComments); }; return CssLexer; }()); function cssScannerError(token, message) { var error = Error('CssParseError: ' + message); error[ERROR_RAW_MESSAGE] = message; error[ERROR_TOKEN] = token; return error; } var ERROR_TOKEN = 'ngToken'; var ERROR_RAW_MESSAGE = 'ngRawMessage'; function getRawMessage(error) { return error[ERROR_RAW_MESSAGE]; } function _trackWhitespace(mode) { switch (mode) { case CssLexerMode.SELECTOR: case CssLexerMode.PSEUDO_SELECTOR: case CssLexerMode.ALL_TRACK_WS: case CssLexerMode.STYLE_VALUE: return true; default: return false; } } var CssScanner = /** @class */ (function () { function CssScanner(input, _trackComments) { if (_trackComments === void 0) { _trackComments = false; } this.input = input; this._trackComments = _trackComments; this.length = 0; this.index = -1; this.column = -1; this.line = 0; /** @internal */ this._currentMode = CssLexerMode.BLOCK; /** @internal */ this._currentError = null; this.length = this.input.length; this.peekPeek = this.peekAt(0); this.advance(); } CssScanner.prototype.getMode = function () { return this._currentMode; }; CssScanner.prototype.setMode = function (mode) { if (this._currentMode != mode) { if (_trackWhitespace(this._currentMode) && !_trackWhitespace(mode)) { this.consumeWhitespace(); } this._currentMode = mode; } }; CssScanner.prototype.advance = function () { if (isNewline(this.peek)) { this.column = 0; this.line++; } else { this.column++; } this.index++; this.peek = this.peekPeek; this.peekPeek = this.peekAt(this.index + 1); }; CssScanner.prototype.peekAt = function (index) { return index >= this.length ? $EOF : this.input.charCodeAt(index); }; CssScanner.prototype.consumeEmptyStatements = function () { this.consumeWhitespace(); while (this.peek == $SEMICOLON) { this.advance(); this.consumeWhitespace(); } }; CssScanner.prototype.consumeWhitespace = function () { while (isWhitespace(this.peek) || isNewline(this.peek)) { this.advance(); if (!this._trackComments && isCommentStart(this.peek, this.peekPeek)) { this.advance(); // / this.advance(); // * while (!isCommentEnd(this.peek, this.peekPeek)) { if (this.peek == $EOF) { this.error('Unterminated comment'); } this.advance(); } this.advance(); // * this.advance(); // / } } }; CssScanner.prototype.consume = function (type, value) { if (value === void 0) { value = null; } var mode = this._currentMode; this.setMode(_trackWhitespace(mode) ? CssLexerMode.ALL_TRACK_WS : CssLexerMode.ALL); var previousIndex = this.index; var previousLine = this.line; var previousColumn = this.column; var next = undefined; var output = this.scan(); if (output != null) { // just incase the inner scan method returned an error if (output.error != null) { this.setMode(mode); return output; } next = output.token; } if (next == null) { next = new CssToken(this.index, this.column, this.line, CssTokenType.EOF, 'end of file'); } var isMatchingType = false; if (type == CssTokenType.IdentifierOrNumber) { // TODO (matsko): implement array traversal for lookup here isMatchingType = next.type == CssTokenType.Number || next.type == CssTokenType.Identifier; } else { isMatchingType = next.type == type; } // before throwing the error we need to bring back the former // mode so that the parser can recover... this.setMode(mode); var error = null; if (!isMatchingType || (value != null && value != next.strValue)) { var errorMessage = CssTokenType[next.type] + ' does not match expected ' + CssTokenType[type] + ' value'; if (value != null) { errorMessage += ' ("' + next.strValue + '" should match "' + value + '")'; } error = cssScannerError(next, generateErrorMessage(this.input, errorMessage, next.strValue, previousIndex, previousLine, previousColumn)); } return new LexedCssResult(error, next); }; CssScanner.prototype.scan = function () { var trackWS = _trackWhitespace(this._currentMode); if (this.index == 0 && !trackWS) { // first scan this.consumeWhitespace(); } var token = this._scan(); if (token == null) return null; var error = this._currentError; this._currentError = null; if (!trackWS) { this.consumeWhitespace(); } return new LexedCssResult(error, token); }; /** @internal */ CssScanner.prototype._scan = function () { var peek = this.peek; var peekPeek = this.peekPeek; if (peek == $EOF) return null; if (isCommentStart(peek, peekPeek)) { // even if comments are not tracked we still lex the // comment so we can move the pointer forward var commentToken = this.scanComment(); if (this._trackComments) { return commentToken; } } if (_trackWhitespace(this._currentMode) && (isWhitespace(peek) || isNewline(peek))) { return this.scanWhitespace(); } peek = this.peek; peekPeek = this.peekPeek; if (peek == $EOF) return null; if (isStringStart(peek, peekPeek)) { return this.scanString(); } // something like url(cool) if (this._currentMode == CssLexerMode.STYLE_VALUE_FUNCTION) { return this.scanCssValueFunction(); } var isModifier = peek == $PLUS || peek == $MINUS; var digitA = isModifier ? false : isDigit(peek); var digitB = isDigit(peekPeek); if (digitA || (isModifier && (peekPeek == $PERIOD || digitB)) || (peek == $PERIOD && digitB)) { return this.scanNumber(); } if (peek == $AT) { return this.scanAtExpression(); } if (isIdentifierStart(peek, peekPeek)) { return this.scanIdentifier(); } if (isValidCssCharacter(peek, this._currentMode)) { return this.scanCharacter(); } return this.error("Unexpected character [" + String.fromCharCode(peek) + "]"); }; CssScanner.prototype.scanComment = function () { if (this.assertCondition(isCommentStart(this.peek, this.peekPeek), 'Expected comment start value')) { return null; } var start = this.index; var startingColumn = this.column; var startingLine = this.line; this.advance(); // / this.advance(); // * while (!isCommentEnd(this.peek, this.peekPeek)) { if (this.peek == $EOF) { this.error('Unterminated comment'); } this.advance(); } this.advance(); // * this.advance(); // / var str = this.input.substring(start, this.index); return new CssToken(start, startingColumn, startingLine, CssTokenType.Comment, str); }; CssScanner.prototype.scanWhitespace = function () { var start = this.index; var startingColumn = this.column; var startingLine = this.line; while (isWhitespace(this.peek) && this.peek != $EOF) { this.advance(); } var str = this.input.substring(start, this.index); return new CssToken(start, startingColumn, startingLine, CssTokenType.Whitespace, str); }; CssScanner.prototype.scanString = function () { if (this.assertCondition(isStringStart(this.peek, this.peekPeek), 'Unexpected non-string starting value')) { return null; } var target = this.peek; var start = this.index; var startingColumn = this.column; var startingLine = this.line; var previous = target; this.advance(); while (!isCharMatch(target, previous, this.peek)) { if (this.peek == $EOF || isNewline(this.peek)) { this.error('Unterminated quote'); } previous = this.peek; this.advance(); } if (this.assertCondition(this.peek == target, 'Unterminated quote')) { return null; } this.advance(); var str = this.input.substring(start, this.index); return new CssToken(start, startingColumn, startingLine, CssTokenType.String, str); }; CssScanner.prototype.scanNumber = function () { var start = this.index; var startingColumn = this.column; if (this.peek == $PLUS || this.peek == $MINUS) { this.advance(); } var periodUsed = false; while (isDigit(this.peek) || this.peek == $PERIOD) { if (this.peek == $PERIOD) { if (periodUsed) { this.error('Unexpected use of a second period value'); } periodUsed = true; } this.advance(); } var strValue = this.input.substring(start, this.index); return new CssToken(start, startingColumn, this.line, CssTokenType.Number, strValue); }; CssScanner.prototype.scanIdentifier = function () { if (this.assertCondition(isIdentifierStart(this.peek, this.peekPeek), 'Expected identifier starting value')) { return null; } var start = this.index; var startingColumn = this.column; while (isIdentifierPart(this.peek)) { this.advance(); } var strValue = this.input.substring(start, this.index); return new CssToken(start, startingColumn, this.line, CssTokenType.Identifier, strValue); }; CssScanner.prototype.scanCssValueFunction = function () { var start = this.index; var startingColumn = this.column; var parenBalance = 1; while (this.peek != $EOF && parenBalance > 0) { this.advance(); if (this.peek == $LPAREN) { parenBalance++; } else if (this.peek == $RPAREN) { parenBalance--; } } var strValue = this.input.substring(start, this.index); return new CssToken(start, startingColumn, this.line, CssTokenType.Identifier, strValue); }; CssScanner.prototype.scanCharacter = function () { var start = this.index; var startingColumn = this.column; if (this.assertCondition(isValidCssCharacter(this.peek, this._currentMode), charStr(this.peek) + ' is not a valid CSS character')) { return null; } var c = this.input.substring(start, start + 1); this.advance(); return new CssToken(start, startingColumn, this.line, CssTokenType.Character, c); }; CssScanner.prototype.scanAtExpression = function () { if (this.assertCondition(this.peek == $AT, 'Expected @ value')) { return null; } var start = this.index; var startingColumn = this.column; this.advance(); if (isIdentifierStart(this.peek, this.peekPeek)) { var ident = this.scanIdentifier(); var strValue = '@' + ident.strValue; return new CssToken(start, startingColumn, this.line, CssTokenType.AtKeyword, strValue); } else { return this.scanCharacter(); } }; CssScanner.prototype.assertCondition = function (status, errorMessage) { if (!status) { this.error(errorMessage); return true; } return false; }; CssScanner.prototype.error = function (message, errorTokenValue, doNotAdvance) { if (errorTokenValue === void 0) { errorTokenValue = null; } if (doNotAdvance === void 0) { doNotAdvance = false; } var index = this.index; var column = this.column; var line = this.line; errorTokenValue = errorTokenValue || String.fromCharCode(this.peek); var invalidToken = new CssToken(index, column, line, CssTokenType.Invalid, errorTokenValue); var errorMessage = generateErrorMessage(this.input, message, errorTokenValue, index, line, column); if (!doNotAdvance) { this.advance(); } this._currentError = cssScannerError(invalidToken, errorMessage); return invalidToken; }; return CssScanner; }()); function isCharMatch(target, previous, code) { return code == target && previous != $BACKSLASH; } function isCommentStart(code, next) { return code == $SLASH && next == $STAR; } function isCommentEnd(code, next) { return code == $STAR && next == $SLASH; } function isStringStart(code, next) { var target = code; if (target == $BACKSLASH) { target = next; } return target == $DQ || target == $SQ; } function isIdentifierStart(code, next) { var target = code; if (target == $MINUS) { target = next; } return isAsciiLetter(target) || target == $BACKSLASH || target == $MINUS || target == $_; } function isIdentifierPart(target) { return isAsciiLetter(target) || target == $BACKSLASH || target == $MINUS || target == $_ || isDigit(target); } function isValidPseudoSelectorCharacter(code) { switch (code) { case $LPAREN: case $RPAREN: return true; default: return false; } } function isValidKeyframeBlockCharacter(code) { return code == $PERCENT; } function isValidAttributeSelectorCharacter(code) { // value^*|$~=something switch (code) { case $$: case $PIPE: case $CARET: case $TILDA: case $STAR: case $EQ: return true; default: return false; } } function isValidSelectorCharacter(code) { // selector [ key = value ] // IDENT C IDENT C IDENT C // #id, .class, *+~> // tag:PSEUDO switch (code) { case $HASH: case $PERIOD: case $TILDA: case $STAR: case $PLUS: case $GT: case $COLON: case $PIPE: case $COMMA: case $LBRACKET: case $RBRACKET: return true; default: return false; } } function isValidStyleBlockCharacter(code) { // key:value; // key:calc(something ... ) switch (code) { case $HASH: case $SEMICOLON: case $COLON: case $PERCENT: case $SLASH: case $BACKSLASH: case $BANG: case $PERIOD: case $LPAREN: case $RPAREN: return true; default: return false; } } function isValidMediaQueryRuleCharacter(code) { // (min-width: 7.5em) and (orientation: landscape) switch (code) { case $LPAREN: case $RPAREN: case $COLON: case $PERCENT: case $PERIOD: return true; default: return false; } } function isValidAtRuleCharacter(code) { // @document url(http://www.w3.org/page?something=on#hash), switch (code) { case $LPAREN: case $RPAREN: case $COLON: case $PERCENT: case $PERIOD: case $SLASH: case $BACKSLASH: case $HASH: case $EQ: case $QUESTION: case $AMPERSAND: case $STAR: case $COMMA: case $MINUS: case $PLUS: return true; default: return false; } } function isValidStyleFunctionCharacter(code) { switch (code) { case $PERIOD: case $MINUS: case $PLUS: case $STAR: case $SLASH: case $LPAREN: case $RPAREN: case $COMMA: return true; default: return false; } } function isValidBlockCharacter(code) { // @something { } // IDENT return code == $AT; } function isValidCssCharacter(code, mode) { switch (mode) { case CssLexerMode.ALL: case CssLexerMode.ALL_TRACK_WS: return true; case CssLexerMode.SELECTOR: return isValidSelectorCharacter(code); case CssLexerMode.PSEUDO_SELECTOR_WITH_ARGUMENTS: return isValidPseudoSelectorCharacter(code); case CssLexerMode.ATTRIBUTE_SELECTOR: return isValidAttributeSelectorCharacter(code); case CssLexerMode.MEDIA_QUERY: return isValidMediaQueryRuleCharacter(code); case CssLexerMode.AT_RULE_QUERY: return isValidAtRuleCharacter(code); case CssLexerMode.KEYFRAME_BLOCK: return isValidKeyframeBlockCharacter(code); case CssLexerMode.STYLE_BLOCK: case CssLexerMode.STYLE_VALUE: return isValidStyleBlockCharacter(code); case CssLexerMode.STYLE_CALC_FUNCTION: return isValidStyleFunctionCharacter(code); case CssLexerMode.BLOCK: return isValidBlockCharacter(code); default: return false; } } function charCode(input, index) { return index >= input.length ? $EOF : input.charCodeAt(index); } function charStr(code) { return String.fromCharCode(code); } function isNewline(code) { switch (code) { case $FF: case $CR: case $LF: case $VTAB: return true; default: return false; } } /** * @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 = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var BlockType; (function (BlockType) { BlockType[BlockType["Import"] = 0] = "Import"; BlockType[BlockType["Charset"] = 1] = "Charset"; BlockType[BlockType["Namespace"] = 2] = "Namespace"; BlockType[BlockType["Supports"] = 3] = "Supports"; BlockType[BlockType["Keyframes"] = 4] = "Keyframes"; BlockType[BlockType["MediaQuery"] = 5] = "MediaQuery"; BlockType[BlockType["Selector"] = 6] = "Selector"; BlockType[BlockType["FontFace"] = 7] = "FontFace"; BlockType[BlockType["Page"] = 8] = "Page"; BlockType[BlockType["Document"] = 9] = "Document"; BlockType[BlockType["Viewport"] = 10] = "Viewport"; BlockType[BlockType["Unsupported"] = 11] = "Unsupported"; })(BlockType || (BlockType = {})); var CssAst = /** @class */ (function () { function CssAst(location) { this.location = location; } Object.defineProperty(CssAst.prototype, "start", { get: function () { return this.location.start; }, enumerable: false, configurable: true }); Object.defineProperty(CssAst.prototype, "end", { get: function () { return this.location.end; }, enumerable: false, configurable: true }); return CssAst; }()); var CssStyleValueAst = /** @class */ (function (_super) { __extends(CssStyleValueAst, _super); function CssStyleValueAst(location, tokens, strValue) { var _this = _super.call(this, location) || this; _this.tokens = tokens; _this.strValue = strValue; return _this; } CssStyleValueAst.prototype.visit = function (visitor, context) { return visitor.visitCssValue(this); }; return CssStyleValueAst; }(CssAst)); var CssRuleAst = /** @class */ (function (_super) { __extends(CssRuleAst, _super); function CssRuleAst(location) { return _super.call(this, location) || this; } return CssRuleAst; }(CssAst)); var CssBlockRuleAst = /** @class */ (function (_super) { __extends(CssBlockRuleAst, _super); function CssBlockRuleAst(location, type, block, name) { if (name === void 0) { name = null; } var _this = _super.call(this, location) || this; _this.location = location; _this.type = type; _this.block = block; _this.name = name; return _this; } CssBlockRuleAst.prototype.visit = function (visitor, context) { return visitor.visitCssBlock(this.block, context); }; return CssBlockRuleAst; }(CssRuleAst)); var CssKeyframeRuleAst = /** @class */ (function (_super) { __extends(CssKeyframeRuleAst, _super); function CssKeyframeRuleAst(location, name, block) { return _super.call(this, location, BlockType.Keyframes, block, name) || this; } CssKeyframeRuleAst.prototype.visit = function (visitor, context) { return visitor.visitCssKeyframeRule(this, context); }; return CssKeyframeRuleAst; }(CssBlockRuleAst)); var CssKeyframeDefinitionAst = /** @class */ (function (_super) { __extends(CssKeyframeDefinitionAst, _super); function CssKeyframeDefinitionAst(location, steps, block) { var _this = _super.call(this, location, BlockType.Keyframes, block, mergeTokens(steps, ',')) || this; _this.steps = steps; return _this; } CssKeyframeDefinitionAst.prototype.visit = function (visitor, context) { return visitor.visitCssKeyframeDefinition(this, context); }; return CssKeyframeDefinitionAst; }(CssBlockRuleAst)); var CssBlockDefinitionRuleAst = /** @class */ (function (_super) { __extends(CssBlockDefinitionRuleAst, _super); function CssBlockDefinitionRuleAst(location, strValue, type, query, block) { var _this = _super.call(this, location, type, block) || this; _this.strValue = strValue; _this.query = query; var firstCssToken = query.tokens[0]; _this.name = new CssToken(firstCssToken.index, firstCssToken.column, firstCssToken.line, CssTokenType.Identifier, _this.strValue); return _this; } CssBlockDefinitionRuleAst.prototype.visit = function (visitor, context) { return visitor.visitCssBlock(this.block, context); }; return CssBlockDefinitionRuleAst; }(CssBlockRuleAst)); var CssMediaQueryRuleAst = /** @class */ (function (_super) { __extends(CssMediaQueryRuleAst, _super); function CssMediaQueryRuleAst(location, strValue, query, block) { return _super.call(this, location, strValue, BlockType.MediaQuery, query, block) || this; } CssMediaQueryRuleAst.prototype.visit = function (visitor, context) { return visitor.visitCssMediaQueryRule(this, context); }; return CssMediaQueryRuleAst; }(CssBlockDefinitionRuleAst)); var CssAtRulePredicateAst = /** @class */ (function (_super) { __extends(CssAtRulePredicateAst, _super); function CssAtRulePredicateAst(location, strValue, tokens) { var _this = _super.call(this, location) || this; _this.strValue = strValue; _this.tokens = tokens; return _this; } CssAtRulePredicateAst.prototype.visit = function (visitor, context) { return visitor.visitCssAtRulePredicate(this, context); }; return CssAtRulePredicateAst; }(CssAst)); var CssInlineRuleAst = /** @class */ (function (_super) { __extends(CssInlineRuleAst, _super); function CssInlineRuleAst(location, type, value) { var _this = _super.call(this, location) || this; _this.type = type; _this.value = value; return _this; } CssInlineRuleAst.prototype.visit = function (visitor, context) { return visitor.visitCssInlineRule(this, context); }; return CssInlineRuleAst; }(CssRuleAst)); var CssSelectorRuleAst = /** @class */ (function (_super) { __extends(CssSelectorRuleAst, _super); function CssSelectorRuleAst(location, selectors, block) { var _this = _super.call(this, location, BlockType.Selector, block) || this; _this.selectors = selectors; _this.strValue = selectors.map(function (selector) { return selector.strValue; }).join(','); return _this; } CssSelectorRuleAst.prototype.visit = function (visitor, context) { return visitor.visitCssSelectorRule(this, context); }; return CssSelectorRuleAst; }(CssBlockRuleAst)); var CssDefinitionAst = /** @class */ (function (_super) { __extends(CssDefinitionAst, _super); function CssDefinitionAst(location, property, value) { var _this = _super.call(this, location) || this; _this.property = property; _this.value = value; return _this; } CssDefinitionAst.prototype.visit = function (visitor, context) { return visitor.visitCssDefinition(this, context); }; return CssDefinitionAst; }(CssAst)); var CssSelectorPartAst = /** @class */ (function (_super) { __extends(CssSelectorPartAst, _super); function CssSelectorPartAst(location) { return _super.call(this, location) || this; } return CssSelectorPartAst; }(CssAst)); var CssSelectorAst = /** @class */ (function (_super) { __extends(CssSelectorAst, _super); function CssSelectorAst(location, selectorParts) { var _this = _super.call(this, location) || this; _this.selectorParts = selectorParts; _this.strValue = selectorParts.map(function (part) { return part.strValue; }).join(''); return _this; } CssSelectorAst.prototype.visit = function (visitor, context) { return visitor.visitCssSelector(this, context); }; return CssSelectorAst; }(CssSelectorPartAst)); var CssSimpleSelectorAst = /** @class */ (function (_super) { __extends(CssSimpleSelectorAst, _super); function CssSimpleSelectorAst(location, tokens, strValue, pseudoSelectors, operator) { var _this = _super.call(this, location) || this; _this.tokens = tokens; _this.strValue = strValue; _this.pseudoSelectors = pseudoSelectors; _this.operator = operator; return _this; } CssSimpleSelectorAst.prototype.visit = function (visitor, context) { return