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
JavaScript
(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