UNPKG

@angular/language-service

Version:
1,319 lines (1,303 loc) • 18.9 MB
/** * @license Angular v17.0.4 * Copyright Google LLC All Rights Reserved. * License: MIT */ let $deferred; function define(modules, callback) { $deferred = {modules, callback}; } module.exports = function(provided) { const ts = provided['typescript']; if (!ts) { throw new Error('Caller does not provide typescript module'); } const results = {}; const resolvedModules = $deferred.modules.map(m => { if (m === 'exports') { return results; } if (m === 'typescript' || m === 'typescript/lib/tsserverlibrary') { return ts; } return require(m); }); $deferred.callback(...resolvedModules); return results; }; define(['module', 'exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', 'module', 'path', 'url'], (function (module, exports, ts$1, os, ts, fs$1, module$1, p, url) { 'use strict'; function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var ts__default$1 = /*#__PURE__*/_interopDefaultLegacy(ts$1); var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts); var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs$1); var module__default = /*#__PURE__*/_interopDefaultLegacy(module$1); var p__namespace = /*#__PURE__*/_interopNamespace(p); /** * @license * Copyright Google LLC 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 isNgLanguageService(ls) { return 'getTcb' in ls; } /** * The default `FileSystem` that will always fail. * * This is a way of ensuring that the developer consciously chooses and * configures the `FileSystem` before using it; particularly important when * considering static functions like `absoluteFrom()` which rely on * the `FileSystem` under the hood. */ class InvalidFileSystem { exists(path) { throw makeError(); } readFile(path) { throw makeError(); } readFileBuffer(path) { throw makeError(); } writeFile(path, data, exclusive) { throw makeError(); } removeFile(path) { throw makeError(); } symlink(target, path) { throw makeError(); } readdir(path) { throw makeError(); } lstat(path) { throw makeError(); } stat(path) { throw makeError(); } pwd() { throw makeError(); } chdir(path) { throw makeError(); } extname(path) { throw makeError(); } copyFile(from, to) { throw makeError(); } moveFile(from, to) { throw makeError(); } ensureDir(path) { throw makeError(); } removeDeep(path) { throw makeError(); } isCaseSensitive() { throw makeError(); } resolve(...paths) { throw makeError(); } dirname(file) { throw makeError(); } join(basePath, ...paths) { throw makeError(); } isRoot(path) { throw makeError(); } isRooted(path) { throw makeError(); } relative(from, to) { throw makeError(); } basename(filePath, extension) { throw makeError(); } realpath(filePath) { throw makeError(); } getDefaultLibLocation() { throw makeError(); } normalize(path) { throw makeError(); } } function makeError() { return new Error('FileSystem has not been configured. Please call `setFileSystem()` before calling this method.'); } const TS_DTS_JS_EXTENSION = /(?:\.d)?\.ts$|\.js$/; /** * Remove a .ts, .d.ts, or .js extension from a file name. */ function stripExtension(path) { return path.replace(TS_DTS_JS_EXTENSION, ''); } function getSourceFileOrError(program, fileName) { const sf = program.getSourceFile(fileName); if (sf === undefined) { throw new Error(`Program does not contain "${fileName}" - available files are ${program.getSourceFiles().map(sf => sf.fileName).join(', ')}`); } return sf; } let fs = new InvalidFileSystem(); function getFileSystem() { return fs; } function setFileSystem(fileSystem) { fs = fileSystem; } /** * Convert the path `path` to an `AbsoluteFsPath`, throwing an error if it's not an absolute path. */ function absoluteFrom(path) { if (!fs.isRooted(path)) { throw new Error(`Internal Error: absoluteFrom(${path}): path is not absolute`); } return fs.resolve(path); } const ABSOLUTE_PATH = Symbol('AbsolutePath'); /** * Extract an `AbsoluteFsPath` from a `ts.SourceFile`-like object. */ function absoluteFromSourceFile(sf) { const sfWithPatch = sf; if (sfWithPatch[ABSOLUTE_PATH] === undefined) { sfWithPatch[ABSOLUTE_PATH] = fs.resolve(sfWithPatch.fileName); } // Non-null assertion needed since TS doesn't narrow the type of fields that use a symbol as a key // apparently. return sfWithPatch[ABSOLUTE_PATH]; } /** * Static access to `dirname`. */ function dirname(file) { return fs.dirname(file); } /** * Static access to `join`. */ function join(basePath, ...paths) { return fs.join(basePath, ...paths); } /** * Static access to `resolve`s. */ function resolve(basePath, ...paths) { return fs.resolve(basePath, ...paths); } /** * Static access to `isRooted`. */ function isRooted(path) { return fs.isRooted(path); } /** * Static access to `relative`. */ function relative(from, to) { return fs.relative(from, to); } /** * Returns true if the given path is locally relative. * * This is used to work out if the given path is relative (i.e. not absolute) but also is not * escaping the current directory. */ function isLocalRelativePath(relativePath) { return !isRooted(relativePath) && !relativePath.startsWith('..'); } /** * Converts a path to a form suitable for use as a relative module import specifier. * * In other words it adds the `./` to the path if it is locally relative. */ function toRelativeImport(relativePath) { return isLocalRelativePath(relativePath) ? `./${relativePath}` : relativePath; } const LogicalProjectPath = { /** * Get the relative path between two `LogicalProjectPath`s. * * This will return a `PathSegment` which would be a valid module specifier to use in `from` when * importing from `to`. */ relativePathBetween: function (from, to) { const relativePath = relative(dirname(resolve(from)), resolve(to)); return toRelativeImport(relativePath); }, }; /** * A utility class which can translate absolute paths to source files into logical paths in * TypeScript's logical file system, based on the root directories of the project. */ class LogicalFileSystem { constructor(rootDirs, compilerHost) { this.compilerHost = compilerHost; /** * A cache of file paths to project paths, because computation of these paths is slightly * expensive. */ this.cache = new Map(); // Make a copy and sort it by length in reverse order (longest first). This speeds up lookups, // since there's no need to keep going through the array once a match is found. this.rootDirs = rootDirs.concat([]).sort((a, b) => b.length - a.length); this.canonicalRootDirs = this.rootDirs.map(dir => this.compilerHost.getCanonicalFileName(dir)); } /** * Get the logical path in the project of a `ts.SourceFile`. * * This method is provided as a convenient alternative to calling * `logicalPathOfFile(absoluteFromSourceFile(sf))`. */ logicalPathOfSf(sf) { return this.logicalPathOfFile(absoluteFromSourceFile(sf)); } /** * Get the logical path in the project of a source file. * * @returns A `LogicalProjectPath` to the source file, or `null` if the source file is not in any * of the TS project's root directories. */ logicalPathOfFile(physicalFile) { if (!this.cache.has(physicalFile)) { const canonicalFilePath = this.compilerHost.getCanonicalFileName(physicalFile); let logicalFile = null; for (let i = 0; i < this.rootDirs.length; i++) { const rootDir = this.rootDirs[i]; const canonicalRootDir = this.canonicalRootDirs[i]; if (isWithinBasePath(canonicalRootDir, canonicalFilePath)) { // Note that we match against canonical paths but then create the logical path from // original paths. logicalFile = this.createLogicalProjectPath(physicalFile, rootDir); // The logical project does not include any special "node_modules" nested directories. if (logicalFile.indexOf('/node_modules/') !== -1) { logicalFile = null; } else { break; } } } this.cache.set(physicalFile, logicalFile); } return this.cache.get(physicalFile); } createLogicalProjectPath(file, rootDir) { const logicalPath = stripExtension(file.slice(rootDir.length)); return (logicalPath.startsWith('/') ? logicalPath : '/' + logicalPath); } } /** * Is the `path` a descendant of the `base`? * E.g. `foo/bar/zee` is within `foo/bar` but not within `foo/car`. */ function isWithinBasePath(base, path) { return isLocalRelativePath(relative(base, path)); } /** * @license * Copyright Google LLC 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 */ /** * A wrapper around the Node.js file-system that supports path manipulation. */ class NodeJSPathManipulation { pwd() { return this.normalize(process.cwd()); } chdir(dir) { process.chdir(dir); } resolve(...paths) { return this.normalize(p__namespace.resolve(...paths)); } dirname(file) { return this.normalize(p__namespace.dirname(file)); } join(basePath, ...paths) { return this.normalize(p__namespace.join(basePath, ...paths)); } isRoot(path) { return this.dirname(path) === this.normalize(path); } isRooted(path) { return p__namespace.isAbsolute(path); } relative(from, to) { return this.normalize(p__namespace.relative(from, to)); } basename(filePath, extension) { return p__namespace.basename(filePath, extension); } extname(path) { return p__namespace.extname(path); } normalize(path) { // Convert backslashes to forward slashes return path.replace(/\\/g, '/'); } } // G3-ESM-MARKER: G3 uses CommonJS, but externally everything in ESM. // CommonJS/ESM interop for determining the current file name and containing dir. const isCommonJS = typeof __filename !== 'undefined'; const currentFileUrl = isCommonJS ? null : new URL(module.uri, document.baseURI).href; const currentFileName = isCommonJS ? __filename : url.fileURLToPath(currentFileUrl); /** * A wrapper around the Node.js file-system that supports readonly operations and path manipulation. */ class NodeJSReadonlyFileSystem extends NodeJSPathManipulation { constructor() { super(...arguments); this._caseSensitive = undefined; } isCaseSensitive() { if (this._caseSensitive === undefined) { // Note the use of the real file-system is intentional: // `this.exists()` relies upon `isCaseSensitive()` so that would cause an infinite recursion. this._caseSensitive = !fs__default["default"].existsSync(this.normalize(toggleCase(currentFileName))); } return this._caseSensitive; } exists(path) { return fs__default["default"].existsSync(path); } readFile(path) { return fs__default["default"].readFileSync(path, 'utf8'); } readFileBuffer(path) { return fs__default["default"].readFileSync(path); } readdir(path) { return fs__default["default"].readdirSync(path); } lstat(path) { return fs__default["default"].lstatSync(path); } stat(path) { return fs__default["default"].statSync(path); } realpath(path) { return this.resolve(fs__default["default"].realpathSync(path)); } getDefaultLibLocation() { // G3-ESM-MARKER: G3 uses CommonJS, but externally everything in ESM. const requireFn = isCommonJS ? require : module__default["default"].createRequire(currentFileUrl); return this.resolve(requireFn.resolve('typescript'), '..'); } } /** * A wrapper around the Node.js file-system (i.e. the `fs` package). */ class NodeJSFileSystem extends NodeJSReadonlyFileSystem { writeFile(path, data, exclusive = false) { fs__default["default"].writeFileSync(path, data, exclusive ? { flag: 'wx' } : undefined); } removeFile(path) { fs__default["default"].unlinkSync(path); } symlink(target, path) { fs__default["default"].symlinkSync(target, path); } copyFile(from, to) { fs__default["default"].copyFileSync(from, to); } moveFile(from, to) { fs__default["default"].renameSync(from, to); } ensureDir(path) { fs__default["default"].mkdirSync(path, { recursive: true }); } removeDeep(path) { fs__default["default"].rmdirSync(path, { recursive: true }); } } /** * Toggle the case of each character in a string. */ function toggleCase(str) { return str.replace(/\w/g, ch => ch.toUpperCase() === ch ? ch.toLowerCase() : ch.toUpperCase()); } /** * @license * Copyright Google LLC 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 */ const _SELECTOR_REGEXP = new RegExp('(\\:not\\()|' + // 1: ":not(" '(([\\.\\#]?)[-\\w]+)|' + // 2: "tag"; 3: "."/"#"; // "-" should appear first in the regexp below as FF31 parses "[.-\w]" as a range // 4: attribute; 5: attribute_string; 6: attribute_value '(?:\\[([-.\\w*\\\\$]+)(?:=([\"\']?)([^\\]\"\']*)\\5)?\\])|' + // "[name]", "[name=value]", // "[name="value"]", // "[name='value']" '(\\))|' + // 7: ")" '(\\s*,\\s*)', // 8: "," 'g'); /** * A css selector contains an element name, * css classes and attribute/value pairs with the purpose * of selecting subsets out of them. */ class CssSelector { constructor() { this.element = null; this.classNames = []; /** * The selectors are encoded in pairs where: * - even locations are attribute names * - odd locations are attribute values. * * Example: * Selector: `[key1=value1][key2]` would parse to: * ``` * ['key1', 'value1', 'key2', ''] * ``` */ this.attrs = []; this.notSelectors = []; } static parse(selector) { const results = []; const _addResult = (res, cssSel) => { if (cssSel.notSelectors.length > 0 && !cssSel.element && cssSel.classNames.length == 0 && cssSel.attrs.length == 0) { cssSel.element = '*'; } res.push(cssSel); }; let cssSelector = new CssSelector(); let match; let current = cssSelector; let inNot = false; _SELECTOR_REGEXP.lastIndex = 0; while (match = _SELECTOR_REGEXP.exec(selector)) { if (match[1 /* SelectorRegexp.NOT */]) { if (inNot) { throw new Error('Nesting :not in a selector is not allowed'); } inNot = true; current = new CssSelector(); cssSelector.notSelectors.push(current); } const tag = match[2 /* SelectorRegexp.TAG */]; if (tag) { const prefix = match[3 /* SelectorRegexp.PREFIX */]; if (prefix === '#') { // #hash current.addAttribute('id', tag.slice(1)); } else if (prefix === '.') { // Class current.addClassName(tag.slice(1)); } else { // Element current.setElement(tag); } } const attribute = match[4 /* SelectorRegexp.ATTRIBUTE */]; if (attribute) { current.addAttribute(current.unescapeAttribute(attribute), match[6 /* SelectorRegexp.ATTRIBUTE_VALUE */]); } if (match[7 /* SelectorRegexp.NOT_END */]) { inNot = false; current = cssSelector; } if (match[8 /* SelectorRegexp.SEPARATOR */]) { if (inNot) { throw new Error('Multiple selectors in :not are not supported'); } _addResult(results, cssSelector); cssSelector = current = new CssSelector(); } } _addResult(results, cssSelector); return results; } /** * Unescape `\$` sequences from the CSS attribute selector. * * This is needed because `$` can have a special meaning in CSS selectors, * but we might want to match an attribute that contains `$`. * [MDN web link for more * info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors). * @param attr the attribute to unescape. * @returns the unescaped string. */ unescapeAttribute(attr) { let result = ''; let escaping = false; for (let i = 0; i < attr.length; i++) { const char = attr.charAt(i); if (char === '\\') { escaping = true; continue; } if (char === '$' && !escaping) { throw new Error(`Error in attribute selector "${attr}". ` + `Unescaped "$" is not supported. Please escape with "\\$".`); } escaping = false; result += char; } return result; } /** * Escape `$` sequences from the CSS attribute selector. * * This is needed because `$` can have a special meaning in CSS selectors, * with this method we are escaping `$` with `\$'. * [MDN web link for more * info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors). * @param attr the attribute to escape. * @returns the escaped string. */ escapeAttribute(attr) { return attr.replace(/\\/g, '\\\\').replace(/\$/g, '\\$'); } isElementSelector() { return this.hasElementSelector() && this.classNames.length == 0 && this.attrs.length == 0 && this.notSelectors.length === 0; } hasElementSelector() { return !!this.element; } setElement(element = null) { this.element = element; } getAttrs() { const result = []; if (this.classNames.length > 0) { result.push('class', this.classNames.join(' ')); } return result.concat(this.attrs); } addAttribute(name, value = '') { this.attrs.push(name, value && value.toLowerCase() || ''); } addClassName(name) { this.classNames.push(name.toLowerCase()); } toString() { let res = this.element || ''; if (this.classNames) { this.classNames.forEach(klass => res += `.${klass}`); } if (this.attrs) { for (let i = 0; i < this.attrs.length; i += 2) { const name = this.escapeAttribute(this.attrs[i]); const value = this.attrs[i + 1]; res += `[${name}${value ? '=' + value : ''}]`; } } this.notSelectors.forEach(notSelector => res += `:not(${notSelector})`); return res; } } /** * Reads a list of CssSelectors and allows to calculate which ones * are contained in a given CssSelector. */ class SelectorMatcher { constructor() { this._elementMap = new Map(); this._elementPartialMap = new Map(); this._classMap = new Map(); this._classPartialMap = new Map(); this._attrValueMap = new Map(); this._attrValuePartialMap = new Map(); this._listContexts = []; } static createNotMatcher(notSelectors) { const notMatcher = new SelectorMatcher(); notMatcher.addSelectables(notSelectors, null); return notMatcher; } addSelectables(cssSelectors, callbackCtxt) { let listContext = null; if (cssSelectors.length > 1) { listContext = new SelectorListContext(cssSelectors); this._listContexts.push(listContext); } for (let i = 0; i < cssSelectors.length; i++) { this._addSelectable(cssSelectors[i], callbackCtxt, listContext); } } /** * Add an object that can be found later on by calling `match`. * @param cssSelector A css selector * @param callbackCtxt An opaque object that will be given to the callback of the `match` function */ _addSelectable(cssSelector, callbackCtxt, listContext) { let matcher = this; const element = cssSelector.element; const classNames = cssSelector.classNames; const attrs = cssSelector.attrs; const selectable = new SelectorContext(cssSelector, callbackCtxt, listContext); if (element) { const isTerminal = attrs.length === 0 && classNames.length === 0; if (isTerminal) { this._addTerminal(matcher._elementMap, element, selectable); } else { matcher = this._addPartial(matcher._elementPartialMap, element); } } if (classNames) { for (let i = 0; i < classNames.length; i++) { const isTerminal = attrs.length === 0 && i === classNames.length - 1; const className = classNames[i]; if (isTerminal) { this._addTerminal(matcher._classMap, className, selectable); } else { matcher = this._addPartial(matcher._classPartialMap, className); } } } if (attrs) { for (let i = 0; i < attrs.length; i += 2) { const isTerminal = i === attrs.length - 2; const name = attrs[i]; const value = attrs[i + 1]; if (isTerminal) { const terminalMap = matcher._attrValueMap; let terminalValuesMap = terminalMap.get(name); if (!terminalValuesMap) { terminalValuesMap = new Map(); terminalMap.set(name, terminalValuesMap); } this._addTerminal(terminalValuesMap, value, selectable); } else { const partialMap = matcher._attrValuePartialMap; let partialValuesMap = partialMap.get(name); if (!partialValuesMap) { partialValuesMap = new Map(); partialMap.set(name, partialValuesMap); } matcher = this._addPartial(partialValuesMap, value); } } } } _addTerminal(map, name, selectable) { let terminalList = map.get(name); if (!terminalList) { terminalList = []; map.set(name, terminalList); } terminalList.push(selectable); } _addPartial(map, name) { let matcher = map.get(name); if (!matcher) { matcher = new SelectorMatcher(); map.set(name, matcher); } return matcher; } /** * Find the objects that have been added via `addSelectable` * whose css selector is contained in the given css selector. * @param cssSelector A css selector * @param matchedCallback This callback will be called with the object handed into `addSelectable` * @return boolean true if a match was found */ match(cssSelector, matchedCallback) { let result = false; const element = cssSelector.element; const classNames = cssSelector.classNames; const attrs = cssSelector.attrs; for (let i = 0; i < this._listContexts.length; i++) { this._listContexts[i].alreadyMatched = false; } result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result; result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) || result; if (classNames) { for (let i = 0; i < classNames.length; i++) { const className = classNames[i]; result = this._matchTerminal(this._classMap, className, cssSelector, matchedCallback) || result; result = this._matchPartial(this._classPartialMap, className, cssSelector, matchedCallback) || result; } } if (attrs) { for (let i = 0; i < attrs.length; i += 2) { const name = attrs[i]; const value = attrs[i + 1]; const terminalValuesMap = this._attrValueMap.get(name); if (value) { result = this._matchTerminal(terminalValuesMap, '', cssSelector, matchedCallback) || result; } result = this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result; const partialValuesMap = this._attrValuePartialMap.get(name); if (value) { result = this._matchPartial(partialValuesMap, '', cssSelector, matchedCallback) || result; } result = this._matchPartial(partialValuesMap, value, cssSelector, matchedCallback) || result; } } return result; } /** @internal */ _matchTerminal(map, name, cssSelector, matchedCallback) { if (!map || typeof name !== 'string') { return false; } let selectables = map.get(name) || []; const starSelectables = map.get('*'); if (starSelectables) { selectables = selectables.concat(starSelectables); } if (selectables.length === 0) { return false; } let selectable; let result = false; for (let i = 0; i < selectables.length; i++) { selectable = selectables[i]; result = selectable.finalize(cssSelector, matchedCallback) || result; } return result; } /** @internal */ _matchPartial(map, name, cssSelector, matchedCallback) { if (!map || typeof name !== 'string') { return false; } const nestedSelector = map.get(name); if (!nestedSelector) { return false; } // TODO(perf): get rid of recursion and measure again // TODO(perf): don't pass the whole selector into the recursion, // but only the not processed parts return nestedSelector.match(cssSelector, matchedCallback); } } class SelectorListContext { constructor(selectors) { this.selectors = selectors; this.alreadyMatched = false; } } // Store context to pass back selector and context when a selector is matched class SelectorContext { constructor(selector, cbContext, listContext) { this.selector = selector; this.cbContext = cbContext; this.listContext = listContext; this.notSelectors = selector.notSelectors; } finalize(cssSelector, callback) { let result = true; if (this.notSelectors.length > 0 && (!this.listContext || !this.listContext.alreadyMatched)) { const notMatcher = SelectorMatcher.createNotMatcher(this.notSelectors); result = !notMatcher.match(cssSelector, null); } if (result && callback && (!this.listContext || !this.listContext.alreadyMatched)) { if (this.listContext) { this.listContext.alreadyMatched = true; } callback(this.selector, this.cbContext); } return result; } } /** * @license * Copyright Google LLC 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 */ // Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not // explicitly set. const emitDistinctChangesOnlyDefaultValue = true; var ViewEncapsulation; (function (ViewEncapsulation) { ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated"; // Historically the 1 value was for `Native` encapsulation which has been removed as of v11. ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None"; ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom"; })(ViewEncapsulation || (ViewEncapsulation = {})); var ChangeDetectionStrategy; (function (ChangeDetectionStrategy) { ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush"; ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default"; })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {})); const CUSTOM_ELEMENTS_SCHEMA = { name: 'custom-elements' }; const NO_ERRORS_SCHEMA = { name: 'no-errors-schema' }; var SecurityContext; (function (SecurityContext) { SecurityContext[SecurityContext["NONE"] = 0] = "NONE"; SecurityContext[SecurityContext["HTML"] = 1] = "HTML"; SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE"; SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT"; SecurityContext[SecurityContext["URL"] = 4] = "URL"; SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL"; })(SecurityContext || (SecurityContext = {})); var MissingTranslationStrategy; (function (MissingTranslationStrategy) { MissingTranslationStrategy[MissingTranslationStrategy["Error"] = 0] = "Error"; MissingTranslationStrategy[MissingTranslationStrategy["Warning"] = 1] = "Warning"; MissingTranslationStrategy[MissingTranslationStrategy["Ignore"] = 2] = "Ignore"; })(MissingTranslationStrategy || (MissingTranslationStrategy = {})); function parserSelectorToSimpleSelector(selector) { const classes = selector.classNames && selector.classNames.length ? [8 /* SelectorFlags.CLASS */, ...selector.classNames] : []; const elementName = selector.element && selector.element !== '*' ? selector.element : ''; return [elementName, ...selector.attrs, ...classes]; } function parserSelectorToNegativeSelector(selector) { const classes = selector.classNames && selector.classNames.length ? [8 /* SelectorFlags.CLASS */, ...selector.classNames] : []; if (selector.element) { return [ 1 /* SelectorFlags.NOT */ | 4 /* SelectorFlags.ELEMENT */, selector.element, ...selector.attrs, ...classes ]; } else if (selector.attrs.length) { return [1 /* SelectorFlags.NOT */ | 2 /* SelectorFlags.ATTRIBUTE */, ...selector.attrs, ...classes]; } else { return selector.classNames && selector.classNames.length ? [1 /* SelectorFlags.NOT */ | 8 /* SelectorFlags.CLASS */, ...selector.classNames] : []; } } function parserSelectorToR3Selector(selector) { const positive = parserSelectorToSimpleSelector(selector); const negative = selector.notSelectors && selector.notSelectors.length ? selector.notSelectors.map(notSelector => parserSelectorToNegativeSelector(notSelector)) : []; return positive.concat(...negative); } function parseSelectorToR3Selector(selector) { return selector ? CssSelector.parse(selector).map(parserSelectorToR3Selector) : []; } /** * @license * Copyright Google LLC 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 */ /** * A lazily created TextEncoder instance for converting strings into UTF-8 bytes */ let textEncoder; /** * Compute the message id using the XLIFF1 digest. */ function computeDigest(message) { return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`); } /** * Return the message id or compute it using the XLIFF2/XMB/$localize digest. */ function decimalDigest(message) { return message.id || computeDecimalDigest(message); } /** * Compute the message id using the XLIFF2/XMB/$localize digest. */ function computeDecimalDigest(message) { const visitor = new _SerializerIgnoreIcuExpVisitor(); const parts = message.nodes.map(a => a.visit(visitor, null)); return computeMsgId(parts.join(''), message.meaning); } /** * Serialize the i18n ast to something xml-like in order to generate an UID. * * The visitor is also used in the i18n parser tests * * @internal */ class _SerializerVisitor { visitText(text, context) { return text.value; } visitContainer(container, context) { return `[${container.children.map(child => child.visit(this)).join(', ')}]`; } visitIcu(icu, context) { const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`); return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`; } visitTagPlaceholder(ph, context) { return ph.isVoid ? `<ph tag name="${ph.startName}"/>` : `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`; } visitPlaceholder(ph, context) { return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`; } visitIcuPlaceholder(ph, context) { return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`; } visitBlockPlaceholder(ph, context) { return `<ph block name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`; } } const serializerVisitor$1 = new _SerializerVisitor(); function serializeNodes(nodes) { return nodes.map(a => a.visit(serializerVisitor$1, null)); } /** * Serialize the i18n ast to something xml-like in order to generate an UID. * * Ignore the ICU expressions so that message IDs stays identical if only the expression changes. * * @internal */ class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor { visitIcu(icu, context) { let strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`); // Do not take the expression into account return `{${icu.type}, ${strCases.join(', ')}}`; } } /** * Compute the SHA1 of the given string * * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf * * WARNING: this function has not been designed not tested with security in mind. * DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT. */ function sha1(str) { textEncoder ??= new TextEncoder(); const utf8 = [...textEncoder.encode(str)]; const words32 = bytesToWords32(utf8, Endian.Big); const len = utf8.length * 8; const w = new Uint32Array(80); let a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476, e = 0xc3d2e1f0; words32[len >> 5] |= 0x80 << (24 - len % 32); words32[((len + 64 >> 9) << 4) + 15] = len; for (let i = 0; i < words32.length; i += 16) { const h0 = a, h1 = b, h2 = c, h3 = d, h4 = e; for (let j = 0; j < 80; j++) { if (j < 16) { w[j] = words32[i + j]; } else { w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); } const fkVal = fk(j, b, c, d); const f = fkVal[0]; const k = fkVal[1]; const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32); e = d; d = c; c = rol32(b, 30); b = a; a = temp; } a = add32(a, h0); b = add32(b, h1); c = add32(c, h2); d = add32(d, h3); e = add32(e, h4); } // Convert the output parts to a 160-bit hexadecimal string return toHexU32(a) + toHexU32(b) + toHexU32(c) + toHexU32(d) + toHexU32(e); } /** * Convert and format a number as a string representing a 32-bit unsigned hexadecimal number. * @param value The value to format as a string. * @returns A hexadecimal string representing the value. */ function toHexU32(value) { // unsigned right shift of zero ensures an unsigned 32-bit number return (value >>> 0).toString(16).padStart(8, '0'); } function fk(index, b, c, d) { if (index < 20) { return [(b & c) | (~b & d), 0x5a827999]; } if (index < 40) { return [b ^ c ^ d, 0x6ed9eba1]; } if (index < 60) { return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc]; } return [b ^ c ^ d, 0xca62c1d6]; } /** * Compute the fingerprint of the given string * * The output is 64 bit number encoded as a decimal string * * based on: * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java */ function fingerprint(str) { textEncoder ??= new TextEncoder(); const utf8 = textEncoder.encode(str); const view = new DataView(utf8.buffer, utf8.byteOffset, utf8.byteLength); let hi = hash32(view, utf8.length, 0); let lo = hash32(view, utf8.length, 102072); if (hi == 0 && (lo == 0 || lo == 1)) { hi = hi ^ 0x130f9bef; lo = lo ^ -0x6b5f56d8; } return (BigInt.asUintN(32, BigInt(hi)) << BigInt(32)) | BigInt.asUintN(32, BigInt(lo)); } function computeMsgId(msg, meaning = '') { let msgFingerprint = fingerprint(msg); if (meaning) { // Rotate the 64-bit message fingerprint one bit to the left and then add the meaning // fingerprint. msgFingerprint = BigInt.asUintN(64, msgFingerprint << BigInt(1)) | ((msgFingerprint >> BigInt(63)) & BigInt(1)); msgFingerprint += fingerprint(meaning); } return BigInt.asUintN(63, msgFingerprint).toString(); } function hash32(view, length, c) { let a = 0x9e3779b9, b = 0x9e3779b9; let index = 0; const end = length - 12; for (; index <= end; index += 12) { a += view.getUint32(index, true); b += view.getUint32(index + 4, true); c += view.getUint32(index + 8, true); const res = mix(a, b, c); a = res[0], b = res[1], c = res[2]; } const remainder = length - index; // the first byte of c is reserved for the length c += length; if (remainder >= 4) { a += view.getUint32(index, true); index += 4; if (remainder >= 8) { b += view.getUint32(index, true); index += 4; // Partial 32-bit word for c if (remainder >= 9) { c += view.getUint8(index++) << 8; } if (remainder >= 10) { c += view.getUint8(index++) << 16; } if (remainder === 11) { c += view.getUint8(index++) << 24; } } else { // Partial 32-bit word for b if (remainder >= 5) { b += view.getUint8(index++); } if (remainder >= 6) { b += view.getUint8(index++) << 8; } if (remainder === 7) { b += view.getUint8(index++) << 16; } } } else { // Partial 32-bit word for a if (remainder >= 1) { a += view.getUint8(index++); } if (remainder >= 2) { a += view.getUint8(index++) << 8; } if (remainder === 3) { a += view.getUint8(index++) << 16; } } return mix(a, b, c)[2]; } // clang-format off function mix(a, b, c) { a -= b; a -= c; a ^= c >>> 13; b -= c; b -= a; b ^= a << 8; c -= a; c -= b; c ^= b >>> 13; a -= b; a -= c; a ^= c >>> 12; b -= c; b -= a; b ^= a << 16; c -= a; c -= b; c ^= b >>> 5; a -= b; a -= c; a ^= c >>> 3; b -= c; b -= a; b ^= a << 10; c -= a; c -= b; c ^= b >>> 15; return [a, b, c]; } // clang-format on // Utils var Endian; (function (Endian) { Endian[Endian["Little"] = 0] = "Little"; Endian[Endian["Big"] = 1] = "Big"; })(Endian || (Endian = {})); function add32(a, b) { return add32to64(a, b)[1]; } function add32to64(a, b) { const low = (a & 0xffff) + (b & 0xffff); const high = (a >>> 16) + (b >>> 16) + (low >>> 16); return [high >>> 16, (high << 16) | (low & 0xffff)]; } // Rotate a 32b number left `count` position function rol32(a, count) { return (a << count) | (a >>> (32 - count)); } function bytesToWords32(bytes, endian) { const size = (bytes.length + 3) >>> 2; const words32 = []; for (let i = 0; i < size; i++) { words32[i] = wordAt(bytes, i * 4, endian); } return words32; } function byteAt(bytes, index) { return index >= bytes.length ? 0 : bytes[index]; } function wordAt(bytes, index, endian) { let word = 0; if (endian === Endian.Big) { for (let i = 0; i < 4; i++) { word += byteAt(bytes, index + i) << (24 - 8 * i); } } else { for (let i = 0; i < 4; i++) { word += byteAt(bytes, index + i) << 8 * i; } } return word; } /** * @license * Copyright Google LLC 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 */ //// Types var TypeModifier; (function (TypeModifier) { TypeModifier[TypeModifier["None"] = 0] = "None"; TypeModifier[TypeModifier["Const"] = 1] = "Const"; })(TypeModifier || (TypeModifier = {})); class Type { constructor(modifiers = TypeModifier.None) { this.modifiers = modifiers; } hasModifier(modifier) { return (this.modifiers & modifier) !== 0; } } var BuiltinTypeName; (function (BuiltinTypeName) { BuiltinTypeName[BuiltinTypeName["Dynamic"] = 0] = "Dynamic"; BuiltinTypeName[BuiltinTypeName["Bool"] = 1] = "Bool"; BuiltinTypeName[BuiltinTypeName["String"] = 2] = "String"; BuiltinTypeName[BuiltinTypeName["Int"] = 3] = "Int"; BuiltinTypeName[BuiltinTypeName["Number"] = 4] = "Number"; BuiltinTypeName[BuiltinTypeName["Function"] = 5] = "Function"; BuiltinTypeName[BuiltinTypeName["Inferred"] = 6] = "Inferred"; BuiltinTypeName[BuiltinTypeName["None"] = 7] = "None"; })(BuiltinTypeName || (BuiltinTypeName = {})); class BuiltinType extends Type { constructor(name, modifiers) { super(modifiers); this.name = name; } visitType(visitor, context) { return visitor.visitBuiltinType(this, context); } } class ExpressionType extends Type { constructor(value, modifiers, typeParams = null) { super(modifiers); this.value = value; this.typeParams = typeParams; } visitType(visitor, context) { return visitor.visitExpressionType(this, context); } } class TransplantedType extends Type { constructor(type, modifiers) { super(modifiers); this.type = type; } visitType(visitor, context) { return visitor.visitTransplantedType(this, context); } } const DYNAMIC_TYPE = new BuiltinType(BuiltinTypeName.Dynamic); const INFERRED_TYPE = new BuiltinType(BuiltinTypeName.Inferred); const BOOL_TYPE = new BuiltinType(BuiltinTypeName.Bool); new BuiltinType(BuiltinTypeName.Int); const NUMBER_TYPE = new BuiltinType(BuiltinTypeName.Number); const