1 |
|
2 | import {createRequire as __cjsCompatRequire} from 'module';
|
3 | const require = __cjsCompatRequire(import.meta.url);
|
4 | const __ESM_IMPORT_META_URL__ = import.meta.url;
|
5 |
|
6 | import {
|
7 | CompilationMode,
|
8 | ComponentDecoratorHandler,
|
9 | CompoundMetadataReader,
|
10 | CompoundMetadataRegistry,
|
11 | DirectiveDecoratorHandler,
|
12 | DtsMetadataReader,
|
13 | DtsTransformRegistry,
|
14 | InjectableClassRegistry,
|
15 | InjectableDecoratorHandler,
|
16 | LocalMetadataRegistry,
|
17 | NgModuleDecoratorHandler,
|
18 | NoopReferencesRegistry,
|
19 | PartialEvaluator,
|
20 | PipeDecoratorHandler,
|
21 | ResourceRegistry,
|
22 | SemanticDepGraphUpdater,
|
23 | TraitCompiler,
|
24 | aliasTransformFactory,
|
25 | declarationTransformFactory,
|
26 | flattenInheritedDirectiveMetadata,
|
27 | ivyTransformFactory
|
28 | } from "./chunk-KAJ5EOEG.js";
|
29 | import {
|
30 | TypeScriptReflectionHost,
|
31 | isNamedClassDeclaration
|
32 | } from "./chunk-Q5GIQ3RV.js";
|
33 | import {
|
34 | AbsoluteModuleStrategy,
|
35 | AliasStrategy,
|
36 | COMPILER_ERRORS_WITH_GUIDES,
|
37 | DefaultImportTracker,
|
38 | ERROR_DETAILS_PAGE_BASE_URL,
|
39 | ErrorCode,
|
40 | ExtendedTemplateDiagnosticName,
|
41 | ImportFlags,
|
42 | ImportManager,
|
43 | LocalIdentifierStrategy,
|
44 | LogicalProjectStrategy,
|
45 | ModuleResolver,
|
46 | NoopImportRewriter,
|
47 | PrivateExportAliasingHost,
|
48 | R3SymbolsImportRewriter,
|
49 | Reference,
|
50 | ReferenceEmitter,
|
51 | RelativePathStrategy,
|
52 | UnifiedModulesAliasingHost,
|
53 | UnifiedModulesStrategy,
|
54 | assertSuccessfulReferenceEmit,
|
55 | getRootDirs,
|
56 | getSourceFileOrNull,
|
57 | getTokenAtPosition,
|
58 | identifierOfNode,
|
59 | isAssignment,
|
60 | isDtsPath,
|
61 | isNonDeclarationTsPath,
|
62 | isSymbolWithValueDeclaration,
|
63 | makeDiagnostic,
|
64 | makeRelatedInformation,
|
65 | ngErrorCode,
|
66 | nodeNameForError,
|
67 | normalizeSeparators,
|
68 | relativePathBetween,
|
69 | replaceTsWithNgInErrors,
|
70 | toUnredirectedSourceFile,
|
71 | translateExpression,
|
72 | translateType
|
73 | } from "./chunk-WXB5AWIG.js";
|
74 | import {
|
75 | LogicalFileSystem,
|
76 | absoluteFrom,
|
77 | absoluteFromSourceFile,
|
78 | basename,
|
79 | dirname,
|
80 | getFileSystem,
|
81 | getSourceFileOrError,
|
82 | join,
|
83 | resolve
|
84 | } from "./chunk-CLV7JFJQ.js";
|
85 | import {
|
86 | ActivePerfRecorder,
|
87 | DelegatingPerfRecorder,
|
88 | PerfCheckpoint,
|
89 | PerfEvent,
|
90 | PerfPhase
|
91 | } from "./chunk-R4NY3TJC.js";
|
92 | import {
|
93 | __spreadProps,
|
94 | __spreadValues
|
95 | } from "./chunk-GMSUYBZP.js";
|
96 |
|
97 |
|
98 | var DEFAULT_ERROR_CODE = 100;
|
99 | var UNKNOWN_ERROR_CODE = 500;
|
100 | var SOURCE = "angular";
|
101 | function isTsDiagnostic(diagnostic) {
|
102 | return diagnostic != null && diagnostic.source !== "angular";
|
103 | }
|
104 | var EmitFlags;
|
105 | (function(EmitFlags2) {
|
106 | EmitFlags2[EmitFlags2["DTS"] = 1] = "DTS";
|
107 | EmitFlags2[EmitFlags2["JS"] = 2] = "JS";
|
108 | EmitFlags2[EmitFlags2["Metadata"] = 4] = "Metadata";
|
109 | EmitFlags2[EmitFlags2["I18nBundle"] = 8] = "I18nBundle";
|
110 | EmitFlags2[EmitFlags2["Codegen"] = 16] = "Codegen";
|
111 | EmitFlags2[EmitFlags2["Default"] = 19] = "Default";
|
112 | EmitFlags2[EmitFlags2["All"] = 31] = "All";
|
113 | })(EmitFlags || (EmitFlags = {}));
|
114 |
|
115 |
|
116 | import ts from "typescript";
|
117 | var wrapHostForTest = null;
|
118 | function createCompilerHost({ options, tsHost = ts.createCompilerHost(options, true) }) {
|
119 | if (wrapHostForTest !== null) {
|
120 | tsHost = wrapHostForTest(tsHost);
|
121 | }
|
122 | return tsHost;
|
123 | }
|
124 |
|
125 |
|
126 | var OptimizeFor;
|
127 | (function(OptimizeFor2) {
|
128 | OptimizeFor2[OptimizeFor2["SingleFile"] = 0] = "SingleFile";
|
129 | OptimizeFor2[OptimizeFor2["WholeProgram"] = 1] = "WholeProgram";
|
130 | })(OptimizeFor || (OptimizeFor = {}));
|
131 |
|
132 |
|
133 | var CompletionKind;
|
134 | (function(CompletionKind2) {
|
135 | CompletionKind2[CompletionKind2["Reference"] = 0] = "Reference";
|
136 | CompletionKind2[CompletionKind2["Variable"] = 1] = "Variable";
|
137 | })(CompletionKind || (CompletionKind = {}));
|
138 |
|
139 |
|
140 | var SymbolKind;
|
141 | (function(SymbolKind2) {
|
142 | SymbolKind2[SymbolKind2["Input"] = 0] = "Input";
|
143 | SymbolKind2[SymbolKind2["Output"] = 1] = "Output";
|
144 | SymbolKind2[SymbolKind2["Binding"] = 2] = "Binding";
|
145 | SymbolKind2[SymbolKind2["Reference"] = 3] = "Reference";
|
146 | SymbolKind2[SymbolKind2["Variable"] = 4] = "Variable";
|
147 | SymbolKind2[SymbolKind2["Directive"] = 5] = "Directive";
|
148 | SymbolKind2[SymbolKind2["Element"] = 6] = "Element";
|
149 | SymbolKind2[SymbolKind2["Template"] = 7] = "Template";
|
150 | SymbolKind2[SymbolKind2["Expression"] = 8] = "Expression";
|
151 | SymbolKind2[SymbolKind2["DomBinding"] = 9] = "DomBinding";
|
152 | SymbolKind2[SymbolKind2["Pipe"] = 10] = "Pipe";
|
153 | })(SymbolKind || (SymbolKind = {}));
|
154 |
|
155 |
|
156 | import { HtmlParser, MessageBundle } from "@angular/compiler";
|
157 | import ts35 from "typescript";
|
158 |
|
159 |
|
160 | import { Xliff, Xliff2, Xmb } from "@angular/compiler";
|
161 | import * as path from "path";
|
162 | function i18nGetExtension(formatName) {
|
163 | const format = formatName.toLowerCase();
|
164 | switch (format) {
|
165 | case "xmb":
|
166 | return "xmb";
|
167 | case "xlf":
|
168 | case "xlif":
|
169 | case "xliff":
|
170 | case "xlf2":
|
171 | case "xliff2":
|
172 | return "xlf";
|
173 | }
|
174 | throw new Error(`Unsupported format "${formatName}"`);
|
175 | }
|
176 | function i18nExtract(formatName, outFile, host, options, bundle, pathResolve = path.resolve) {
|
177 | formatName = formatName || "xlf";
|
178 | const ext = i18nGetExtension(formatName);
|
179 | const content = i18nSerialize(bundle, formatName, options);
|
180 | const dstFile = outFile || `messages.${ext}`;
|
181 | const dstPath = pathResolve(options.outDir || options.basePath, dstFile);
|
182 | host.writeFile(dstPath, content, false, void 0, []);
|
183 | return [dstPath];
|
184 | }
|
185 | function i18nSerialize(bundle, formatName, options) {
|
186 | const format = formatName.toLowerCase();
|
187 | let serializer;
|
188 | switch (format) {
|
189 | case "xmb":
|
190 | serializer = new Xmb();
|
191 | break;
|
192 | case "xliff2":
|
193 | case "xlf2":
|
194 | serializer = new Xliff2();
|
195 | break;
|
196 | case "xlf":
|
197 | case "xliff":
|
198 | default:
|
199 | serializer = new Xliff();
|
200 | }
|
201 | return bundle.write(serializer, getPathNormalizer(options.basePath));
|
202 | }
|
203 | function getPathNormalizer(basePath) {
|
204 | return (sourcePath) => {
|
205 | sourcePath = basePath ? path.relative(basePath, sourcePath) : sourcePath;
|
206 | return sourcePath.split(path.sep).join("/");
|
207 | };
|
208 | }
|
209 |
|
210 |
|
211 | import ts2 from "typescript";
|
212 |
|
213 |
|
214 | function toNumbers(value) {
|
215 | const suffixIndex = value.lastIndexOf("-");
|
216 | return value.slice(0, suffixIndex === -1 ? value.length : suffixIndex).split(".").map((segment) => {
|
217 | const parsed = parseInt(segment, 10);
|
218 | if (isNaN(parsed)) {
|
219 | throw Error(`Unable to parse version string ${value}.`);
|
220 | }
|
221 | return parsed;
|
222 | });
|
223 | }
|
224 | function compareNumbers(a, b) {
|
225 | const max = Math.max(a.length, b.length);
|
226 | const min = Math.min(a.length, b.length);
|
227 | for (let i = 0; i < min; i++) {
|
228 | if (a[i] > b[i])
|
229 | return 1;
|
230 | if (a[i] < b[i])
|
231 | return -1;
|
232 | }
|
233 | if (min !== max) {
|
234 | const longestArray = a.length === max ? a : b;
|
235 | const comparisonResult = a.length === max ? 1 : -1;
|
236 | for (let i = min; i < max; i++) {
|
237 | if (longestArray[i] > 0) {
|
238 | return comparisonResult;
|
239 | }
|
240 | }
|
241 | }
|
242 | return 0;
|
243 | }
|
244 | function compareVersions(v1, v2) {
|
245 | return compareNumbers(toNumbers(v1), toNumbers(v2));
|
246 | }
|
247 |
|
248 |
|
249 | var MIN_TS_VERSION = "4.4.2";
|
250 | var MAX_TS_VERSION = "4.7.0";
|
251 | var tsVersion = ts2.version;
|
252 | function checkVersion(version, minVersion, maxVersion) {
|
253 | if (compareVersions(version, minVersion) < 0 || compareVersions(version, maxVersion) >= 0) {
|
254 | throw new Error(`The Angular Compiler requires TypeScript >=${minVersion} and <${maxVersion} but ${version} was found instead.`);
|
255 | }
|
256 | }
|
257 | function verifySupportedTypeScriptVersion() {
|
258 | checkVersion(tsVersion, MIN_TS_VERSION, MAX_TS_VERSION);
|
259 | }
|
260 |
|
261 |
|
262 | import ts33 from "typescript";
|
263 |
|
264 |
|
265 | var CycleAnalyzer = class {
|
266 | constructor(importGraph) {
|
267 | this.importGraph = importGraph;
|
268 | this.cachedResults = null;
|
269 | }
|
270 | wouldCreateCycle(from, to) {
|
271 | if (this.cachedResults === null || this.cachedResults.from !== from) {
|
272 | this.cachedResults = new CycleResults(from, this.importGraph);
|
273 | }
|
274 | return this.cachedResults.wouldBeCyclic(to) ? new Cycle(this.importGraph, from, to) : null;
|
275 | }
|
276 | recordSyntheticImport(from, to) {
|
277 | this.cachedResults = null;
|
278 | this.importGraph.addSyntheticImport(from, to);
|
279 | }
|
280 | };
|
281 | var NgCyclicResult = Symbol("NgCyclicResult");
|
282 | var CycleResults = class {
|
283 | constructor(from, importGraph) {
|
284 | this.from = from;
|
285 | this.importGraph = importGraph;
|
286 | this.cyclic = {};
|
287 | this.acyclic = {};
|
288 | }
|
289 | wouldBeCyclic(sf) {
|
290 | const cached = this.getCachedResult(sf);
|
291 | if (cached !== null) {
|
292 | return cached;
|
293 | }
|
294 | if (sf === this.from) {
|
295 | return true;
|
296 | }
|
297 | this.markAcyclic(sf);
|
298 | const imports = this.importGraph.importsOf(sf);
|
299 | for (const imported of imports) {
|
300 | if (this.wouldBeCyclic(imported)) {
|
301 | this.markCyclic(sf);
|
302 | return true;
|
303 | }
|
304 | }
|
305 | return false;
|
306 | }
|
307 | getCachedResult(sf) {
|
308 | const result = sf[NgCyclicResult];
|
309 | if (result === this.cyclic) {
|
310 | return true;
|
311 | } else if (result === this.acyclic) {
|
312 | return false;
|
313 | } else {
|
314 | return null;
|
315 | }
|
316 | }
|
317 | markCyclic(sf) {
|
318 | sf[NgCyclicResult] = this.cyclic;
|
319 | }
|
320 | markAcyclic(sf) {
|
321 | sf[NgCyclicResult] = this.acyclic;
|
322 | }
|
323 | };
|
324 | var Cycle = class {
|
325 | constructor(importGraph, from, to) {
|
326 | this.importGraph = importGraph;
|
327 | this.from = from;
|
328 | this.to = to;
|
329 | }
|
330 | getPath() {
|
331 | return [this.from, ...this.importGraph.findPath(this.to, this.from)];
|
332 | }
|
333 | };
|
334 |
|
335 |
|
336 | import ts3 from "typescript";
|
337 | var ImportGraph = class {
|
338 | constructor(checker, perf) {
|
339 | this.checker = checker;
|
340 | this.perf = perf;
|
341 | this.imports = new Map();
|
342 | }
|
343 | importsOf(sf) {
|
344 | if (!this.imports.has(sf)) {
|
345 | this.imports.set(sf, this.scanImports(sf));
|
346 | }
|
347 | return this.imports.get(sf);
|
348 | }
|
349 | findPath(start, end) {
|
350 | if (start === end) {
|
351 | return [start];
|
352 | }
|
353 | const found = new Set([start]);
|
354 | const queue = [new Found(start, null)];
|
355 | while (queue.length > 0) {
|
356 | const current = queue.shift();
|
357 | const imports = this.importsOf(current.sourceFile);
|
358 | for (const importedFile of imports) {
|
359 | if (!found.has(importedFile)) {
|
360 | const next = new Found(importedFile, current);
|
361 | if (next.sourceFile === end) {
|
362 | return next.toPath();
|
363 | }
|
364 | found.add(importedFile);
|
365 | queue.push(next);
|
366 | }
|
367 | }
|
368 | }
|
369 | return null;
|
370 | }
|
371 | addSyntheticImport(sf, imported) {
|
372 | if (isLocalFile(imported)) {
|
373 | this.importsOf(sf).add(imported);
|
374 | }
|
375 | }
|
376 | scanImports(sf) {
|
377 | return this.perf.inPhase(PerfPhase.CycleDetection, () => {
|
378 | const imports = new Set();
|
379 | for (const stmt of sf.statements) {
|
380 | if (!ts3.isImportDeclaration(stmt) && !ts3.isExportDeclaration(stmt) || stmt.moduleSpecifier === void 0) {
|
381 | continue;
|
382 | }
|
383 | if (ts3.isImportDeclaration(stmt) && stmt.importClause !== void 0 && isTypeOnlyImportClause(stmt.importClause)) {
|
384 | continue;
|
385 | }
|
386 | const symbol = this.checker.getSymbolAtLocation(stmt.moduleSpecifier);
|
387 | if (symbol === void 0 || symbol.valueDeclaration === void 0) {
|
388 | continue;
|
389 | }
|
390 | const moduleFile = symbol.valueDeclaration;
|
391 | if (ts3.isSourceFile(moduleFile) && isLocalFile(moduleFile)) {
|
392 | imports.add(moduleFile);
|
393 | }
|
394 | }
|
395 | return imports;
|
396 | });
|
397 | }
|
398 | };
|
399 | function isLocalFile(sf) {
|
400 | return !sf.isDeclarationFile;
|
401 | }
|
402 | function isTypeOnlyImportClause(node) {
|
403 | if (node.isTypeOnly) {
|
404 | return true;
|
405 | }
|
406 | if (node.namedBindings !== void 0 && ts3.isNamedImports(node.namedBindings) && node.namedBindings.elements.every((specifier) => specifier.isTypeOnly)) {
|
407 | return true;
|
408 | }
|
409 | return false;
|
410 | }
|
411 | var Found = class {
|
412 | constructor(sourceFile, parent) {
|
413 | this.sourceFile = sourceFile;
|
414 | this.parent = parent;
|
415 | }
|
416 | toPath() {
|
417 | const array = [];
|
418 | let current = this;
|
419 | while (current !== null) {
|
420 | array.push(current.sourceFile);
|
421 | current = current.parent;
|
422 | }
|
423 | return array.reverse();
|
424 | }
|
425 | };
|
426 |
|
427 |
|
428 | import ts4 from "typescript";
|
429 | var FlatIndexGenerator = class {
|
430 | constructor(entryPoint, relativeFlatIndexPath, moduleName) {
|
431 | this.entryPoint = entryPoint;
|
432 | this.moduleName = moduleName;
|
433 | this.shouldEmit = true;
|
434 | this.flatIndexPath = join(dirname(entryPoint), relativeFlatIndexPath).replace(/\.js$/, "") + ".ts";
|
435 | }
|
436 | makeTopLevelShim() {
|
437 | const relativeEntryPoint = relativePathBetween(this.flatIndexPath, this.entryPoint);
|
438 | const contents = `/**
|
439 | * Generated bundle index. Do not edit.
|
440 | */
|
441 |
|
442 | export * from '${relativeEntryPoint}';
|
443 | `;
|
444 | const genFile = ts4.createSourceFile(this.flatIndexPath, contents, ts4.ScriptTarget.ES2015, true, ts4.ScriptKind.TS);
|
445 | if (this.moduleName !== null) {
|
446 | genFile.moduleName = this.moduleName;
|
447 | }
|
448 | return genFile;
|
449 | }
|
450 | };
|
451 |
|
452 |
|
453 | function findFlatIndexEntryPoint(rootFiles) {
|
454 | const tsFiles = rootFiles.filter((file) => isNonDeclarationTsPath(file));
|
455 | let resolvedEntryPoint = null;
|
456 | if (tsFiles.length === 1) {
|
457 | resolvedEntryPoint = tsFiles[0];
|
458 | } else {
|
459 | for (const tsFile of tsFiles) {
|
460 | if (getFileSystem().basename(tsFile) === "index.ts" && (resolvedEntryPoint === null || tsFile.length <= resolvedEntryPoint.length)) {
|
461 | resolvedEntryPoint = tsFile;
|
462 | }
|
463 | }
|
464 | }
|
465 | return resolvedEntryPoint;
|
466 | }
|
467 |
|
468 |
|
469 | import ts5 from "typescript";
|
470 | function checkForPrivateExports(entryPoint, checker, refGraph) {
|
471 | const diagnostics = [];
|
472 | const topLevelExports = new Set();
|
473 | const moduleSymbol = checker.getSymbolAtLocation(entryPoint);
|
474 | if (moduleSymbol === void 0) {
|
475 | throw new Error(`Internal error: failed to get symbol for entrypoint`);
|
476 | }
|
477 | const exportedSymbols = checker.getExportsOfModule(moduleSymbol);
|
478 | exportedSymbols.forEach((symbol) => {
|
479 | if (symbol.flags & ts5.SymbolFlags.Alias) {
|
480 | symbol = checker.getAliasedSymbol(symbol);
|
481 | }
|
482 | const decl = symbol.valueDeclaration;
|
483 | if (decl !== void 0) {
|
484 | topLevelExports.add(decl);
|
485 | }
|
486 | });
|
487 | const checkedSet = new Set();
|
488 | topLevelExports.forEach((mainExport) => {
|
489 | refGraph.transitiveReferencesOf(mainExport).forEach((transitiveReference) => {
|
490 | if (checkedSet.has(transitiveReference)) {
|
491 | return;
|
492 | }
|
493 | checkedSet.add(transitiveReference);
|
494 | if (!topLevelExports.has(transitiveReference)) {
|
495 | const descriptor = getDescriptorOfDeclaration(transitiveReference);
|
496 | const name = getNameOfDeclaration(transitiveReference);
|
497 | let visibleVia = "NgModule exports";
|
498 | const transitivePath = refGraph.pathFrom(mainExport, transitiveReference);
|
499 | if (transitivePath !== null) {
|
500 | visibleVia = transitivePath.map((seg) => getNameOfDeclaration(seg)).join(" -> ");
|
501 | }
|
502 | const diagnostic = __spreadProps(__spreadValues({
|
503 | category: ts5.DiagnosticCategory.Error,
|
504 | code: ngErrorCode(ErrorCode.SYMBOL_NOT_EXPORTED),
|
505 | file: transitiveReference.getSourceFile()
|
506 | }, getPosOfDeclaration(transitiveReference)), {
|
507 | messageText: `Unsupported private ${descriptor} ${name}. This ${descriptor} is visible to consumers via ${visibleVia}, but is not exported from the top-level library entrypoint.`
|
508 | });
|
509 | diagnostics.push(diagnostic);
|
510 | }
|
511 | });
|
512 | });
|
513 | return diagnostics;
|
514 | }
|
515 | function getPosOfDeclaration(decl) {
|
516 | const node = getIdentifierOfDeclaration(decl) || decl;
|
517 | return {
|
518 | start: node.getStart(),
|
519 | length: node.getEnd() + 1 - node.getStart()
|
520 | };
|
521 | }
|
522 | function getIdentifierOfDeclaration(decl) {
|
523 | if ((ts5.isClassDeclaration(decl) || ts5.isVariableDeclaration(decl) || ts5.isFunctionDeclaration(decl)) && decl.name !== void 0 && ts5.isIdentifier(decl.name)) {
|
524 | return decl.name;
|
525 | } else {
|
526 | return null;
|
527 | }
|
528 | }
|
529 | function getNameOfDeclaration(decl) {
|
530 | const id = getIdentifierOfDeclaration(decl);
|
531 | return id !== null ? id.text : "(unnamed)";
|
532 | }
|
533 | function getDescriptorOfDeclaration(decl) {
|
534 | switch (decl.kind) {
|
535 | case ts5.SyntaxKind.ClassDeclaration:
|
536 | return "class";
|
537 | case ts5.SyntaxKind.FunctionDeclaration:
|
538 | return "function";
|
539 | case ts5.SyntaxKind.VariableDeclaration:
|
540 | return "variable";
|
541 | case ts5.SyntaxKind.EnumDeclaration:
|
542 | return "enum";
|
543 | default:
|
544 | return "declaration";
|
545 | }
|
546 | }
|
547 |
|
548 |
|
549 | var ReferenceGraph = class {
|
550 | constructor() {
|
551 | this.references = new Map();
|
552 | }
|
553 | add(from, to) {
|
554 | if (!this.references.has(from)) {
|
555 | this.references.set(from, new Set());
|
556 | }
|
557 | this.references.get(from).add(to);
|
558 | }
|
559 | transitiveReferencesOf(target) {
|
560 | const set = /* @__PURE__ */ new Set();
|
561 | this.collectTransitiveReferences(set, target);
|
562 | return set;
|
563 | }
|
564 | pathFrom(source, target) {
|
565 | return this.collectPathFrom(source, target, new Set());
|
566 | }
|
567 | collectPathFrom(source, target, seen) {
|
568 | if (source === target) {
|
569 | return [target];
|
570 | } else if (seen.has(source)) {
|
571 | return null;
|
572 | }
|
573 | seen.add(source);
|
574 | if (!this.references.has(source)) {
|
575 | return null;
|
576 | } else {
|
577 | let candidatePath = null;
|
578 | this.references.get(source).forEach((edge) => {
|
579 | if (candidatePath !== null) {
|
580 | return;
|
581 | }
|
582 | const partialPath = this.collectPathFrom(edge, target, seen);
|
583 | if (partialPath !== null) {
|
584 | candidatePath = [source, ...partialPath];
|
585 | }
|
586 | });
|
587 | return candidatePath;
|
588 | }
|
589 | }
|
590 | collectTransitiveReferences(set, decl) {
|
591 | if (this.references.has(decl)) {
|
592 | this.references.get(decl).forEach((ref) => {
|
593 | if (!set.has(ref)) {
|
594 | set.add(ref);
|
595 | this.collectTransitiveReferences(set, ref);
|
596 | }
|
597 | });
|
598 | }
|
599 | }
|
600 | };
|
601 |
|
602 | // bazel-out/k8-fastbuild/bin/packages/compiler-cli/src/ngtsc/program_driver/src/api.mjs
|
603 | var NgOriginalFile = Symbol("NgOriginalFile");
|
604 | var UpdateMode;
|
605 | (function(UpdateMode2) {
|
606 | UpdateMode2[UpdateMode2["Complete"] = 0] = "Complete";
|
607 | UpdateMode2[UpdateMode2["Incremental"] = 1] = "Incremental";
|
608 | })(UpdateMode || (UpdateMode = {}));
|
609 |
|
610 |
|
611 | import ts9 from "typescript";
|
612 |
|
613 |
|
614 | import ts6 from "typescript";
|
615 |
|
616 |
|
617 | var NgExtension = Symbol("NgExtension");
|
618 | function isExtended(sf) {
|
619 | return sf[NgExtension] !== void 0;
|
620 | }
|
621 | function sfExtensionData(sf) {
|
622 | const extSf = sf;
|
623 | if (extSf[NgExtension] !== void 0) {
|
624 | return extSf[NgExtension];
|
625 | }
|
626 | const extension = {
|
627 | isTopLevelShim: false,
|
628 | fileShim: null,
|
629 | originalReferencedFiles: null,
|
630 | taggedReferenceFiles: null
|
631 | };
|
632 | extSf[NgExtension] = extension;
|
633 | return extension;
|
634 | }
|
635 | function isFileShimSourceFile(sf) {
|
636 | return isExtended(sf) && sf[NgExtension].fileShim !== null;
|
637 | }
|
638 | function isShim(sf) {
|
639 | return isExtended(sf) && (sf[NgExtension].fileShim !== null || sf[NgExtension].isTopLevelShim);
|
640 | }
|
641 | function copyFileShimData(from, to) {
|
642 | if (!isFileShimSourceFile(from)) {
|
643 | return;
|
644 | }
|
645 | sfExtensionData(to).fileShim = sfExtensionData(from).fileShim;
|
646 | }
|
647 | function untagAllTsFiles(program) {
|
648 | for (const sf of program.getSourceFiles()) {
|
649 | untagTsFile(sf);
|
650 | }
|
651 | }
|
652 | function retagAllTsFiles(program) {
|
653 | for (const sf of program.getSourceFiles()) {
|
654 | retagTsFile(sf);
|
655 | }
|
656 | }
|
657 | function untagTsFile(sf) {
|
658 | if (sf.isDeclarationFile || !isExtended(sf)) {
|
659 | return;
|
660 | }
|
661 | const ext = sfExtensionData(sf);
|
662 | if (ext.originalReferencedFiles !== null) {
|
663 | sf.referencedFiles = ext.originalReferencedFiles;
|
664 | }
|
665 | }
|
666 | function retagTsFile(sf) {
|
667 | if (sf.isDeclarationFile || !isExtended(sf)) {
|
668 | return;
|
669 | }
|
670 | const ext = sfExtensionData(sf);
|
671 | if (ext.taggedReferenceFiles !== null) {
|
672 | sf.referencedFiles = ext.taggedReferenceFiles;
|
673 | }
|
674 | }
|
675 |
|
676 |
|
677 | var TS_EXTENSIONS = /\.tsx?$/i;
|
678 | function makeShimFileName(fileName, suffix) {
|
679 | return absoluteFrom(fileName.replace(TS_EXTENSIONS, suffix));
|
680 | }
|
681 | function generatedModuleName(originalModuleName, originalFileName, genSuffix) {
|
682 | let moduleName;
|
683 | if (originalFileName.endsWith("/index.ts")) {
|
684 | moduleName = originalModuleName + "/index" + genSuffix;
|
685 | } else {
|
686 | moduleName = originalModuleName + genSuffix;
|
687 | }
|
688 | return moduleName;
|
689 | }
|
690 |
|
691 |
|
692 | var ShimAdapter = class {
|
693 | constructor(delegate, tsRootFiles, topLevelGenerators, perFileGenerators, oldProgram) {
|
694 | this.delegate = delegate;
|
695 | this.shims = new Map();
|
696 | this.priorShims = new Map();
|
697 | this.notShims = new Set();
|
698 | this.generators = [];
|
699 | this.ignoreForEmit = new Set();
|
700 | this.extensionPrefixes = [];
|
701 | for (const gen of perFileGenerators) {
|
702 | const pattern = `^(.*)\\.${gen.extensionPrefix}\\.ts$`;
|
703 | const regexp = new RegExp(pattern, "i");
|
704 | this.generators.push({
|
705 | generator: gen,
|
706 | test: regexp,
|
707 | suffix: `.${gen.extensionPrefix}.ts`
|
708 | });
|
709 | this.extensionPrefixes.push(gen.extensionPrefix);
|
710 | }
|
711 | const extraInputFiles = [];
|
712 | for (const gen of topLevelGenerators) {
|
713 | const sf = gen.makeTopLevelShim();
|
714 | sfExtensionData(sf).isTopLevelShim = true;
|
715 | if (!gen.shouldEmit) {
|
716 | this.ignoreForEmit.add(sf);
|
717 | }
|
718 | const fileName = absoluteFromSourceFile(sf);
|
719 | this.shims.set(fileName, sf);
|
720 | extraInputFiles.push(fileName);
|
721 | }
|
722 | for (const rootFile of tsRootFiles) {
|
723 | for (const gen of this.generators) {
|
724 | extraInputFiles.push(makeShimFileName(rootFile, gen.suffix));
|
725 | }
|
726 | }
|
727 | this.extraInputFiles = extraInputFiles;
|
728 | if (oldProgram !== null) {
|
729 | for (const oldSf of oldProgram.getSourceFiles()) {
|
730 | if (oldSf.isDeclarationFile || !isFileShimSourceFile(oldSf)) {
|
731 | continue;
|
732 | }
|
733 | this.priorShims.set(absoluteFromSourceFile(oldSf), oldSf);
|
734 | }
|
735 | }
|
736 | }
|
737 | maybeGenerate(fileName) {
|
738 | if (this.notShims.has(fileName)) {
|
739 | return null;
|
740 | } else if (this.shims.has(fileName)) {
|
741 | return this.shims.get(fileName);
|
742 | }
|
743 | if (isDtsPath(fileName)) {
|
744 | this.notShims.add(fileName);
|
745 | return null;
|
746 | }
|
747 | for (const record of this.generators) {
|
748 | const match = record.test.exec(fileName);
|
749 | if (match === null) {
|
750 | continue;
|
751 | }
|
752 | const prefix = match[1];
|
753 | let baseFileName = absoluteFrom(prefix + ".ts");
|
754 | if (!this.delegate.fileExists(baseFileName)) {
|
755 | baseFileName = absoluteFrom(prefix + ".tsx");
|
756 | if (!this.delegate.fileExists(baseFileName)) {
|
757 | return void 0;
|
758 | }
|
759 | }
|
760 | const inputFile = this.delegate.getSourceFile(baseFileName, ts6.ScriptTarget.Latest);
|
761 | if (inputFile === void 0 || isShim(inputFile)) {
|
762 | return void 0;
|
763 | }
|
764 | return this.generateSpecific(fileName, record.generator, inputFile);
|
765 | }
|
766 | this.notShims.add(fileName);
|
767 | return null;
|
768 | }
|
769 | generateSpecific(fileName, generator, inputFile) {
|
770 | let priorShimSf = null;
|
771 | if (this.priorShims.has(fileName)) {
|
772 | priorShimSf = this.priorShims.get(fileName);
|
773 | this.priorShims.delete(fileName);
|
774 | }
|
775 | const shimSf = generator.generateShimForFile(inputFile, fileName, priorShimSf);
|
776 | sfExtensionData(shimSf).fileShim = {
|
777 | extension: generator.extensionPrefix,
|
778 | generatedFrom: absoluteFromSourceFile(inputFile)
|
779 | };
|
780 | if (!generator.shouldEmit) {
|
781 | this.ignoreForEmit.add(shimSf);
|
782 | }
|
783 | this.shims.set(fileName, shimSf);
|
784 | return shimSf;
|
785 | }
|
786 | };
|
787 |
|
788 |
|
789 | import ts7 from "typescript";
|
790 | var TS_DTS_SUFFIX = /(\.d)?\.ts$/;
|
791 | var STRIP_NG_FACTORY = /(.*)NgFactory$/;
|
792 | var FactoryGenerator = class {
|
793 | constructor() {
|
794 | this.sourceInfo = new Map();
|
795 | this.sourceToFactorySymbols = new Map();
|
796 | this.shouldEmit = true;
|
797 | this.extensionPrefix = "ngfactory";
|
798 | }
|
799 | generateShimForFile(sf, genFilePath) {
|
800 | const absoluteSfPath = absoluteFromSourceFile(sf);
|
801 | const relativePathToSource = "./" + basename(sf.fileName).replace(TS_DTS_SUFFIX, "");
|
802 | const symbolNames = sf.statements.filter(ts7.isClassDeclaration).filter((decl) => isExported(decl) && decl.decorators !== void 0 && decl.name !== void 0).map((decl) => decl.name.text);
|
803 | let sourceText = "";
|
804 | const leadingComment = getFileoverviewComment(sf);
|
805 | if (leadingComment !== null) {
|
806 | sourceText = leadingComment + "\n\n";
|
807 | }
|
808 | if (symbolNames.length > 0) {
|
809 | const varLines = symbolNames.map((name) => `export const ${name}NgFactory: i0.\u0275NgModuleFactory<any> = new i0.\u0275NgModuleFactory(${name});`);
|
810 | sourceText += [
|
811 | `import * as i0 from '@angular/core';`,
|
812 | `import {${symbolNames.join(", ")}} from '${relativePathToSource}';`,
|
813 | ...varLines
|
814 | ].join("\n");
|
815 | }
|
816 | sourceText += "\nexport const \u0275NonEmptyModule = true;";
|
817 | const genFile = ts7.createSourceFile(genFilePath, sourceText, sf.languageVersion, true, ts7.ScriptKind.TS);
|
818 | if (sf.moduleName !== void 0) {
|
819 | genFile.moduleName = generatedModuleName(sf.moduleName, sf.fileName, ".ngfactory");
|
820 | }
|
821 | const moduleSymbols = new Map();
|
822 | this.sourceToFactorySymbols.set(absoluteSfPath, moduleSymbols);
|
823 | this.sourceInfo.set(genFilePath, {
|
824 | sourceFilePath: absoluteSfPath,
|
825 | moduleSymbols
|
826 | });
|
827 | return genFile;
|
828 | }
|
829 | track(sf, moduleInfo) {
|
830 | if (this.sourceToFactorySymbols.has(sf.fileName)) {
|
831 | this.sourceToFactorySymbols.get(sf.fileName).set(moduleInfo.name, moduleInfo);
|
832 | }
|
833 | }
|
834 | };
|
835 | function isExported(decl) {
|
836 | return decl.modifiers !== void 0 && decl.modifiers.some((mod) => mod.kind == ts7.SyntaxKind.ExportKeyword);
|
837 | }
|
838 | function generatedFactoryTransform(factoryMap, importRewriter) {
|
839 | return (context) => {
|
840 | return (file) => {
|
841 | return transformFactorySourceFile(factoryMap, context, importRewriter, file);
|
842 | };
|
843 | };
|
844 | }
|
845 | function transformFactorySourceFile(factoryMap, context, importRewriter, file) {
|
846 | if (!factoryMap.has(file.fileName)) {
|
847 | return file;
|
848 | }
|
849 | const { moduleSymbols, sourceFilePath } = factoryMap.get(file.fileName);
|
850 | const transformedStatements = [];
|
851 | let nonEmptyExport = null;
|
852 | const coreImportIdentifiers = new Set();
|
853 | for (const stmt of file.statements) {
|
854 | if (ts7.isImportDeclaration(stmt) && ts7.isStringLiteral(stmt.moduleSpecifier) && stmt.moduleSpecifier.text === "@angular/core") {
|
855 | const rewrittenModuleSpecifier = importRewriter.rewriteSpecifier("@angular/core", sourceFilePath);
|
856 | if (rewrittenModuleSpecifier !== stmt.moduleSpecifier.text) {
|
857 | transformedStatements.push(ts7.updateImportDeclaration(stmt, stmt.decorators, stmt.modifiers, stmt.importClause, ts7.createStringLiteral(rewrittenModuleSpecifier), void 0));
|
858 | if (stmt.importClause !== void 0 && stmt.importClause.namedBindings !== void 0 && ts7.isNamespaceImport(stmt.importClause.namedBindings)) {
|
859 | coreImportIdentifiers.add(stmt.importClause.namedBindings.name.text);
|
860 | }
|
861 | } else {
|
862 | transformedStatements.push(stmt);
|
863 | }
|
864 | } else if (ts7.isVariableStatement(stmt) && stmt.declarationList.declarations.length === 1) {
|
865 | const decl = stmt.declarationList.declarations[0];
|
866 | if (ts7.isIdentifier(decl.name)) {
|
867 | if (decl.name.text === "\u0275NonEmptyModule") {
|
868 | nonEmptyExport = stmt;
|
869 | continue;
|
870 | }
|
871 | const match = STRIP_NG_FACTORY.exec(decl.name.text);
|
872 | const module = match ? moduleSymbols.get(match[1]) : null;
|
873 | if (module) {
|
874 | const moduleIsTreeShakable = !module.hasId;
|
875 | const newStmt = !moduleIsTreeShakable ? stmt : updateInitializers(stmt, (init) => init ? wrapInNoSideEffects(init) : void 0);
|
876 | transformedStatements.push(newStmt);
|
877 | }
|
878 | } else {
|
879 | transformedStatements.push(stmt);
|
880 | }
|
881 | } else {
|
882 | transformedStatements.push(stmt);
|
883 | }
|
884 | }
|
885 | if (!transformedStatements.some(ts7.isVariableStatement) && nonEmptyExport !== null) {
|
886 | transformedStatements.push(nonEmptyExport);
|
887 | }
|
888 | file = ts7.updateSourceFileNode(file, transformedStatements);
|
889 | if (coreImportIdentifiers.size > 0) {
|
890 | const visit = (node) => {
|
891 | node = ts7.visitEachChild(node, (child) => visit(child), context);
|
892 | if (ts7.isPropertyAccessExpression(node) && ts7.isIdentifier(node.expression) && coreImportIdentifiers.has(node.expression.text)) {
|
893 | const rewrittenSymbol = importRewriter.rewriteSymbol(node.name.text, "@angular/core");
|
894 | if (rewrittenSymbol !== node.name.text) {
|
895 | const updated = ts7.updatePropertyAccess(node, node.expression, ts7.createIdentifier(rewrittenSymbol));
|
896 | node = updated;
|
897 | }
|
898 | }
|
899 | return node;
|
900 | };
|
901 | file = visit(file);
|
902 | }
|
903 | return file;
|
904 | }
|
905 | function getFileoverviewComment(sourceFile) {
|
906 | const text = sourceFile.getFullText();
|
907 | const trivia = text.substring(0, sourceFile.getStart());
|
908 | const leadingComments = ts7.getLeadingCommentRanges(trivia, 0);
|
909 | if (!leadingComments || leadingComments.length === 0) {
|
910 | return null;
|
911 | }
|
912 | const comment = leadingComments[0];
|
913 | if (comment.kind !== ts7.SyntaxKind.MultiLineCommentTrivia) {
|
914 | return null;
|
915 | }
|
916 | if (text.substring(comment.end, comment.end + 2) !== "\n\n") {
|
917 | return null;
|
918 | }
|
919 | const commentText = text.substring(comment.pos, comment.end);
|
920 | if (commentText.indexOf("@license") !== -1) {
|
921 | return null;
|
922 | }
|
923 | return commentText;
|
924 | }
|
925 | function wrapInNoSideEffects(expr) {
|
926 | const noSideEffects = ts7.createPropertyAccess(ts7.createIdentifier("i0"), "\u0275noSideEffects");
|
927 | return ts7.createCall(noSideEffects, [], [
|
928 | ts7.createFunctionExpression([], void 0, void 0, [], [], void 0, ts7.createBlock([
|
929 | ts7.createReturn(expr)
|
930 | ]))
|
931 | ]);
|
932 | }
|
933 | function updateInitializers(stmt, update) {
|
934 | return ts7.updateVariableStatement(stmt, stmt.modifiers, ts7.updateVariableDeclarationList(stmt.declarationList, stmt.declarationList.declarations.map((decl) => ts7.updateVariableDeclaration(decl, decl.name, decl.type, update(decl.initializer)))));
|
935 | }
|
936 |
|
937 |
|
938 | var ShimReferenceTagger = class {
|
939 | constructor(shimExtensions) {
|
940 | this.tagged = new Set();
|
941 | this.enabled = true;
|
942 | this.suffixes = shimExtensions.map((extension) => `.${extension}.ts`);
|
943 | }
|
944 | tag(sf) {
|
945 | if (!this.enabled || sf.isDeclarationFile || isShim(sf) || this.tagged.has(sf) || !isNonDeclarationTsPath(sf.fileName)) {
|
946 | return;
|
947 | }
|
948 | const ext = sfExtensionData(sf);
|
949 | if (ext.originalReferencedFiles === null) {
|
950 | ext.originalReferencedFiles = sf.referencedFiles;
|
951 | }
|
952 | const referencedFiles = [...ext.originalReferencedFiles];
|
953 | const sfPath = absoluteFromSourceFile(sf);
|
954 | for (const suffix of this.suffixes) {
|
955 | referencedFiles.push({
|
956 | fileName: makeShimFileName(sfPath, suffix),
|
957 | pos: 0,
|
958 | end: 0
|
959 | });
|
960 | }
|
961 | ext.taggedReferenceFiles = referencedFiles;
|
962 | sf.referencedFiles = referencedFiles;
|
963 | this.tagged.add(sf);
|
964 | }
|
965 | finalize() {
|
966 | this.enabled = false;
|
967 | this.tagged.clear();
|
968 | }
|
969 | };
|
970 |
|
971 |
|
972 | import ts8 from "typescript";
|
973 | var SummaryGenerator = class {
|
974 | constructor() {
|
975 | this.shouldEmit = true;
|
976 | this.extensionPrefix = "ngsummary";
|
977 | }
|
978 | generateShimForFile(sf, genFilePath) {
|
979 | const symbolNames = [];
|
980 | for (const stmt of sf.statements) {
|
981 | if (ts8.isClassDeclaration(stmt)) {
|
982 | if (!isExported2(stmt) || stmt.decorators === void 0 || stmt.name === void 0) {
|
983 | continue;
|
984 | }
|
985 | symbolNames.push(stmt.name.text);
|
986 | } else if (ts8.isExportDeclaration(stmt)) {
|
987 | if (stmt.exportClause === void 0 || stmt.moduleSpecifier !== void 0 || !ts8.isNamedExports(stmt.exportClause)) {
|
988 | continue;
|
989 | }
|
990 | for (const specifier of stmt.exportClause.elements) {
|
991 | symbolNames.push(specifier.name.text);
|
992 | }
|
993 | }
|
994 | }
|
995 | const varLines = symbolNames.map((name) => `export const ${name}NgSummary: any = null;`);
|
996 | if (varLines.length === 0) {
|
997 | varLines.push(`export const \u0275empty = null;`);
|
998 | }
|
999 | const sourceText = varLines.join("\n");
|
1000 | const genFile = ts8.createSourceFile(genFilePath, sourceText, sf.languageVersion, true, ts8.ScriptKind.TS);
|
1001 | if (sf.moduleName !== void 0) {
|
1002 | genFile.moduleName = generatedModuleName(sf.moduleName, sf.fileName, ".ngsummary");
|
1003 | }
|
1004 | return genFile;
|
1005 | }
|
1006 | };
|
1007 | function isExported2(decl) {
|
1008 | return decl.modifiers !== void 0 && decl.modifiers.some((mod) => mod.kind == ts8.SyntaxKind.ExportKeyword);
|
1009 | }
|
1010 |
|
1011 |
|
1012 | var DelegatingCompilerHost = class {
|
1013 | constructor(delegate) {
|
1014 | this.delegate = delegate;
|
1015 | this.createHash = this.delegateMethod("createHash");
|
1016 | this.directoryExists = this.delegateMethod("directoryExists");
|
1017 | this.getCancellationToken = this.delegateMethod("getCancellationToken");
|
1018 | this.getCanonicalFileName = this.delegateMethod("getCanonicalFileName");
|
1019 | this.getCurrentDirectory = this.delegateMethod("getCurrentDirectory");
|
1020 | this.getDefaultLibFileName = this.delegateMethod("getDefaultLibFileName");
|
1021 | this.getDefaultLibLocation = this.delegateMethod("getDefaultLibLocation");
|
1022 | this.getDirectories = this.delegateMethod("getDirectories");
|
1023 | this.getEnvironmentVariable = this.delegateMethod("getEnvironmentVariable");
|
1024 | this.getNewLine = this.delegateMethod("getNewLine");
|
1025 | this.getParsedCommandLine = this.delegateMethod("getParsedCommandLine");
|
1026 | this.getSourceFileByPath = this.delegateMethod("getSourceFileByPath");
|
1027 | this.readDirectory = this.delegateMethod("readDirectory");
|
1028 | this.readFile = this.delegateMethod("readFile");
|
1029 | this.realpath = this.delegateMethod("realpath");
|
1030 | this.resolveModuleNames = this.delegateMethod("resolveModuleNames");
|
1031 | this.resolveTypeReferenceDirectives = this.delegateMethod("resolveTypeReferenceDirectives");
|
1032 | this.trace = this.delegateMethod("trace");
|
1033 | this.useCaseSensitiveFileNames = this.delegateMethod("useCaseSensitiveFileNames");
|
1034 | this.getModuleResolutionCache = this.delegateMethod("getModuleResolutionCache");
|
1035 | }
|
1036 | delegateMethod(name) {
|
1037 | return this.delegate[name] !== void 0 ? this.delegate[name].bind(this.delegate) : void 0;
|
1038 | }
|
1039 | };
|
1040 | var UpdatedProgramHost = class extends DelegatingCompilerHost {
|
1041 | constructor(sfMap, originalProgram, delegate, shimExtensionPrefixes) {
|
1042 | super(delegate);
|
1043 | this.originalProgram = originalProgram;
|
1044 | this.shimExtensionPrefixes = shimExtensionPrefixes;
|
1045 | this.shimTagger = new ShimReferenceTagger(this.shimExtensionPrefixes);
|
1046 | this.sfMap = sfMap;
|
1047 | }
|
1048 | getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
|
1049 | let delegateSf = this.originalProgram.getSourceFile(fileName);
|
1050 | if (delegateSf === void 0) {
|
1051 | delegateSf = this.delegate.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
|
1052 | }
|
1053 | if (delegateSf === void 0) {
|
1054 | return void 0;
|
1055 | }
|
1056 | let sf;
|
1057 | if (this.sfMap.has(fileName)) {
|
1058 | sf = this.sfMap.get(fileName);
|
1059 | copyFileShimData(delegateSf, sf);
|
1060 | } else {
|
1061 | sf = delegateSf;
|
1062 | }
|
1063 | sf = toUnredirectedSourceFile(sf);
|
1064 | this.shimTagger.tag(sf);
|
1065 | return sf;
|
1066 | }
|
1067 | postProgramCreationCleanup() {
|
1068 | this.shimTagger.finalize();
|
1069 | }
|
1070 | writeFile() {
|
1071 | throw new Error(`TypeCheckProgramHost should never write files`);
|
1072 | }
|
1073 | fileExists(fileName) {
|
1074 | return this.sfMap.has(fileName) || this.delegate.fileExists(fileName);
|
1075 | }
|
1076 | };
|
1077 | var TsCreateProgramDriver = class {
|
1078 | constructor(originalProgram, originalHost, options, shimExtensionPrefixes) {
|
1079 | this.originalProgram = originalProgram;
|
1080 | this.originalHost = originalHost;
|
1081 | this.options = options;
|
1082 | this.shimExtensionPrefixes = shimExtensionPrefixes;
|
1083 | this.sfMap = new Map();
|
1084 | this.program = this.originalProgram;
|
1085 | this.supportsInlineOperations = true;
|
1086 | }
|
1087 | getProgram() {
|
1088 | return this.program;
|
1089 | }
|
1090 | updateFiles(contents, updateMode) {
|
1091 | if (contents.size === 0) {
|
1092 | if (updateMode !== UpdateMode.Complete || this.sfMap.size === 0) {
|
1093 | return;
|
1094 | }
|
1095 | }
|
1096 | if (updateMode === UpdateMode.Complete) {
|
1097 | this.sfMap.clear();
|
1098 | }
|
1099 | for (const [filePath, { newText, originalFile }] of contents.entries()) {
|
1100 | const sf = ts9.createSourceFile(filePath, newText, ts9.ScriptTarget.Latest, true);
|
1101 | if (originalFile !== null) {
|
1102 | sf[NgOriginalFile] = originalFile;
|
1103 | }
|
1104 | this.sfMap.set(filePath, sf);
|
1105 | }
|
1106 | const host = new UpdatedProgramHost(this.sfMap, this.originalProgram, this.originalHost, this.shimExtensionPrefixes);
|
1107 | const oldProgram = this.program;
|
1108 | retagAllTsFiles(oldProgram);
|
1109 | this.program = ts9.createProgram({
|
1110 | host,
|
1111 | rootNames: this.program.getRootFileNames(),
|
1112 | options: this.options,
|
1113 | oldProgram
|
1114 | });
|
1115 | host.postProgramCreationCleanup();
|
1116 | untagAllTsFiles(this.program);
|
1117 | untagAllTsFiles(oldProgram);
|
1118 | }
|
1119 | };
|
1120 |
|
1121 |
|
1122 | var FileDependencyGraph = class {
|
1123 | constructor() {
|
1124 | this.nodes = new Map();
|
1125 | }
|
1126 | addDependency(from, on) {
|
1127 | this.nodeFor(from).dependsOn.add(absoluteFromSourceFile(on));
|
1128 | }
|
1129 | addResourceDependency(from, resource) {
|
1130 | this.nodeFor(from).usesResources.add(resource);
|
1131 | }
|
1132 | recordDependencyAnalysisFailure(file) {
|
1133 | this.nodeFor(file).failedAnalysis = true;
|
1134 | }
|
1135 | getResourceDependencies(from) {
|
1136 | const node = this.nodes.get(from);
|
1137 | return node ? [...node.usesResources] : [];
|
1138 | }
|
1139 | updateWithPhysicalChanges(previous, changedTsPaths, deletedTsPaths, changedResources) {
|
1140 | const logicallyChanged = new Set();
|
1141 | for (const sf of previous.nodes.keys()) {
|
1142 | const sfPath = absoluteFromSourceFile(sf);
|
1143 | const node = previous.nodeFor(sf);
|
1144 | if (isLogicallyChanged(sf, node, changedTsPaths, deletedTsPaths, changedResources)) {
|
1145 | logicallyChanged.add(sfPath);
|
1146 | } else if (!deletedTsPaths.has(sfPath)) {
|
1147 | this.nodes.set(sf, {
|
1148 | dependsOn: new Set(node.dependsOn),
|
1149 | usesResources: new Set(node.usesResources),
|
1150 | failedAnalysis: false
|
1151 | });
|
1152 | }
|
1153 | }
|
1154 | return logicallyChanged;
|
1155 | }
|
1156 | nodeFor(sf) {
|
1157 | if (!this.nodes.has(sf)) {
|
1158 | this.nodes.set(sf, {
|
1159 | dependsOn: new Set(),
|
1160 | usesResources: new Set(),
|
1161 | failedAnalysis: false
|
1162 | });
|
1163 | }
|
1164 | return this.nodes.get(sf);
|
1165 | }
|
1166 | };
|
1167 | function isLogicallyChanged(sf, node, changedTsPaths, deletedTsPaths, changedResources) {
|
1168 | if (node.failedAnalysis) {
|
1169 | return true;
|
1170 | }
|
1171 | const sfPath = absoluteFromSourceFile(sf);
|
1172 | if (changedTsPaths.has(sfPath) || deletedTsPaths.has(sfPath)) {
|
1173 | return true;
|
1174 | }
|
1175 | for (const dep of node.dependsOn) {
|
1176 | if (changedTsPaths.has(dep) || deletedTsPaths.has(dep)) {
|
1177 | return true;
|
1178 | }
|
1179 | }
|
1180 | for (const dep of node.usesResources) {
|
1181 | if (changedResources.has(dep)) {
|
1182 | return true;
|
1183 | }
|
1184 | }
|
1185 | return false;
|
1186 | }
|
1187 |
|
1188 |
|
1189 | var IncrementalStateKind;
|
1190 | (function(IncrementalStateKind2) {
|
1191 | IncrementalStateKind2[IncrementalStateKind2["Fresh"] = 0] = "Fresh";
|
1192 | IncrementalStateKind2[IncrementalStateKind2["Delta"] = 1] = "Delta";
|
1193 | IncrementalStateKind2[IncrementalStateKind2["Analyzed"] = 2] = "Analyzed";
|
1194 | })(IncrementalStateKind || (IncrementalStateKind = {}));
|
1195 |
|
1196 |
|
1197 | var PhaseKind;
|
1198 | (function(PhaseKind2) {
|
1199 | PhaseKind2[PhaseKind2["Analysis"] = 0] = "Analysis";
|
1200 | PhaseKind2[PhaseKind2["TypeCheckAndEmit"] = 1] = "TypeCheckAndEmit";
|
1201 | })(PhaseKind || (PhaseKind = {}));
|
1202 | var IncrementalCompilation = class {
|
1203 | constructor(state, depGraph, versions, step) {
|
1204 | this.depGraph = depGraph;
|
1205 | this.versions = versions;
|
1206 | this.step = step;
|
1207 | this._state = state;
|
1208 | this.phase = {
|
1209 | kind: PhaseKind.Analysis,
|
1210 | semanticDepGraphUpdater: new SemanticDepGraphUpdater(step !== null ? step.priorState.semanticDepGraph : null)
|
1211 | };
|
1212 | }
|
1213 | static fresh(program, versions) {
|
1214 | const state = {
|
1215 | kind: IncrementalStateKind.Fresh
|
1216 | };
|
1217 | return new IncrementalCompilation(state, new FileDependencyGraph(), versions, null);
|
1218 | }
|
1219 | static incremental(program, newVersions, oldProgram, oldState, modifiedResourceFiles, perf) {
|
1220 | return perf.inPhase(PerfPhase.Reconciliation, () => {
|
1221 | const physicallyChangedTsFiles = new Set();
|
1222 | const changedResourceFiles = new Set(modifiedResourceFiles != null ? modifiedResourceFiles : []);
|
1223 | let priorAnalysis;
|
1224 | switch (oldState.kind) {
|
1225 | case IncrementalStateKind.Fresh:
|
1226 | return IncrementalCompilation.fresh(program, newVersions);
|
1227 | case IncrementalStateKind.Analyzed:
|
1228 | priorAnalysis = oldState;
|
1229 | break;
|
1230 | case IncrementalStateKind.Delta:
|
1231 | priorAnalysis = oldState.lastAnalyzedState;
|
1232 | for (const sfPath of oldState.physicallyChangedTsFiles) {
|
1233 | physicallyChangedTsFiles.add(sfPath);
|
1234 | }
|
1235 | for (const resourcePath of oldState.changedResourceFiles) {
|
1236 | changedResourceFiles.add(resourcePath);
|
1237 | }
|
1238 | break;
|
1239 | }
|
1240 | const oldVersions = priorAnalysis.versions;
|
1241 | const oldFilesArray = oldProgram.getSourceFiles().map(toOriginalSourceFile);
|
1242 | const oldFiles = new Set(oldFilesArray);
|
1243 | const deletedTsFiles = new Set(oldFilesArray.map((sf) => absoluteFromSourceFile(sf)));
|
1244 | for (const possiblyRedirectedNewFile of program.getSourceFiles()) {
|
1245 | const sf = toOriginalSourceFile(possiblyRedirectedNewFile);
|
1246 | const sfPath = absoluteFromSourceFile(sf);
|
1247 | deletedTsFiles.delete(sfPath);
|
1248 | if (oldFiles.has(sf)) {
|
1249 | if (oldVersions === null || newVersions === null) {
|
1250 | continue;
|
1251 | }
|
1252 | if (oldVersions.has(sfPath) && newVersions.has(sfPath) && oldVersions.get(sfPath) === newVersions.get(sfPath)) {
|
1253 | continue;
|
1254 | }
|
1255 | }
|
1256 | if (sf.isDeclarationFile) {
|
1257 | return IncrementalCompilation.fresh(program, newVersions);
|
1258 | }
|
1259 | physicallyChangedTsFiles.add(sfPath);
|
1260 | }
|
1261 | for (const deletedFileName of deletedTsFiles) {
|
1262 | physicallyChangedTsFiles.delete(resolve(deletedFileName));
|
1263 | }
|
1264 | const depGraph = new FileDependencyGraph();
|
1265 | const logicallyChangedTsFiles = depGraph.updateWithPhysicalChanges(priorAnalysis.depGraph, physicallyChangedTsFiles, deletedTsFiles, changedResourceFiles);
|
1266 | for (const sfPath of physicallyChangedTsFiles) {
|
1267 | logicallyChangedTsFiles.add(sfPath);
|
1268 | }
|
1269 | const state = {
|
1270 | kind: IncrementalStateKind.Delta,
|
1271 | physicallyChangedTsFiles,
|
1272 | changedResourceFiles,
|
1273 | lastAnalyzedState: priorAnalysis
|
1274 | };
|
1275 | return new IncrementalCompilation(state, depGraph, newVersions, {
|
1276 | priorState: priorAnalysis,
|
1277 | logicallyChangedTsFiles
|
1278 | });
|
1279 | });
|
1280 | }
|
1281 | get state() {
|
1282 | return this._state;
|
1283 | }
|
1284 | get semanticDepGraphUpdater() {
|
1285 | if (this.phase.kind !== PhaseKind.Analysis) {
|
1286 | throw new Error(`AssertionError: Cannot update the SemanticDepGraph after analysis completes`);
|
1287 | }
|
1288 | return this.phase.semanticDepGraphUpdater;
|
1289 | }
|
1290 | recordSuccessfulAnalysis(traitCompiler) {
|
1291 | if (this.phase.kind !== PhaseKind.Analysis) {
|
1292 | throw new Error(`AssertionError: Incremental compilation in phase ${PhaseKind[this.phase.kind]}, expected Analysis`);
|
1293 | }
|
1294 | const { needsEmit, needsTypeCheckEmit, newGraph } = this.phase.semanticDepGraphUpdater.finalize();
|
1295 | let emitted;
|
1296 | if (this.step === null) {
|
1297 | emitted = new Set();
|
1298 | } else {
|
1299 | emitted = new Set(this.step.priorState.emitted);
|
1300 | for (const sfPath of this.step.logicallyChangedTsFiles) {
|
1301 | emitted.delete(sfPath);
|
1302 | }
|
1303 | for (const sfPath of needsEmit) {
|
1304 | emitted.delete(sfPath);
|
1305 | }
|
1306 | }
|
1307 | this._state = {
|
1308 | kind: IncrementalStateKind.Analyzed,
|
1309 | versions: this.versions,
|
1310 | depGraph: this.depGraph,
|
1311 | semanticDepGraph: newGraph,
|
1312 | priorAnalysis: traitCompiler.getAnalyzedRecords(),
|
1313 | typeCheckResults: null,
|
1314 | emitted
|
1315 | };
|
1316 | this.phase = {
|
1317 | kind: PhaseKind.TypeCheckAndEmit,
|
1318 | needsEmit,
|
1319 | needsTypeCheckEmit
|
1320 | };
|
1321 | }
|
1322 | recordSuccessfulTypeCheck(results) {
|
1323 | if (this._state.kind !== IncrementalStateKind.Analyzed) {
|
1324 | throw new Error(`AssertionError: Expected successfully analyzed compilation.`);
|
1325 | } else if (this.phase.kind !== PhaseKind.TypeCheckAndEmit) {
|
1326 | throw new Error(`AssertionError: Incremental compilation in phase ${PhaseKind[this.phase.kind]}, expected TypeCheck`);
|
1327 | }
|
1328 | this._state.typeCheckResults = results;
|
1329 | }
|
1330 | recordSuccessfulEmit(sf) {
|
1331 | if (this._state.kind !== IncrementalStateKind.Analyzed) {
|
1332 | throw new Error(`AssertionError: Expected successfully analyzed compilation.`);
|
1333 | }
|
1334 | this._state.emitted.add(absoluteFromSourceFile(sf));
|
1335 | }
|
1336 | priorAnalysisFor(sf) {
|
1337 | if (this.step === null) {
|
1338 | return null;
|
1339 | }
|
1340 | const sfPath = absoluteFromSourceFile(sf);
|
1341 | if (this.step.logicallyChangedTsFiles.has(sfPath)) {
|
1342 | return null;
|
1343 | }
|
1344 | const priorAnalysis = this.step.priorState.priorAnalysis;
|
1345 | if (!priorAnalysis.has(sf)) {
|
1346 | return null;
|
1347 | }
|
1348 | return priorAnalysis.get(sf);
|
1349 | }
|
1350 | priorTypeCheckingResultsFor(sf) {
|
1351 | if (this.phase.kind !== PhaseKind.TypeCheckAndEmit) {
|
1352 | throw new Error(`AssertionError: Expected successfully analyzed compilation.`);
|
1353 | }
|
1354 | if (this.step === null) {
|
1355 | return null;
|
1356 | }
|
1357 | const sfPath = absoluteFromSourceFile(sf);
|
1358 | if (this.step.logicallyChangedTsFiles.has(sfPath) || this.phase.needsTypeCheckEmit.has(sfPath)) {
|
1359 | return null;
|
1360 | }
|
1361 | if (this.step.priorState.typeCheckResults === null || !this.step.priorState.typeCheckResults.has(sfPath)) {
|
1362 | return null;
|
1363 | }
|
1364 | const priorResults = this.step.priorState.typeCheckResults.get(sfPath);
|
1365 | if (priorResults.hasInlines) {
|
1366 | return null;
|
1367 | }
|
1368 | return priorResults;
|
1369 | }
|
1370 | safeToSkipEmit(sf) {
|
1371 | if (this.step === null) {
|
1372 | return false;
|
1373 | }
|
1374 | const sfPath = absoluteFromSourceFile(sf);
|
1375 | if (this.step.logicallyChangedTsFiles.has(sfPath)) {
|
1376 | return false;
|
1377 | }
|
1378 | if (this.phase.kind !== PhaseKind.TypeCheckAndEmit) {
|
1379 | throw new Error(`AssertionError: Expected successful analysis before attempting to emit files`);
|
1380 | }
|
1381 | if (this.phase.needsEmit.has(sfPath)) {
|
1382 | return false;
|
1383 | }
|
1384 | return this.step.priorState.emitted.has(sfPath);
|
1385 | }
|
1386 | };
|
1387 | function toOriginalSourceFile(sf) {
|
1388 | const unredirectedSf = toUnredirectedSourceFile(sf);
|
1389 | const originalFile = unredirectedSf[NgOriginalFile];
|
1390 | if (originalFile !== void 0) {
|
1391 | return originalFile;
|
1392 | } else {
|
1393 | return unredirectedSf;
|
1394 | }
|
1395 | }
|
1396 |
|
1397 |
|
1398 | var TrackedIncrementalBuildStrategy = class {
|
1399 | constructor() {
|
1400 | this.state = null;
|
1401 | this.isSet = false;
|
1402 | }
|
1403 | getIncrementalState() {
|
1404 | return this.state;
|
1405 | }
|
1406 | setIncrementalState(state) {
|
1407 | this.state = state;
|
1408 | this.isSet = true;
|
1409 | }
|
1410 | toNextBuildStrategy() {
|
1411 | const strategy = new TrackedIncrementalBuildStrategy();
|
1412 | strategy.state = this.isSet ? this.state : null;
|
1413 | return strategy;
|
1414 | }
|
1415 | };
|
1416 | var PatchedProgramIncrementalBuildStrategy = class {
|
1417 | getIncrementalState(program) {
|
1418 | const state = program[SYM_INCREMENTAL_STATE];
|
1419 | if (state === void 0) {
|
1420 | return null;
|
1421 | }
|
1422 | return state;
|
1423 | }
|
1424 | setIncrementalState(state, program) {
|
1425 | program[SYM_INCREMENTAL_STATE] = state;
|
1426 | }
|
1427 | toNextBuildStrategy() {
|
1428 | return this;
|
1429 | }
|
1430 | };
|
1431 | var SYM_INCREMENTAL_STATE = Symbol("NgIncrementalState");
|
1432 |
|
1433 |
|
1434 | var IdentifierKind;
|
1435 | (function(IdentifierKind2) {
|
1436 | IdentifierKind2[IdentifierKind2["Property"] = 0] = "Property";
|
1437 | IdentifierKind2[IdentifierKind2["Method"] = 1] = "Method";
|
1438 | IdentifierKind2[IdentifierKind2["Element"] = 2] = "Element";
|
1439 | IdentifierKind2[IdentifierKind2["Template"] = 3] = "Template";
|
1440 | IdentifierKind2[IdentifierKind2["Attribute"] = 4] = "Attribute";
|
1441 | IdentifierKind2[IdentifierKind2["Reference"] = 5] = "Reference";
|
1442 | IdentifierKind2[IdentifierKind2["Variable"] = 6] = "Variable";
|
1443 | })(IdentifierKind || (IdentifierKind = {}));
|
1444 | var AbsoluteSourceSpan = class {
|
1445 | constructor(start, end) {
|
1446 | this.start = start;
|
1447 | this.end = end;
|
1448 | }
|
1449 | };
|
1450 |
|
1451 |
|
1452 | var IndexingContext = class {
|
1453 | constructor() {
|
1454 | this.components = new Set();
|
1455 | }
|
1456 | addComponent(info) {
|
1457 | this.components.add(info);
|
1458 | }
|
1459 | };
|
1460 |
|
1461 |
|
1462 | import { ParseSourceFile } from "@angular/compiler";
|
1463 |
|
1464 |
|
1465 | import { ASTWithSource, ImplicitReceiver, PropertyRead, PropertyWrite, RecursiveAstVisitor, TmplAstElement, TmplAstRecursiveVisitor, TmplAstReference, TmplAstTemplate } from "@angular/compiler";
|
1466 | var ExpressionVisitor = class extends RecursiveAstVisitor {
|
1467 | constructor(expressionStr, absoluteOffset, boundTemplate, targetToIdentifier) {
|
1468 | super();
|
1469 | this.expressionStr = expressionStr;
|
1470 | this.absoluteOffset = absoluteOffset;
|
1471 | this.boundTemplate = boundTemplate;
|
1472 | this.targetToIdentifier = targetToIdentifier;
|
1473 | this.identifiers = [];
|
1474 | this.errors = [];
|
1475 | }
|
1476 | static getIdentifiers(ast, source, absoluteOffset, boundTemplate, targetToIdentifier) {
|
1477 | const visitor = new ExpressionVisitor(source, absoluteOffset, boundTemplate, targetToIdentifier);
|
1478 | visitor.visit(ast);
|
1479 | return { identifiers: visitor.identifiers, errors: visitor.errors };
|
1480 | }
|
1481 | visit(ast) {
|
1482 | ast.visit(this);
|
1483 | }
|
1484 | visitPropertyRead(ast, context) {
|
1485 | this.visitIdentifier(ast, IdentifierKind.Property);
|
1486 | super.visitPropertyRead(ast, context);
|
1487 | }
|
1488 | visitPropertyWrite(ast, context) {
|
1489 | this.visitIdentifier(ast, IdentifierKind.Property);
|
1490 | super.visitPropertyWrite(ast, context);
|
1491 | }
|
1492 | visitIdentifier(ast, kind) {
|
1493 | if (!(ast.receiver instanceof ImplicitReceiver)) {
|
1494 | return;
|
1495 | }
|
1496 | let identifierStart = ast.sourceSpan.start - this.absoluteOffset;
|
1497 | if (ast instanceof PropertyRead || ast instanceof PropertyWrite) {
|
1498 | identifierStart = ast.nameSpan.start - this.absoluteOffset;
|
1499 | }
|
1500 | if (!this.expressionStr.substring(identifierStart).startsWith(ast.name)) {
|
1501 | this.errors.push(new Error(`Impossible state: "${ast.name}" not found in "${this.expressionStr}" at location ${identifierStart}`));
|
1502 | return;
|
1503 | }
|
1504 | const absoluteStart = this.absoluteOffset + identifierStart;
|
1505 | const span = new AbsoluteSourceSpan(absoluteStart, absoluteStart + ast.name.length);
|
1506 | const targetAst = this.boundTemplate.getExpressionTarget(ast);
|
1507 | const target = targetAst ? this.targetToIdentifier(targetAst) : null;
|
1508 | const identifier = {
|
1509 | name: ast.name,
|
1510 | span,
|
1511 | kind,
|
1512 | target
|
1513 | };
|
1514 | this.identifiers.push(identifier);
|
1515 | }
|
1516 | };
|
1517 | var TemplateVisitor = class extends TmplAstRecursiveVisitor {
|
1518 | constructor(boundTemplate) {
|
1519 | super();
|
1520 | this.boundTemplate = boundTemplate;
|
1521 | this.identifiers = new Set();
|
1522 | this.errors = [];
|
1523 | this.targetIdentifierCache = new Map();
|
1524 | this.elementAndTemplateIdentifierCache = new Map();
|
1525 | }
|
1526 | visit(node) {
|
1527 | node.visit(this);
|
1528 | }
|
1529 | visitAll(nodes) {
|
1530 | nodes.forEach((node) => this.visit(node));
|
1531 | }
|
1532 | visitElement(element) {
|
1533 | const elementIdentifier = this.elementOrTemplateToIdentifier(element);
|
1534 | if (elementIdentifier !== null) {
|
1535 | this.identifiers.add(elementIdentifier);
|
1536 | }
|
1537 | this.visitAll(element.references);
|
1538 | this.visitAll(element.inputs);
|
1539 | this.visitAll(element.attributes);
|
1540 | this.visitAll(element.children);
|
1541 | this.visitAll(element.outputs);
|
1542 | }
|
1543 | visitTemplate(template) {
|
1544 | const templateIdentifier = this.elementOrTemplateToIdentifier(template);
|
1545 | if (templateIdentifier !== null) {
|
1546 | this.identifiers.add(templateIdentifier);
|
1547 | }
|
1548 | this.visitAll(template.variables);
|
1549 | this.visitAll(template.attributes);
|
1550 | this.visitAll(template.templateAttrs);
|
1551 | this.visitAll(template.children);
|
1552 | this.visitAll(template.references);
|
1553 | }
|
1554 | visitBoundAttribute(attribute) {
|
1555 | if (attribute.valueSpan === void 0) {
|
1556 | return;
|
1557 | }
|
1558 | const { identifiers, errors } = ExpressionVisitor.getIdentifiers(attribute.value, attribute.valueSpan.toString(), attribute.valueSpan.start.offset, this.boundTemplate, this.targetToIdentifier.bind(this));
|
1559 | identifiers.forEach((id) => this.identifiers.add(id));
|
1560 | this.errors.push(...errors);
|
1561 | }
|
1562 | visitBoundEvent(attribute) {
|
1563 | this.visitExpression(attribute.handler);
|
1564 | }
|
1565 | visitBoundText(text) {
|
1566 | this.visitExpression(text.value);
|
1567 | }
|
1568 | visitReference(reference) {
|
1569 | const referenceIdentifer = this.targetToIdentifier(reference);
|
1570 | if (referenceIdentifer === null) {
|
1571 | return;
|
1572 | }
|
1573 | this.identifiers.add(referenceIdentifer);
|
1574 | }
|
1575 | visitVariable(variable) {
|
1576 | const variableIdentifier = this.targetToIdentifier(variable);
|
1577 | if (variableIdentifier === null) {
|
1578 | return;
|
1579 | }
|
1580 | this.identifiers.add(variableIdentifier);
|
1581 | }
|
1582 | elementOrTemplateToIdentifier(node) {
|
1583 | var _a;
|
1584 | if (this.elementAndTemplateIdentifierCache.has(node)) {
|
1585 | return this.elementAndTemplateIdentifierCache.get(node);
|
1586 | }
|
1587 | let name;
|
1588 | let kind;
|
1589 | if (node instanceof TmplAstTemplate) {
|
1590 | name = (_a = node.tagName) != null ? _a : "ng-template";
|
1591 | kind = IdentifierKind.Template;
|
1592 | } else {
|
1593 | name = node.name;
|
1594 | kind = IdentifierKind.Element;
|
1595 | }
|
1596 | if (name.startsWith(":")) {
|
1597 | name = name.split(":").pop();
|
1598 | }
|
1599 | const sourceSpan = node.startSourceSpan;
|
1600 | const start = this.getStartLocation(name, sourceSpan);
|
1601 | if (start === null) {
|
1602 | return null;
|
1603 | }
|
1604 | const absoluteSpan = new AbsoluteSourceSpan(start, start + name.length);
|
1605 | const attributes = node.attributes.map(({ name: name2, sourceSpan: sourceSpan2 }) => {
|
1606 | return {
|
1607 | name: name2,
|
1608 | span: new AbsoluteSourceSpan(sourceSpan2.start.offset, sourceSpan2.end.offset),
|
1609 | kind: IdentifierKind.Attribute
|
1610 | };
|
1611 | });
|
1612 | const usedDirectives = this.boundTemplate.getDirectivesOfNode(node) || [];
|
1613 | const identifier = {
|
1614 | name,
|
1615 | span: absoluteSpan,
|
1616 | kind,
|
1617 | attributes: new Set(attributes),
|
1618 | usedDirectives: new Set(usedDirectives.map((dir) => {
|
1619 | return {
|
1620 | node: dir.ref.node,
|
1621 | selector: dir.selector
|
1622 | };
|
1623 | }))
|
1624 | };
|
1625 | this.elementAndTemplateIdentifierCache.set(node, identifier);
|
1626 | return identifier;
|
1627 | }
|
1628 | targetToIdentifier(node) {
|
1629 | if (this.targetIdentifierCache.has(node)) {
|
1630 | return this.targetIdentifierCache.get(node);
|
1631 | }
|
1632 | const { name, sourceSpan } = node;
|
1633 | const start = this.getStartLocation(name, sourceSpan);
|
1634 | if (start === null) {
|
1635 | return null;
|
1636 | }
|
1637 | const span = new AbsoluteSourceSpan(start, start + name.length);
|
1638 | let identifier;
|
1639 | if (node instanceof TmplAstReference) {
|
1640 | const refTarget = this.boundTemplate.getReferenceTarget(node);
|
1641 | let target = null;
|
1642 | if (refTarget) {
|
1643 | let node2 = null;
|
1644 | let directive = null;
|
1645 | if (refTarget instanceof TmplAstElement || refTarget instanceof TmplAstTemplate) {
|
1646 | node2 = this.elementOrTemplateToIdentifier(refTarget);
|
1647 | } else {
|
1648 | node2 = this.elementOrTemplateToIdentifier(refTarget.node);
|
1649 | directive = refTarget.directive.ref.node;
|
1650 | }
|
1651 | if (node2 === null) {
|
1652 | return null;
|
1653 | }
|
1654 | target = {
|
1655 | node: node2,
|
1656 | directive
|
1657 | };
|
1658 | }
|
1659 | identifier = {
|
1660 | name,
|
1661 | span,
|
1662 | kind: IdentifierKind.Reference,
|
1663 | target
|
1664 | };
|
1665 | } else {
|
1666 | identifier = {
|
1667 | name,
|
1668 | span,
|
1669 | kind: IdentifierKind.Variable
|
1670 | };
|
1671 | }
|
1672 | this.targetIdentifierCache.set(node, identifier);
|
1673 | return identifier;
|
1674 | }
|
1675 | getStartLocation(name, context) {
|
1676 | const localStr = context.toString();
|
1677 | if (!localStr.includes(name)) {
|
1678 | this.errors.push(new Error(`Impossible state: "${name}" not found in "${localStr}"`));
|
1679 | return null;
|
1680 | }
|
1681 | return context.start.offset + localStr.indexOf(name);
|
1682 | }
|
1683 | visitExpression(ast) {
|
1684 | if (ast instanceof ASTWithSource && ast.source !== null) {
|
1685 | const targetToIdentifier = this.targetToIdentifier.bind(this);
|
1686 | const absoluteOffset = ast.sourceSpan.start;
|
1687 | const { identifiers, errors } = ExpressionVisitor.getIdentifiers(ast, ast.source, absoluteOffset, this.boundTemplate, targetToIdentifier);
|
1688 | identifiers.forEach((id) => this.identifiers.add(id));
|
1689 | this.errors.push(...errors);
|
1690 | }
|
1691 | }
|
1692 | };
|
1693 | function getTemplateIdentifiers(boundTemplate) {
|
1694 | const visitor = new TemplateVisitor(boundTemplate);
|
1695 | if (boundTemplate.target.template !== void 0) {
|
1696 | visitor.visitAll(boundTemplate.target.template);
|
1697 | }
|
1698 | return { identifiers: visitor.identifiers, errors: visitor.errors };
|
1699 | }
|
1700 |
|
1701 |
|
1702 | function generateAnalysis(context) {
|
1703 | const analysis = new Map();
|
1704 | context.components.forEach(({ declaration, selector, boundTemplate, templateMeta }) => {
|
1705 | const name = declaration.name.getText();
|
1706 | const usedComponents = new Set();
|
1707 | const usedDirs = boundTemplate.getUsedDirectives();
|
1708 | usedDirs.forEach((dir) => {
|
1709 | if (dir.isComponent) {
|
1710 | usedComponents.add(dir.ref.node);
|
1711 | }
|
1712 | });
|
1713 | const componentFile = new ParseSourceFile(declaration.getSourceFile().getFullText(), declaration.getSourceFile().fileName);
|
1714 | let templateFile;
|
1715 | if (templateMeta.isInline) {
|
1716 | templateFile = componentFile;
|
1717 | } else {
|
1718 | templateFile = templateMeta.file;
|
1719 | }
|
1720 | const { identifiers, errors } = getTemplateIdentifiers(boundTemplate);
|
1721 | analysis.set(declaration, {
|
1722 | name,
|
1723 | selector,
|
1724 | file: componentFile,
|
1725 | template: {
|
1726 | identifiers,
|
1727 | usedComponents,
|
1728 | isInline: templateMeta.isInline,
|
1729 | file: templateFile
|
1730 | },
|
1731 | errors
|
1732 | });
|
1733 | });
|
1734 | return analysis;
|
1735 | }
|
1736 |
|
1737 |
|
1738 | import ts10 from "typescript";
|
1739 | var CSS_PREPROCESSOR_EXT = /(\.scss|\.sass|\.less|\.styl)$/;
|
1740 | var RESOURCE_MARKER = ".$ngresource$";
|
1741 | var RESOURCE_MARKER_TS = RESOURCE_MARKER + ".ts";
|
1742 | var AdapterResourceLoader = class {
|
1743 | constructor(adapter, options) {
|
1744 | this.adapter = adapter;
|
1745 | this.options = options;
|
1746 | this.cache = new Map();
|
1747 | this.fetching = new Map();
|
1748 | this.lookupResolutionHost = createLookupResolutionHost(this.adapter);
|
1749 | this.canPreload = !!this.adapter.readResource;
|
1750 | this.canPreprocess = !!this.adapter.transformResource;
|
1751 | }
|
1752 | resolve(url, fromFile) {
|
1753 | let resolvedUrl = null;
|
1754 | if (this.adapter.resourceNameToFileName) {
|
1755 | resolvedUrl = this.adapter.resourceNameToFileName(url, fromFile, (url2, fromFile2) => this.fallbackResolve(url2, fromFile2));
|
1756 | } else {
|
1757 | resolvedUrl = this.fallbackResolve(url, fromFile);
|
1758 | }
|
1759 | if (resolvedUrl === null) {
|
1760 | throw new Error(`HostResourceResolver: could not resolve ${url} in context of ${fromFile})`);
|
1761 | }
|
1762 | return resolvedUrl;
|
1763 | }
|
1764 | preload(resolvedUrl, context) {
|
1765 | if (!this.adapter.readResource) {
|
1766 | throw new Error("HostResourceLoader: the CompilerHost provided does not support pre-loading resources.");
|
1767 | }
|
1768 | if (this.cache.has(resolvedUrl)) {
|
1769 | return void 0;
|
1770 | } else if (this.fetching.has(resolvedUrl)) {
|
1771 | return this.fetching.get(resolvedUrl);
|
1772 | }
|
1773 | let result = this.adapter.readResource(resolvedUrl);
|
1774 | if (this.adapter.transformResource && context.type === "style") {
|
1775 | const resourceContext = {
|
1776 | type: "style",
|
1777 | containingFile: context.containingFile,
|
1778 | resourceFile: resolvedUrl
|
1779 | };
|
1780 | result = Promise.resolve(result).then(async (str) => {
|
1781 | const transformResult = await this.adapter.transformResource(str, resourceContext);
|
1782 | return transformResult === null ? str : transformResult.content;
|
1783 | });
|
1784 | }
|
1785 | if (typeof result === "string") {
|
1786 | this.cache.set(resolvedUrl, result);
|
1787 | return void 0;
|
1788 | } else {
|
1789 | const fetchCompletion = result.then((str) => {
|
1790 | this.fetching.delete(resolvedUrl);
|
1791 | this.cache.set(resolvedUrl, str);
|
1792 | });
|
1793 | this.fetching.set(resolvedUrl, fetchCompletion);
|
1794 | return fetchCompletion;
|
1795 | }
|
1796 | }
|
1797 | async preprocessInline(data, context) {
|
1798 | if (!this.adapter.transformResource || context.type !== "style") {
|
1799 | return data;
|
1800 | }
|
1801 | const transformResult = await this.adapter.transformResource(data, { type: "style", containingFile: context.containingFile, resourceFile: null });
|
1802 | if (transformResult === null) {
|
1803 | return data;
|
1804 | }
|
1805 | return transformResult.content;
|
1806 | }
|
1807 | load(resolvedUrl) {
|
1808 | if (this.cache.has(resolvedUrl)) {
|
1809 | return this.cache.get(resolvedUrl);
|
1810 | }
|
1811 | const result = this.adapter.readResource ? this.adapter.readResource(resolvedUrl) : this.adapter.readFile(resolvedUrl);
|
1812 | if (typeof result !== "string") {
|
1813 | throw new Error(`HostResourceLoader: loader(${resolvedUrl}) returned a Promise`);
|
1814 | }
|
1815 | this.cache.set(resolvedUrl, result);
|
1816 | return result;
|
1817 | }
|
1818 | invalidate() {
|
1819 | this.cache.clear();
|
1820 | }
|
1821 | fallbackResolve(url, fromFile) {
|
1822 | let candidateLocations;
|
1823 | if (url.startsWith("/")) {
|
1824 | candidateLocations = this.getRootedCandidateLocations(url);
|
1825 | } else {
|
1826 | if (!url.startsWith(".")) {
|
1827 | url = `./${url}`;
|
1828 | }
|
1829 | candidateLocations = this.getResolvedCandidateLocations(url, fromFile);
|
1830 | }
|
1831 | for (const candidate of candidateLocations) {
|
1832 | if (this.adapter.fileExists(candidate)) {
|
1833 | return candidate;
|
1834 | } else if (CSS_PREPROCESSOR_EXT.test(candidate)) {
|
1835 | const cssFallbackUrl = candidate.replace(CSS_PREPROCESSOR_EXT, ".css");
|
1836 | if (this.adapter.fileExists(cssFallbackUrl)) {
|
1837 | return cssFallbackUrl;
|
1838 | }
|
1839 | }
|
1840 | }
|
1841 | return null;
|
1842 | }
|
1843 | getRootedCandidateLocations(url) {
|
1844 | const segment = "." + url;
|
1845 | return this.adapter.rootDirs.map((rootDir) => join(rootDir, segment));
|
1846 | }
|
1847 | getResolvedCandidateLocations(url, fromFile) {
|
1848 | const failedLookup = ts10.resolveModuleName(url + RESOURCE_MARKER, fromFile, this.options, this.lookupResolutionHost);
|
1849 | if (failedLookup.failedLookupLocations === void 0) {
|
1850 | throw new Error(`Internal error: expected to find failedLookupLocations during resolution of resource '${url}' in context of ${fromFile}`);
|
1851 | }
|
1852 | return failedLookup.failedLookupLocations.filter((candidate) => candidate.endsWith(RESOURCE_MARKER_TS)).map((candidate) => candidate.slice(0, -RESOURCE_MARKER_TS.length));
|
1853 | }
|
1854 | };
|
1855 | function createLookupResolutionHost(adapter) {
|
1856 | var _a, _b, _c;
|
1857 | return {
|
1858 | directoryExists(directoryName) {
|
1859 | if (directoryName.includes(RESOURCE_MARKER)) {
|
1860 | return false;
|
1861 | } else if (adapter.directoryExists !== void 0) {
|
1862 | return adapter.directoryExists(directoryName);
|
1863 | } else {
|
1864 | return true;
|
1865 | }
|
1866 | },
|
1867 | fileExists(fileName) {
|
1868 | if (fileName.includes(RESOURCE_MARKER)) {
|
1869 | return false;
|
1870 | } else {
|
1871 | return adapter.fileExists(fileName);
|
1872 | }
|
1873 | },
|
1874 | readFile: adapter.readFile.bind(adapter),
|
1875 | getCurrentDirectory: adapter.getCurrentDirectory.bind(adapter),
|
1876 | getDirectories: (_a = adapter.getDirectories) == null ? void 0 : _a.bind(adapter),
|
1877 | realpath: (_b = adapter.realpath) == null ? void 0 : _b.bind(adapter),
|
1878 | trace: (_c = adapter.trace) == null ? void 0 : _c.bind(adapter),
|
1879 | useCaseSensitiveFileNames: typeof adapter.useCaseSensitiveFileNames === "function" ? adapter.useCaseSensitiveFileNames.bind(adapter) : adapter.useCaseSensitiveFileNames
|
1880 | };
|
1881 | }
|
1882 |
|
1883 |
|
1884 | var MetadataDtsModuleScopeResolver = class {
|
1885 | constructor(dtsMetaReader, aliasingHost) {
|
1886 | this.dtsMetaReader = dtsMetaReader;
|
1887 | this.aliasingHost = aliasingHost;
|
1888 | this.cache = new Map();
|
1889 | }
|
1890 | resolve(ref) {
|
1891 | const clazz = ref.node;
|
1892 | const sourceFile = clazz.getSourceFile();
|
1893 | if (!sourceFile.isDeclarationFile) {
|
1894 | throw new Error(`Debug error: DtsModuleScopeResolver.read(${ref.debugName} from ${sourceFile.fileName}), but not a .d.ts file`);
|
1895 | }
|
1896 | if (this.cache.has(clazz)) {
|
1897 | return this.cache.get(clazz);
|
1898 | }
|
1899 | const directives = [];
|
1900 | const pipes = [];
|
1901 | const ngModules = new Set([clazz]);
|
1902 | const meta = this.dtsMetaReader.getNgModuleMetadata(ref);
|
1903 | if (meta === null) {
|
1904 | this.cache.set(clazz, null);
|
1905 | return null;
|
1906 | }
|
1907 | const declarations = new Set();
|
1908 | for (const declRef of meta.declarations) {
|
1909 | declarations.add(declRef.node);
|
1910 | }
|
1911 | for (const exportRef of meta.exports) {
|
1912 | const directive = this.dtsMetaReader.getDirectiveMetadata(exportRef);
|
1913 | if (directive !== null) {
|
1914 | const isReExport = !declarations.has(exportRef.node);
|
1915 | directives.push(this.maybeAlias(directive, sourceFile, isReExport));
|
1916 | continue;
|
1917 | }
|
1918 | const pipe = this.dtsMetaReader.getPipeMetadata(exportRef);
|
1919 | if (pipe !== null) {
|
1920 | const isReExport = !declarations.has(exportRef.node);
|
1921 | pipes.push(this.maybeAlias(pipe, sourceFile, isReExport));
|
1922 | continue;
|
1923 | }
|
1924 | const exportScope2 = this.resolve(exportRef);
|
1925 | if (exportScope2 !== null) {
|
1926 | if (this.aliasingHost === null) {
|
1927 | directives.push(...exportScope2.exported.directives);
|
1928 | pipes.push(...exportScope2.exported.pipes);
|
1929 | } else {
|
1930 | for (const directive2 of exportScope2.exported.directives) {
|
1931 | directives.push(this.maybeAlias(directive2, sourceFile, true));
|
1932 | }
|
1933 | for (const pipe2 of exportScope2.exported.pipes) {
|
1934 | pipes.push(this.maybeAlias(pipe2, sourceFile, true));
|
1935 | }
|
1936 | for (const ngModule of exportScope2.exported.ngModules) {
|
1937 | ngModules.add(ngModule);
|
1938 | }
|
1939 | }
|
1940 | }
|
1941 | continue;
|
1942 | }
|
1943 | const exportScope = {
|
1944 | exported: {
|
1945 | directives,
|
1946 | pipes,
|
1947 | ngModules: Array.from(ngModules),
|
1948 | isPoisoned: false
|
1949 | }
|
1950 | };
|
1951 | this.cache.set(clazz, exportScope);
|
1952 | return exportScope;
|
1953 | }
|
1954 | maybeAlias(dirOrPipe, maybeAliasFrom, isReExport) {
|
1955 | const ref = dirOrPipe.ref;
|
1956 | if (this.aliasingHost === null || ref.node.getSourceFile() === maybeAliasFrom) {
|
1957 | return dirOrPipe;
|
1958 | }
|
1959 | const alias = this.aliasingHost.getAliasIn(ref.node, maybeAliasFrom, isReExport);
|
1960 | if (alias === null) {
|
1961 | return dirOrPipe;
|
1962 | }
|
1963 | return __spreadProps(__spreadValues({}, dirOrPipe), {
|
1964 | ref: ref.cloneWithAlias(alias)
|
1965 | });
|
1966 | }
|
1967 | };
|
1968 |
|
1969 |
|
1970 | import { ExternalExpr } from "@angular/compiler";
|
1971 | import ts11 from "typescript";
|
1972 | var LocalModuleScopeRegistry = class {
|
1973 | constructor(localReader, dependencyScopeReader, refEmitter, aliasingHost) {
|
1974 | this.localReader = localReader;
|
1975 | this.dependencyScopeReader = dependencyScopeReader;
|
1976 | this.refEmitter = refEmitter;
|
1977 | this.aliasingHost = aliasingHost;
|
1978 | this.sealed = false;
|
1979 | this.declarationToModule = new Map();
|
1980 | this.duplicateDeclarations = new Map();
|
1981 | this.moduleToRef = new Map();
|
1982 | this.cache = new Map();
|
1983 | this.remoteScoping = new Map();
|
1984 | this.scopeErrors = new Map();
|
1985 | this.modulesWithStructuralErrors = new Set();
|
1986 | }
|
1987 | registerNgModuleMetadata(data) {
|
1988 | this.assertCollecting();
|
1989 | const ngModule = data.ref.node;
|
1990 | this.moduleToRef.set(data.ref.node, data.ref);
|
1991 | for (const decl of data.declarations) {
|
1992 | this.registerDeclarationOfModule(ngModule, decl, data.rawDeclarations);
|
1993 | }
|
1994 | }
|
1995 | registerDirectiveMetadata(directive) {
|
1996 | }
|
1997 | registerPipeMetadata(pipe) {
|
1998 | }
|
1999 | getScopeForComponent(clazz) {
|
2000 | const scope = !this.declarationToModule.has(clazz) ? null : this.getScopeOfModule(this.declarationToModule.get(clazz).ngModule);
|
2001 | return scope;
|
2002 | }
|
2003 | getDuplicateDeclarations(node) {
|
2004 | if (!this.duplicateDeclarations.has(node)) {
|
2005 | return null;
|
2006 | }
|
2007 | return Array.from(this.duplicateDeclarations.get(node).values());
|
2008 | }
|
2009 | getScopeOfModule(clazz) {
|
2010 | return this.moduleToRef.has(clazz) ? this.getScopeOfModuleReference(this.moduleToRef.get(clazz)) : null;
|
2011 | }
|
2012 | getDiagnosticsOfModule(clazz) {
|
2013 | this.getScopeOfModule(clazz);
|
2014 | if (this.scopeErrors.has(clazz)) {
|
2015 | return this.scopeErrors.get(clazz);
|
2016 | } else {
|
2017 | return null;
|
2018 | }
|
2019 | }
|
2020 | registerDeclarationOfModule(ngModule, decl, rawDeclarations) {
|
2021 | const declData = {
|
2022 | ngModule,
|
2023 | ref: decl,
|
2024 | rawDeclarations
|
2025 | };
|
2026 | if (this.duplicateDeclarations.has(decl.node)) {
|
2027 | this.duplicateDeclarations.get(decl.node).set(ngModule, declData);
|
2028 | } else if (this.declarationToModule.has(decl.node) && this.declarationToModule.get(decl.node).ngModule !== ngModule) {
|
2029 | const duplicateDeclMap = new Map();
|
2030 | const firstDeclData = this.declarationToModule.get(decl.node);
|
2031 | this.modulesWithStructuralErrors.add(firstDeclData.ngModule);
|
2032 | this.modulesWithStructuralErrors.add(ngModule);
|
2033 | duplicateDeclMap.set(firstDeclData.ngModule, firstDeclData);
|
2034 | duplicateDeclMap.set(ngModule, declData);
|
2035 | this.duplicateDeclarations.set(decl.node, duplicateDeclMap);
|
2036 | this.declarationToModule.delete(decl.node);
|
2037 | } else {
|
2038 | this.declarationToModule.set(decl.node, declData);
|
2039 | }
|
2040 | }
|
2041 | getScopeOfModuleReference(ref) {
|
2042 | if (this.cache.has(ref.node)) {
|
2043 | return this.cache.get(ref.node);
|
2044 | }
|
2045 | this.sealed = true;
|
2046 | const ngModule = this.localReader.getNgModuleMetadata(ref);
|
2047 | if (ngModule === null) {
|
2048 | this.cache.set(ref.node, null);
|
2049 | return null;
|
2050 | }
|
2051 | const compilationModules = new Set([ngModule.ref.node]);
|
2052 | const exportedModules = new Set([ngModule.ref.node]);
|
2053 | const diagnostics = [];
|
2054 | const compilationDirectives = new Map();
|
2055 | const compilationPipes = new Map();
|
2056 | const declared = new Set();
|
2057 | const exportDirectives = new Map();
|
2058 | const exportPipes = new Map();
|
2059 | let isPoisoned = false;
|
2060 | if (this.modulesWithStructuralErrors.has(ngModule.ref.node)) {
|
2061 | isPoisoned = true;
|
2062 | }
|
2063 | for (const decl of ngModule.imports) {
|
2064 | const importScope = this.getExportedScope(decl, diagnostics, ref.node, "import");
|
2065 | if (importScope === null) {
|
2066 | diagnostics.push(invalidRef(ref.node, decl, "import"));
|
2067 | isPoisoned = true;
|
2068 | continue;
|
2069 | } else if (importScope === "invalid" || importScope.exported.isPoisoned) {
|
2070 | diagnostics.push(invalidTransitiveNgModuleRef(ref.node, decl, "import"));
|
2071 | isPoisoned = true;
|
2072 | if (importScope === "invalid") {
|
2073 | continue;
|
2074 | }
|
2075 | }
|
2076 | for (const directive of importScope.exported.directives) {
|
2077 | compilationDirectives.set(directive.ref.node, directive);
|
2078 | }
|
2079 | for (const pipe of importScope.exported.pipes) {
|
2080 | compilationPipes.set(pipe.ref.node, pipe);
|
2081 | }
|
2082 | for (const importedModule of importScope.exported.ngModules) {
|
2083 | compilationModules.add(importedModule);
|
2084 | }
|
2085 | }
|
2086 | for (const decl of ngModule.declarations) {
|
2087 | const directive = this.localReader.getDirectiveMetadata(decl);
|
2088 | const pipe = this.localReader.getPipeMetadata(decl);
|
2089 | if (directive !== null) {
|
2090 | compilationDirectives.set(decl.node, __spreadProps(__spreadValues({}, directive), { ref: decl }));
|
2091 | if (directive.isPoisoned) {
|
2092 | isPoisoned = true;
|
2093 | }
|
2094 | } else if (pipe !== null) {
|
2095 | compilationPipes.set(decl.node, __spreadProps(__spreadValues({}, pipe), { ref: decl }));
|
2096 | } else {
|
2097 | const errorNode = decl.getOriginForDiagnostics(ngModule.rawDeclarations);
|
2098 | diagnostics.push(makeDiagnostic(ErrorCode.NGMODULE_INVALID_DECLARATION, errorNode, `The class '${decl.node.name.text}' is listed in the declarations of the NgModule '${ngModule.ref.node.name.text}', but is not a directive, a component, or a pipe. Either remove it from the NgModule's declarations, or add an appropriate Angular decorator.`, [makeRelatedInformation(decl.node.name, `'${decl.node.name.text}' is declared here.`)]));
|
2099 | isPoisoned = true;
|
2100 | continue;
|
2101 | }
|
2102 | declared.add(decl.node);
|
2103 | }
|
2104 | for (const decl of ngModule.exports) {
|
2105 | const exportScope = this.getExportedScope(decl, diagnostics, ref.node, "export");
|
2106 | if (exportScope === "invalid" || exportScope !== null && exportScope.exported.isPoisoned) {
|
2107 | diagnostics.push(invalidTransitiveNgModuleRef(ref.node, decl, "export"));
|
2108 | isPoisoned = true;
|
2109 | if (exportScope === "invalid") {
|
2110 | continue;
|
2111 | }
|
2112 | } else if (exportScope !== null) {
|
2113 | for (const directive of exportScope.exported.directives) {
|
2114 | exportDirectives.set(directive.ref.node, directive);
|
2115 | }
|
2116 | for (const pipe of exportScope.exported.pipes) {
|
2117 | exportPipes.set(pipe.ref.node, pipe);
|
2118 | }
|
2119 | for (const exportedModule of exportScope.exported.ngModules) {
|
2120 | exportedModules.add(exportedModule);
|
2121 | }
|
2122 | } else if (compilationDirectives.has(decl.node)) {
|
2123 | const directive = compilationDirectives.get(decl.node);
|
2124 | exportDirectives.set(decl.node, directive);
|
2125 | } else if (compilationPipes.has(decl.node)) {
|
2126 | const pipe = compilationPipes.get(decl.node);
|
2127 | exportPipes.set(decl.node, pipe);
|
2128 | } else {
|
2129 | if (this.localReader.getDirectiveMetadata(decl) !== null || this.localReader.getPipeMetadata(decl) !== null) {
|
2130 | diagnostics.push(invalidReexport(ref.node, decl));
|
2131 | } else {
|
2132 | diagnostics.push(invalidRef(ref.node, decl, "export"));
|
2133 | }
|
2134 | isPoisoned = true;
|
2135 | continue;
|
2136 | }
|
2137 | }
|
2138 | const exported = {
|
2139 | directives: Array.from(exportDirectives.values()),
|
2140 | pipes: Array.from(exportPipes.values()),
|
2141 | ngModules: Array.from(exportedModules),
|
2142 | isPoisoned
|
2143 | };
|
2144 | const reexports = this.getReexports(ngModule, ref, declared, exported, diagnostics);
|
2145 | const scope = {
|
2146 | ngModule: ngModule.ref.node,
|
2147 | compilation: {
|
2148 | directives: Array.from(compilationDirectives.values()),
|
2149 | pipes: Array.from(compilationPipes.values()),
|
2150 | ngModules: Array.from(compilationModules),
|
2151 | isPoisoned
|
2152 | },
|
2153 | exported,
|
2154 | reexports,
|
2155 | schemas: ngModule.schemas
|
2156 | };
|
2157 | if (diagnostics.length > 0) {
|
2158 | this.scopeErrors.set(ref.node, diagnostics);
|
2159 | this.modulesWithStructuralErrors.add(ref.node);
|
2160 | }
|
2161 | this.cache.set(ref.node, scope);
|
2162 | return scope;
|
2163 | }
|
2164 | getRemoteScope(node) {
|
2165 | return this.remoteScoping.has(node) ? this.remoteScoping.get(node) : null;
|
2166 | }
|
2167 | setComponentRemoteScope(node, directives, pipes) {
|
2168 | this.remoteScoping.set(node, { directives, pipes });
|
2169 | }
|
2170 | getExportedScope(ref, diagnostics, ownerForErrors, type) {
|
2171 | if (ref.node.getSourceFile().isDeclarationFile) {
|
2172 | if (!ts11.isClassDeclaration(ref.node)) {
|
2173 | const code = type === "import" ? ErrorCode.NGMODULE_INVALID_IMPORT : ErrorCode.NGMODULE_INVALID_EXPORT;
|
2174 | diagnostics.push(makeDiagnostic(code, identifierOfNode(ref.node) || ref.node, `Appears in the NgModule.${type}s of ${nodeNameForError(ownerForErrors)}, but could not be resolved to an NgModule`));
|
2175 | return "invalid";
|
2176 | }
|
2177 | return this.dependencyScopeReader.resolve(ref);
|
2178 | } else {
|
2179 | return this.getScopeOfModuleReference(ref);
|
2180 | }
|
2181 | }
|
2182 | getReexports(ngModule, ref, declared, exported, diagnostics) {
|
2183 | let reexports = null;
|
2184 | const sourceFile = ref.node.getSourceFile();
|
2185 | if (this.aliasingHost === null) {
|
2186 | return null;
|
2187 | }
|
2188 | reexports = [];
|
2189 | const reexportMap = new Map();
|
2190 | const ngModuleRef = ref;
|
2191 | const addReexport = (exportRef) => {
|
2192 | if (exportRef.node.getSourceFile() === sourceFile) {
|
2193 | return;
|
2194 | }
|
2195 | const isReExport = !declared.has(exportRef.node);
|
2196 | const exportName = this.aliasingHost.maybeAliasSymbolAs(exportRef, sourceFile, ngModule.ref.node.name.text, isReExport);
|
2197 | if (exportName === null) {
|
2198 | return;
|
2199 | }
|
2200 | if (!reexportMap.has(exportName)) {
|
2201 | if (exportRef.alias && exportRef.alias instanceof ExternalExpr) {
|
2202 | reexports.push({
|
2203 | fromModule: exportRef.alias.value.moduleName,
|
2204 | symbolName: exportRef.alias.value.name,
|
2205 | asAlias: exportName
|
2206 | });
|
2207 | } else {
|
2208 | const emittedRef = this.refEmitter.emit(exportRef.cloneWithNoIdentifiers(), sourceFile);
|
2209 | assertSuccessfulReferenceEmit(emittedRef, ngModuleRef.node.name, "class");
|
2210 | const expr = emittedRef.expression;
|
2211 | if (!(expr instanceof ExternalExpr) || expr.value.moduleName === null || expr.value.name === null) {
|
2212 | throw new Error("Expected ExternalExpr");
|
2213 | }
|
2214 | reexports.push({
|
2215 | fromModule: expr.value.moduleName,
|
2216 | symbolName: expr.value.name,
|
2217 | asAlias: exportName
|
2218 | });
|
2219 | }
|
2220 | reexportMap.set(exportName, exportRef);
|
2221 | } else {
|
2222 | const prevRef = reexportMap.get(exportName);
|
2223 | diagnostics.push(reexportCollision(ngModuleRef.node, prevRef, exportRef));
|
2224 | }
|
2225 | };
|
2226 | for (const { ref: ref2 } of exported.directives) {
|
2227 | addReexport(ref2);
|
2228 | }
|
2229 | for (const { ref: ref2 } of exported.pipes) {
|
2230 | addReexport(ref2);
|
2231 | }
|
2232 | return reexports;
|
2233 | }
|
2234 | assertCollecting() {
|
2235 | if (this.sealed) {
|
2236 | throw new Error(`Assertion: LocalModuleScopeRegistry is not COLLECTING`);
|
2237 | }
|
2238 | }
|
2239 | };
|
2240 | function invalidRef(clazz, decl, type) {
|
2241 | const code = type === "import" ? ErrorCode.NGMODULE_INVALID_IMPORT : ErrorCode.NGMODULE_INVALID_EXPORT;
|
2242 | const resolveTarget = type === "import" ? "NgModule" : "NgModule, Component, Directive, or Pipe";
|
2243 | let message = `Appears in the NgModule.${type}s of ${nodeNameForError(clazz)}, but could not be resolved to an ${resolveTarget} class.
|
2244 |
|
2245 | `;
|
2246 | const library = decl.ownedByModuleGuess !== null ? ` (${decl.ownedByModuleGuess})` : "";
|
2247 | const sf = decl.node.getSourceFile();
|
2248 | if (!sf.isDeclarationFile) {
|
2249 | const annotationType = type === "import" ? "@NgModule" : "Angular";
|
2250 | message += `Is it missing an ${annotationType} annotation?`;
|
2251 | } else if (sf.fileName.indexOf("node_modules") !== -1) {
|
2252 | message += `This likely means that the library${library} which declares ${decl.debugName} has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.`;
|
2253 | } else {
|
2254 | message += `This likely means that the dependency${library} which declares ${decl.debugName} has not been processed correctly by ngcc.`;
|
2255 | }
|
2256 | return makeDiagnostic(code, identifierOfNode(decl.node) || decl.node, message);
|
2257 | }
|
2258 | function invalidTransitiveNgModuleRef(clazz, decl, type) {
|
2259 | const code = type === "import" ? ErrorCode.NGMODULE_INVALID_IMPORT : ErrorCode.NGMODULE_INVALID_EXPORT;
|
2260 | return makeDiagnostic(code, identifierOfNode(decl.node) || decl.node, `Appears in the NgModule.${type}s of ${nodeNameForError(clazz)}, but itself has errors`);
|
2261 | }
|
2262 | function invalidReexport(clazz, decl) {
|
2263 | return makeDiagnostic(ErrorCode.NGMODULE_INVALID_REEXPORT, identifierOfNode(decl.node) || decl.node, `Present in the NgModule.exports of ${nodeNameForError(clazz)} but neither declared nor imported`);
|
2264 | }
|
2265 | function reexportCollision(module, refA, refB) {
|
2266 | const childMessageText = `This directive/pipe is part of the exports of '${module.name.text}' and shares the same name as another exported directive/pipe.`;
|
2267 | return makeDiagnostic(ErrorCode.NGMODULE_REEXPORT_NAME_COLLISION, module.name, `
|
2268 | There was a name collision between two classes named '${refA.node.name.text}', which are both part of the exports of '${module.name.text}'.
|
2269 |
|
2270 | Angular generates re-exports of an NgModule's exported directives/pipes from the module's source file in certain cases, using the declared name of the class. If two classes of the same name are exported, this automatic naming does not work.
|
2271 |
|
2272 | To fix this problem please re-export one or both classes directly from this file.
|
2273 | `.trim(), [
|
2274 | makeRelatedInformation(refA.node.name, childMessageText),
|
2275 | makeRelatedInformation(refB.node.name, childMessageText)
|
2276 | ]);
|
2277 | }
|
2278 |
|
2279 |
|
2280 | import { CssSelector, SelectorMatcher } from "@angular/compiler";
|
2281 | import ts12 from "typescript";
|
2282 | var TypeCheckScopeRegistry = class {
|
2283 | constructor(scopeReader, metaReader) {
|
2284 | this.scopeReader = scopeReader;
|
2285 | this.metaReader = metaReader;
|
2286 | this.flattenedDirectiveMetaCache = new Map();
|
2287 | this.scopeCache = new Map();
|
2288 | }
|
2289 | getTypeCheckScope(node) {
|
2290 | const matcher = new SelectorMatcher();
|
2291 | const directives = [];
|
2292 | const pipes = new Map();
|
2293 | const scope = this.scopeReader.getScopeForComponent(node);
|
2294 | if (scope === null) {
|
2295 | return {
|
2296 | matcher,
|
2297 | directives,
|
2298 | pipes,
|
2299 | schemas: [],
|
2300 | isPoisoned: false
|
2301 | };
|
2302 | }
|
2303 | if (this.scopeCache.has(scope.ngModule)) {
|
2304 | return this.scopeCache.get(scope.ngModule);
|
2305 | }
|
2306 | for (const meta of scope.compilation.directives) {
|
2307 | if (meta.selector !== null) {
|
2308 | const extMeta = this.getTypeCheckDirectiveMetadata(meta.ref);
|
2309 | matcher.addSelectables(CssSelector.parse(meta.selector), extMeta);
|
2310 | directives.push(extMeta);
|
2311 | }
|
2312 | }
|
2313 | for (const { name, ref } of scope.compilation.pipes) {
|
2314 | if (!ts12.isClassDeclaration(ref.node)) {
|
2315 | throw new Error(`Unexpected non-class declaration ${ts12.SyntaxKind[ref.node.kind]} for pipe ${ref.debugName}`);
|
2316 | }
|
2317 | pipes.set(name, ref);
|
2318 | }
|
2319 | const typeCheckScope = {
|
2320 | matcher,
|
2321 | directives,
|
2322 | pipes,
|
2323 | schemas: scope.schemas,
|
2324 | isPoisoned: scope.compilation.isPoisoned || scope.exported.isPoisoned
|
2325 | };
|
2326 | this.scopeCache.set(scope.ngModule, typeCheckScope);
|
2327 | return typeCheckScope;
|
2328 | }
|
2329 | getTypeCheckDirectiveMetadata(ref) {
|
2330 | const clazz = ref.node;
|
2331 | if (this.flattenedDirectiveMetaCache.has(clazz)) {
|
2332 | return this.flattenedDirectiveMetaCache.get(clazz);
|
2333 | }
|
2334 | const meta = flattenInheritedDirectiveMetadata(this.metaReader, ref);
|
2335 | this.flattenedDirectiveMetaCache.set(clazz, meta);
|
2336 | return meta;
|
2337 | }
|
2338 | };
|
2339 |
|
2340 |
|
2341 | import { CssSelector as CssSelector2, DomElementSchemaRegistry as DomElementSchemaRegistry2 } from "@angular/compiler";
|
2342 |
|
2343 |
|
2344 | import ts13 from "typescript";
|
2345 | function makeTemplateDiagnostic(templateId, mapping, span, category, code, messageText, relatedMessages) {
|
2346 | if (mapping.type === "direct") {
|
2347 | let relatedInformation = void 0;
|
2348 | if (relatedMessages !== void 0) {
|
2349 | relatedInformation = [];
|
2350 | for (const relatedMessage of relatedMessages) {
|
2351 | relatedInformation.push({
|
2352 | category: ts13.DiagnosticCategory.Message,
|
2353 | code: 0,
|
2354 | file: relatedMessage.sourceFile,
|
2355 | start: relatedMessage.start,
|
2356 | length: relatedMessage.end - relatedMessage.start,
|
2357 | messageText: relatedMessage.text
|
2358 | });
|
2359 | }
|
2360 | }
|
2361 | return {
|
2362 | source: "ngtsc",
|
2363 | code,
|
2364 | category,
|
2365 | messageText,
|
2366 | file: mapping.node.getSourceFile(),
|
2367 | componentFile: mapping.node.getSourceFile(),
|
2368 | templateId,
|
2369 | start: span.start.offset,
|
2370 | length: span.end.offset - span.start.offset,
|
2371 | relatedInformation
|
2372 | };
|
2373 | } else if (mapping.type === "indirect" || mapping.type === "external") {
|
2374 | const componentSf = mapping.componentClass.getSourceFile();
|
2375 | const componentName = mapping.componentClass.name.text;
|
2376 | const fileName = mapping.type === "indirect" ? `${componentSf.fileName} (${componentName} template)` : mapping.templateUrl;
|
2377 | const sf = ts13.createSourceFile(fileName, mapping.template, ts13.ScriptTarget.Latest, false, ts13.ScriptKind.JSX);
|
2378 | let relatedInformation = [];
|
2379 | if (relatedMessages !== void 0) {
|
2380 | for (const relatedMessage of relatedMessages) {
|
2381 | relatedInformation.push({
|
2382 | category: ts13.DiagnosticCategory.Message,
|
2383 | code: 0,
|
2384 | file: relatedMessage.sourceFile,
|
2385 | start: relatedMessage.start,
|
2386 | length: relatedMessage.end - relatedMessage.start,
|
2387 | messageText: relatedMessage.text
|
2388 | });
|
2389 | }
|
2390 | }
|
2391 | relatedInformation.push({
|
2392 | category: ts13.DiagnosticCategory.Message,
|
2393 | code: 0,
|
2394 | file: componentSf,
|
2395 | start: mapping.node.getStart(),
|
2396 | length: mapping.node.getEnd() - mapping.node.getStart(),
|
2397 | messageText: `Error occurs in the template of component ${componentName}.`
|
2398 | });
|
2399 | return {
|
2400 | source: "ngtsc",
|
2401 | category,
|
2402 | code,
|
2403 | messageText,
|
2404 | file: sf,
|
2405 | componentFile: componentSf,
|
2406 | templateId,
|
2407 | start: span.start.offset,
|
2408 | length: span.end.offset - span.start.offset,
|
2409 | relatedInformation
|
2410 | };
|
2411 | } else {
|
2412 | throw new Error(`Unexpected source mapping type: ${mapping.type}`);
|
2413 | }
|
2414 | }
|
2415 |
|
2416 |
|
2417 | var TEMPLATE_ID = Symbol("ngTemplateId");
|
2418 | var NEXT_TEMPLATE_ID = Symbol("ngNextTemplateId");
|
2419 | function getTemplateId(clazz) {
|
2420 | const node = clazz;
|
2421 | if (node[TEMPLATE_ID] === void 0) {
|
2422 | node[TEMPLATE_ID] = allocateTemplateId(node.getSourceFile());
|
2423 | }
|
2424 | return node[TEMPLATE_ID];
|
2425 | }
|
2426 | function allocateTemplateId(sf) {
|
2427 | if (sf[NEXT_TEMPLATE_ID] === void 0) {
|
2428 | sf[NEXT_TEMPLATE_ID] = 1;
|
2429 | }
|
2430 | return `tcb${sf[NEXT_TEMPLATE_ID]++}`;
|
2431 | }
|
2432 |
|
2433 |
|
2434 | import { EmptyExpr, ImplicitReceiver as ImplicitReceiver2, PropertyRead as PropertyRead2, PropertyWrite as PropertyWrite2, SafePropertyRead, TmplAstReference as TmplAstReference2, TmplAstTextAttribute } from "@angular/compiler";
|
2435 | import ts15 from "typescript";
|
2436 |
|
2437 |
|
2438 | import { AbsoluteSourceSpan as AbsoluteSourceSpan2 } from "@angular/compiler";
|
2439 | import ts14 from "typescript";
|
2440 | var parseSpanComment = /^(\d+),(\d+)$/;
|
2441 | function readSpanComment(node, sourceFile = node.getSourceFile()) {
|
2442 | return ts14.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
2443 | if (kind !== ts14.SyntaxKind.MultiLineCommentTrivia) {
|
2444 | return null;
|
2445 | }
|
2446 | const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
2447 | const match = commentText.match(parseSpanComment);
|
2448 | if (match === null) {
|
2449 | return null;
|
2450 | }
|
2451 | return new AbsoluteSourceSpan2(+match[1], +match[2]);
|
2452 | }) || null;
|
2453 | }
|
2454 | var CommentTriviaType;
|
2455 | (function(CommentTriviaType2) {
|
2456 | CommentTriviaType2["DIAGNOSTIC"] = "D";
|
2457 | CommentTriviaType2["EXPRESSION_TYPE_IDENTIFIER"] = "T";
|
2458 | })(CommentTriviaType || (CommentTriviaType = {}));
|
2459 | var ExpressionIdentifier;
|
2460 | (function(ExpressionIdentifier2) {
|
2461 | ExpressionIdentifier2["DIRECTIVE"] = "DIR";
|
2462 | ExpressionIdentifier2["COMPONENT_COMPLETION"] = "COMPCOMP";
|
2463 | ExpressionIdentifier2["EVENT_PARAMETER"] = "EP";
|
2464 | })(ExpressionIdentifier || (ExpressionIdentifier = {}));
|
2465 | function addExpressionIdentifier(node, identifier) {
|
2466 | ts14.addSyntheticTrailingComment(node, ts14.SyntaxKind.MultiLineCommentTrivia, `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`, false);
|
2467 | }
|
2468 | var IGNORE_FOR_DIAGNOSTICS_MARKER = `${CommentTriviaType.DIAGNOSTIC}:ignore`;
|
2469 | function markIgnoreDiagnostics(node) {
|
2470 | ts14.addSyntheticTrailingComment(node, ts14.SyntaxKind.MultiLineCommentTrivia, IGNORE_FOR_DIAGNOSTICS_MARKER, false);
|
2471 | }
|
2472 | function hasIgnoreForDiagnosticsMarker(node, sourceFile) {
|
2473 | return ts14.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
2474 | if (kind !== ts14.SyntaxKind.MultiLineCommentTrivia) {
|
2475 | return null;
|
2476 | }
|
2477 | const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
2478 | return commentText === IGNORE_FOR_DIAGNOSTICS_MARKER;
|
2479 | }) === true;
|
2480 | }
|
2481 | function makeRecursiveVisitor(visitor) {
|
2482 | function recursiveVisitor(node) {
|
2483 | const res = visitor(node);
|
2484 | return res !== null ? res : node.forEachChild(recursiveVisitor);
|
2485 | }
|
2486 | return recursiveVisitor;
|
2487 | }
|
2488 | function getSpanFromOptions(opts) {
|
2489 | let withSpan = null;
|
2490 | if (opts.withSpan !== void 0) {
|
2491 | if (opts.withSpan instanceof AbsoluteSourceSpan2) {
|
2492 | withSpan = opts.withSpan;
|
2493 | } else {
|
2494 | withSpan = { start: opts.withSpan.start.offset, end: opts.withSpan.end.offset };
|
2495 | }
|
2496 | }
|
2497 | return withSpan;
|
2498 | }
|
2499 | function findFirstMatchingNode(tcb, opts) {
|
2500 | var _a;
|
2501 | const withSpan = getSpanFromOptions(opts);
|
2502 | const withExpressionIdentifier = opts.withExpressionIdentifier;
|
2503 | const sf = tcb.getSourceFile();
|
2504 | const visitor = makeRecursiveVisitor((node) => {
|
2505 | if (!opts.filter(node)) {
|
2506 | return null;
|
2507 | }
|
2508 | if (withSpan !== null) {
|
2509 | const comment = readSpanComment(node, sf);
|
2510 | if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
2511 | return null;
|
2512 | }
|
2513 | }
|
2514 | if (withExpressionIdentifier !== void 0 && !hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
2515 | return null;
|
2516 | }
|
2517 | return node;
|
2518 | });
|
2519 | return (_a = tcb.forEachChild(visitor)) != null ? _a : null;
|
2520 | }
|
2521 | function findAllMatchingNodes(tcb, opts) {
|
2522 | const withSpan = getSpanFromOptions(opts);
|
2523 | const withExpressionIdentifier = opts.withExpressionIdentifier;
|
2524 | const results = [];
|
2525 | const stack = [tcb];
|
2526 | const sf = tcb.getSourceFile();
|
2527 | while (stack.length > 0) {
|
2528 | const node = stack.pop();
|
2529 | if (!opts.filter(node)) {
|
2530 | stack.push(...node.getChildren());
|
2531 | continue;
|
2532 | }
|
2533 | if (withSpan !== null) {
|
2534 | const comment = readSpanComment(node, sf);
|
2535 | if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
2536 | stack.push(...node.getChildren());
|
2537 | continue;
|
2538 | }
|
2539 | }
|
2540 | if (withExpressionIdentifier !== void 0 && !hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
2541 | continue;
|
2542 | }
|
2543 | results.push(node);
|
2544 | }
|
2545 | return results;
|
2546 | }
|
2547 | function hasExpressionIdentifier(sourceFile, node, identifier) {
|
2548 | return ts14.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
2549 | if (kind !== ts14.SyntaxKind.MultiLineCommentTrivia) {
|
2550 | return false;
|
2551 | }
|
2552 | const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
2553 | return commentText === `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`;
|
2554 | }) || false;
|
2555 | }
|
2556 |
|
2557 |
|
2558 | var CompletionEngine = class {
|
2559 | constructor(tcb, data, tcbPath, tcbIsShim) {
|
2560 | this.tcb = tcb;
|
2561 | this.data = data;
|
2562 | this.tcbPath = tcbPath;
|
2563 | this.tcbIsShim = tcbIsShim;
|
2564 | this.templateContextCache = new Map();
|
2565 | this.expressionCompletionCache = new Map();
|
2566 | const globalRead = findFirstMatchingNode(this.tcb, {
|
2567 | filter: ts15.isPropertyAccessExpression,
|
2568 | withExpressionIdentifier: ExpressionIdentifier.COMPONENT_COMPLETION
|
2569 | });
|
2570 | if (globalRead !== null) {
|
2571 | this.componentContext = {
|
2572 | tcbPath: this.tcbPath,
|
2573 | isShimFile: this.tcbIsShim,
|
2574 | positionInFile: globalRead.name.getStart()
|
2575 | };
|
2576 | } else {
|
2577 | this.componentContext = null;
|
2578 | }
|
2579 | }
|
2580 | getGlobalCompletions(context, node) {
|
2581 | if (this.componentContext === null) {
|
2582 | return null;
|
2583 | }
|
2584 | const templateContext = this.getTemplateContextCompletions(context);
|
2585 | if (templateContext === null) {
|
2586 | return null;
|
2587 | }
|
2588 | let nodeContext = null;
|
2589 | if (node instanceof EmptyExpr) {
|
2590 | const nodeLocation = findFirstMatchingNode(this.tcb, {
|
2591 | filter: ts15.isIdentifier,
|
2592 | withSpan: node.sourceSpan
|
2593 | });
|
2594 | if (nodeLocation !== null) {
|
2595 | nodeContext = {
|
2596 | tcbPath: this.tcbPath,
|
2597 | isShimFile: this.tcbIsShim,
|
2598 | positionInFile: nodeLocation.getStart()
|
2599 | };
|
2600 | }
|
2601 | }
|
2602 | if (node instanceof PropertyRead2 && node.receiver instanceof ImplicitReceiver2) {
|
2603 | const nodeLocation = findFirstMatchingNode(this.tcb, {
|
2604 | filter: ts15.isPropertyAccessExpression,
|
2605 | withSpan: node.sourceSpan
|
2606 | });
|
2607 | if (nodeLocation) {
|
2608 | nodeContext = {
|
2609 | tcbPath: this.tcbPath,
|
2610 | isShimFile: this.tcbIsShim,
|
2611 | positionInFile: nodeLocation.getStart()
|
2612 | };
|
2613 | }
|
2614 | }
|
2615 | return {
|
2616 | componentContext: this.componentContext,
|
2617 | templateContext,
|
2618 | nodeContext
|
2619 | };
|
2620 | }
|
2621 | getExpressionCompletionLocation(expr) {
|
2622 | if (this.expressionCompletionCache.has(expr)) {
|
2623 | return this.expressionCompletionCache.get(expr);
|
2624 | }
|
2625 | let tsExpr = null;
|
2626 | if (expr instanceof PropertyRead2 || expr instanceof PropertyWrite2) {
|
2627 | tsExpr = findFirstMatchingNode(this.tcb, {
|
2628 | filter: ts15.isPropertyAccessExpression,
|
2629 | withSpan: expr.nameSpan
|
2630 | });
|
2631 | } else if (expr instanceof SafePropertyRead) {
|
2632 | const ternaryExpr = findFirstMatchingNode(this.tcb, {
|
2633 | filter: ts15.isParenthesizedExpression,
|
2634 | withSpan: expr.sourceSpan
|
2635 | });
|
2636 | if (ternaryExpr === null || !ts15.isConditionalExpression(ternaryExpr.expression)) {
|
2637 | return null;
|
2638 | }
|
2639 | const whenTrue = ternaryExpr.expression.whenTrue;
|
2640 | if (ts15.isPropertyAccessExpression(whenTrue)) {
|
2641 | tsExpr = whenTrue;
|
2642 | } else if (ts15.isCallExpression(whenTrue) && ts15.isPropertyAccessExpression(whenTrue.expression)) {
|
2643 | tsExpr = whenTrue.expression;
|
2644 | }
|
2645 | }
|
2646 | if (tsExpr === null) {
|
2647 | return null;
|
2648 | }
|
2649 | const res = {
|
2650 | tcbPath: this.tcbPath,
|
2651 | isShimFile: this.tcbIsShim,
|
2652 | positionInFile: tsExpr.name.getEnd()
|
2653 | };
|
2654 | this.expressionCompletionCache.set(expr, res);
|
2655 | return res;
|
2656 | }
|
2657 | getLiteralCompletionLocation(expr) {
|
2658 | if (this.expressionCompletionCache.has(expr)) {
|
2659 | return this.expressionCompletionCache.get(expr);
|
2660 | }
|
2661 | let tsExpr = null;
|
2662 | if (expr instanceof TmplAstTextAttribute) {
|
2663 | const strNode = findFirstMatchingNode(this.tcb, {
|
2664 | filter: ts15.isParenthesizedExpression,
|
2665 | withSpan: expr.sourceSpan
|
2666 | });
|
2667 | if (strNode !== null && ts15.isStringLiteral(strNode.expression)) {
|
2668 | tsExpr = strNode.expression;
|
2669 | }
|
2670 | } else {
|
2671 | tsExpr = findFirstMatchingNode(this.tcb, {
|
2672 | filter: (n) => ts15.isStringLiteral(n) || ts15.isNumericLiteral(n),
|
2673 | withSpan: expr.sourceSpan
|
2674 | });
|
2675 | }
|
2676 | if (tsExpr === null) {
|
2677 | return null;
|
2678 | }
|
2679 | let positionInShimFile = tsExpr.getEnd();
|
2680 | if (ts15.isStringLiteral(tsExpr)) {
|
2681 | positionInShimFile -= 1;
|
2682 | }
|
2683 | const res = {
|
2684 | tcbPath: this.tcbPath,
|
2685 | isShimFile: this.tcbIsShim,
|
2686 | positionInFile: positionInShimFile
|
2687 | };
|
2688 | this.expressionCompletionCache.set(expr, res);
|
2689 | return res;
|
2690 | }
|
2691 | getTemplateContextCompletions(context) {
|
2692 | if (this.templateContextCache.has(context)) {
|
2693 | return this.templateContextCache.get(context);
|
2694 | }
|
2695 | const templateContext = new Map();
|
2696 | for (const node of this.data.boundTarget.getEntitiesInTemplateScope(context)) {
|
2697 | if (node instanceof TmplAstReference2) {
|
2698 | templateContext.set(node.name, {
|
2699 | kind: CompletionKind.Reference,
|
2700 | node
|
2701 | });
|
2702 | } else {
|
2703 | templateContext.set(node.name, {
|
2704 | kind: CompletionKind.Variable,
|
2705 | node
|
2706 | });
|
2707 | }
|
2708 | }
|
2709 | this.templateContextCache.set(context, templateContext);
|
2710 | return templateContext;
|
2711 | }
|
2712 | };
|
2713 |
|
2714 |
|
2715 | import ts29 from "typescript";
|
2716 |
|
2717 |
|
2718 | import { DomElementSchemaRegistry } from "@angular/compiler";
|
2719 | import ts16 from "typescript";
|
2720 | var REGISTRY = new DomElementSchemaRegistry();
|
2721 | var REMOVE_XHTML_REGEX = /^:xhtml:/;
|
2722 | var RegistryDomSchemaChecker = class {
|
2723 | constructor(resolver) {
|
2724 | this.resolver = resolver;
|
2725 | this._diagnostics = [];
|
2726 | }
|
2727 | get diagnostics() {
|
2728 | return this._diagnostics;
|
2729 | }
|
2730 | checkElement(id, element, schemas) {
|
2731 | const name = element.name.replace(REMOVE_XHTML_REGEX, "");
|
2732 | if (!REGISTRY.hasElement(name, schemas)) {
|
2733 | const mapping = this.resolver.getSourceMapping(id);
|
2734 | let errorMsg = `'${name}' is not a known element:
|
2735 | `;
|
2736 | errorMsg += `1. If '${name}' is an Angular component, then verify that it is part of this module.
|
2737 | `;
|
2738 | if (name.indexOf("-") > -1) {
|
2739 | errorMsg += `2. If '${name}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.`;
|
2740 | } else {
|
2741 | errorMsg += `2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`;
|
2742 | }
|
2743 | const diag = makeTemplateDiagnostic(id, mapping, element.startSourceSpan, ts16.DiagnosticCategory.Error, ngErrorCode(ErrorCode.SCHEMA_INVALID_ELEMENT), errorMsg);
|
2744 | this._diagnostics.push(diag);
|
2745 | }
|
2746 | }
|
2747 | checkProperty(id, element, name, span, schemas) {
|
2748 | if (!REGISTRY.hasProperty(element.name, name, schemas)) {
|
2749 | const mapping = this.resolver.getSourceMapping(id);
|
2750 | let errorMsg = `Can't bind to '${name}' since it isn't a known property of '${element.name}'.`;
|
2751 | if (element.name.startsWith("ng-")) {
|
2752 | errorMsg += `
|
2753 | 1. If '${name}' is an Angular directive, then add 'CommonModule' to the '@NgModule.imports' of this component.
|
2754 | 2. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`;
|
2755 | } else if (element.name.indexOf("-") > -1) {
|
2756 | errorMsg += `
|
2757 | 1. If '${element.name}' is an Angular component and it has '${name}' input, then verify that it is part of this module.
|
2758 | 2. If '${element.name}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
|
2759 | 3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`;
|
2760 | }
|
2761 | const diag = makeTemplateDiagnostic(id, mapping, span, ts16.DiagnosticCategory.Error, ngErrorCode(ErrorCode.SCHEMA_INVALID_ATTRIBUTE), errorMsg);
|
2762 | this._diagnostics.push(diag);
|
2763 | }
|
2764 | }
|
2765 | };
|
2766 |
|
2767 |
|
2768 | import { ExpressionType, ExternalExpr as ExternalExpr2, TypeModifier } from "@angular/compiler";
|
2769 | import ts22 from "typescript";
|
2770 |
|
2771 |
|
2772 | import ts17 from "typescript";
|
2773 | var SAFE_TO_CAST_WITHOUT_PARENS = new Set([
|
2774 | ts17.SyntaxKind.ParenthesizedExpression,
|
2775 | ts17.SyntaxKind.Identifier,
|
2776 | ts17.SyntaxKind.CallExpression,
|
2777 | ts17.SyntaxKind.NonNullExpression,
|
2778 | ts17.SyntaxKind.ElementAccessExpression,
|
2779 | ts17.SyntaxKind.PropertyAccessExpression,
|
2780 | ts17.SyntaxKind.ArrayLiteralExpression,
|
2781 | ts17.SyntaxKind.ObjectLiteralExpression,
|
2782 | ts17.SyntaxKind.StringLiteral,
|
2783 | ts17.SyntaxKind.NumericLiteral,
|
2784 | ts17.SyntaxKind.TrueKeyword,
|
2785 | ts17.SyntaxKind.FalseKeyword,
|
2786 | ts17.SyntaxKind.NullKeyword,
|
2787 | ts17.SyntaxKind.UndefinedKeyword
|
2788 | ]);
|
2789 | function tsCastToAny(expr) {
|
2790 | if (!SAFE_TO_CAST_WITHOUT_PARENS.has(expr.kind)) {
|
2791 | expr = ts17.createParen(expr);
|
2792 | }
|
2793 | return ts17.createParen(ts17.createAsExpression(expr, ts17.createKeywordTypeNode(ts17.SyntaxKind.AnyKeyword)));
|
2794 | }
|
2795 | function tsCreateElement(tagName) {
|
2796 | const createElement = ts17.createPropertyAccess(ts17.createIdentifier("document"), "createElement");
|
2797 | return ts17.createCall(createElement, void 0, [ts17.createLiteral(tagName)]);
|
2798 | }
|
2799 | function tsDeclareVariable(id, type) {
|
2800 | const decl = ts17.createVariableDeclaration(id, type, ts17.createNonNullExpression(ts17.createNull()));
|
2801 | return ts17.createVariableStatement(void 0, [decl]);
|
2802 | }
|
2803 | function tsCreateTypeQueryForCoercedInput(typeName, coercedInputName) {
|
2804 | return ts17.createTypeQueryNode(ts17.createQualifiedName(typeName, `ngAcceptInputType_${coercedInputName}`));
|
2805 | }
|
2806 | function tsCreateVariable(id, initializer) {
|
2807 | const decl = ts17.createVariableDeclaration(id, void 0, initializer);
|
2808 | return ts17.createVariableStatement(void 0, [decl]);
|
2809 | }
|
2810 | function tsCallMethod(receiver, methodName, args = []) {
|
2811 | const methodAccess = ts17.createPropertyAccess(receiver, methodName);
|
2812 | return ts17.createCall(methodAccess, void 0, args);
|
2813 | }
|
2814 | function checkIfClassIsExported(node) {
|
2815 | if (node.modifiers !== void 0 && node.modifiers.some((mod) => mod.kind === ts17.SyntaxKind.ExportKeyword)) {
|
2816 | return true;
|
2817 | } else if (node.parent !== void 0 && ts17.isSourceFile(node.parent) && checkIfFileHasExport(node.parent, node.name.text)) {
|
2818 | return true;
|
2819 | }
|
2820 | return false;
|
2821 | }
|
2822 | function checkIfFileHasExport(sf, name) {
|
2823 | for (const stmt of sf.statements) {
|
2824 | if (ts17.isExportDeclaration(stmt) && stmt.exportClause !== void 0 && ts17.isNamedExports(stmt.exportClause)) {
|
2825 | for (const element of stmt.exportClause.elements) {
|
2826 | if (element.propertyName === void 0 && element.name.text === name) {
|
2827 | return true;
|
2828 | } else if (element.propertyName !== void 0 && element.propertyName.text == name) {
|
2829 | return true;
|
2830 | }
|
2831 | }
|
2832 | }
|
2833 | }
|
2834 | return false;
|
2835 | }
|
2836 | function isAccessExpression(node) {
|
2837 | return ts17.isPropertyAccessExpression(node) || ts17.isElementAccessExpression(node);
|
2838 | }
|
2839 |
|
2840 |
|
2841 | import ts21 from "typescript";
|
2842 |
|
2843 |
|
2844 | import ts20 from "typescript";
|
2845 |
|
2846 |
|
2847 | import ts19 from "typescript";
|
2848 |
|
2849 |
|
2850 | import ts18 from "typescript";
|
2851 | var INELIGIBLE = {};
|
2852 | function canEmitType(type, canEmit) {
|
2853 | return canEmitTypeWorker(type);
|
2854 | function canEmitTypeWorker(type2) {
|
2855 | return visitNode(type2) !== INELIGIBLE;
|
2856 | }
|
2857 | function visitNode(node) {
|
2858 | if (ts18.isImportTypeNode(node)) {
|
2859 | return INELIGIBLE;
|
2860 | }
|
2861 | if (ts18.isTypeReferenceNode(node) && !canEmitTypeReference(node)) {
|
2862 | return INELIGIBLE;
|
2863 | } else {
|
2864 | return ts18.forEachChild(node, visitNode);
|
2865 | }
|
2866 | }
|
2867 | function canEmitTypeReference(type2) {
|
2868 | if (!canEmit(type2)) {
|
2869 | return false;
|
2870 | }
|
2871 | return type2.typeArguments === void 0 || type2.typeArguments.every(canEmitTypeWorker);
|
2872 | }
|
2873 | }
|
2874 | var TypeEmitter = class {
|
2875 | constructor(translator) {
|
2876 | this.translator = translator;
|
2877 | }
|
2878 | emitType(type) {
|
2879 | const typeReferenceTransformer = (context) => {
|
2880 | const visitNode = (node) => {
|
2881 | if (ts18.isImportTypeNode(node)) {
|
2882 | throw new Error("Unable to emit import type");
|
2883 | }
|
2884 | if (ts18.isTypeReferenceNode(node)) {
|
2885 | return this.emitTypeReference(node);
|
2886 | } else if (ts18.isLiteralExpression(node)) {
|
2887 | const clone = ts18.getMutableClone(node);
|
2888 | ts18.setTextRange(clone, { pos: -1, end: -1 });
|
2889 | return clone;
|
2890 | } else {
|
2891 | return ts18.visitEachChild(node, visitNode, context);
|
2892 | }
|
2893 | };
|
2894 | return (node) => ts18.visitNode(node, visitNode);
|
2895 | };
|
2896 | return ts18.transform(type, [typeReferenceTransformer]).transformed[0];
|
2897 | }
|
2898 | emitTypeReference(type) {
|
2899 | const translatedType = this.translator(type);
|
2900 | if (translatedType === null) {
|
2901 | throw new Error("Unable to emit an unresolved reference");
|
2902 | }
|
2903 | let typeArguments = void 0;
|
2904 | if (type.typeArguments !== void 0) {
|
2905 | typeArguments = ts18.createNodeArray(type.typeArguments.map((typeArg) => this.emitType(typeArg)));
|
2906 | }
|
2907 | return ts18.updateTypeReferenceNode(type, translatedType.typeName, typeArguments);
|
2908 | }
|
2909 | };
|
2910 |
|
2911 |
|
2912 | var TypeParameterEmitter = class {
|
2913 | constructor(typeParameters, reflector) {
|
2914 | this.typeParameters = typeParameters;
|
2915 | this.reflector = reflector;
|
2916 | }
|
2917 | canEmit(canEmitReference) {
|
2918 | if (this.typeParameters === void 0) {
|
2919 | return true;
|
2920 | }
|
2921 | return this.typeParameters.every((typeParam) => {
|
2922 | return this.canEmitType(typeParam.constraint, canEmitReference) && this.canEmitType(typeParam.default, canEmitReference);
|
2923 | });
|
2924 | }
|
2925 | canEmitType(type, canEmitReference) {
|
2926 | if (type === void 0) {
|
2927 | return true;
|
2928 | }
|
2929 | return canEmitType(type, (typeReference) => {
|
2930 | const reference = this.resolveTypeReference(typeReference);
|
2931 | if (reference === null) {
|
2932 | return false;
|
2933 | }
|
2934 | if (reference instanceof Reference) {
|
2935 | return canEmitReference(reference);
|
2936 | }
|
2937 | return true;
|
2938 | });
|
2939 | }
|
2940 | emit(emitReference) {
|
2941 | if (this.typeParameters === void 0) {
|
2942 | return void 0;
|
2943 | }
|
2944 | const emitter = new TypeEmitter((type) => this.translateTypeReference(type, emitReference));
|
2945 | return this.typeParameters.map((typeParam) => {
|
2946 | const constraint = typeParam.constraint !== void 0 ? emitter.emitType(typeParam.constraint) : void 0;
|
2947 | const defaultType = typeParam.default !== void 0 ? emitter.emitType(typeParam.default) : void 0;
|
2948 | return ts19.updateTypeParameterDeclaration(typeParam, typeParam.name, constraint, defaultType);
|
2949 | });
|
2950 | }
|
2951 | resolveTypeReference(type) {
|
2952 | const target = ts19.isIdentifier(type.typeName) ? type.typeName : type.typeName.right;
|
2953 | const declaration = this.reflector.getDeclarationOfIdentifier(target);
|
2954 | if (declaration === null || declaration.node === null) {
|
2955 | return null;
|
2956 | }
|
2957 | if (this.isLocalTypeParameter(declaration.node)) {
|
2958 | return type;
|
2959 | }
|
2960 | let owningModule = null;
|
2961 | if (declaration.viaModule !== null) {
|
2962 | owningModule = {
|
2963 | specifier: declaration.viaModule,
|
2964 | resolutionContext: type.getSourceFile().fileName
|
2965 | };
|
2966 | }
|
2967 | return new Reference(declaration.node, owningModule);
|
2968 | }
|
2969 | translateTypeReference(type, emitReference) {
|
2970 | const reference = this.resolveTypeReference(type);
|
2971 | if (!(reference instanceof Reference)) {
|
2972 | return reference;
|
2973 | }
|
2974 | const typeNode = emitReference(reference);
|
2975 | if (typeNode === null) {
|
2976 | return null;
|
2977 | }
|
2978 | if (!ts19.isTypeReferenceNode(typeNode)) {
|
2979 | throw new Error(`Expected TypeReferenceNode for emitted reference, got ${ts19.SyntaxKind[typeNode.kind]}.`);
|
2980 | }
|
2981 | return typeNode;
|
2982 | }
|
2983 | isLocalTypeParameter(decl) {
|
2984 | return this.typeParameters.some((param) => param === decl);
|
2985 | }
|
2986 | };
|
2987 |
|
2988 |
|
2989 | var TcbInliningRequirement;
|
2990 | (function(TcbInliningRequirement2) {
|
2991 | TcbInliningRequirement2[TcbInliningRequirement2["MustInline"] = 0] = "MustInline";
|
2992 | TcbInliningRequirement2[TcbInliningRequirement2["ShouldInlineForGenericBounds"] = 1] = "ShouldInlineForGenericBounds";
|
2993 | TcbInliningRequirement2[TcbInliningRequirement2["None"] = 2] = "None";
|
2994 | })(TcbInliningRequirement || (TcbInliningRequirement = {}));
|
2995 | function requiresInlineTypeCheckBlock(node, env, usedPipes, reflector) {
|
2996 | if (!checkIfClassIsExported(node)) {
|
2997 | return TcbInliningRequirement.MustInline;
|
2998 | } else if (!checkIfGenericTypeBoundsCanBeEmitted(node, reflector, env)) {
|
2999 | return TcbInliningRequirement.ShouldInlineForGenericBounds;
|
3000 | } else if (Array.from(usedPipes.values()).some((pipeRef) => !checkIfClassIsExported(pipeRef.node))) {
|
3001 | return TcbInliningRequirement.MustInline;
|
3002 | } else {
|
3003 | return TcbInliningRequirement.None;
|
3004 | }
|
3005 | }
|
3006 | function getTemplateMapping(shimSf, position, resolver, isDiagnosticRequest) {
|
3007 | const node = getTokenAtPosition(shimSf, position);
|
3008 | const sourceLocation = findSourceLocation(node, shimSf, isDiagnosticRequest);
|
3009 | if (sourceLocation === null) {
|
3010 | return null;
|
3011 | }
|
3012 | const mapping = resolver.getSourceMapping(sourceLocation.id);
|
3013 | const span = resolver.toParseSourceSpan(sourceLocation.id, sourceLocation.span);
|
3014 | if (span === null) {
|
3015 | return null;
|
3016 | }
|
3017 | return { sourceLocation, templateSourceMapping: mapping, span };
|
3018 | }
|
3019 | function findTypeCheckBlock(file, id, isDiagnosticRequest) {
|
3020 | for (const stmt of file.statements) {
|
3021 | if (ts20.isFunctionDeclaration(stmt) && getTemplateId2(stmt, file, isDiagnosticRequest) === id) {
|
3022 | return stmt;
|
3023 | }
|
3024 | }
|
3025 | return null;
|
3026 | }
|
3027 | function findSourceLocation(node, sourceFile, isDiagnosticsRequest) {
|
3028 | while (node !== void 0 && !ts20.isFunctionDeclaration(node)) {
|
3029 | if (hasIgnoreForDiagnosticsMarker(node, sourceFile) && isDiagnosticsRequest) {
|
3030 | return null;
|
3031 | }
|
3032 | const span = readSpanComment(node, sourceFile);
|
3033 | if (span !== null) {
|
3034 | const id = getTemplateId2(node, sourceFile, isDiagnosticsRequest);
|
3035 | if (id === null) {
|
3036 | return null;
|
3037 | }
|
3038 | return { id, span };
|
3039 | }
|
3040 | node = node.parent;
|
3041 | }
|
3042 | return null;
|
3043 | }
|
3044 | function getTemplateId2(node, sourceFile, isDiagnosticRequest) {
|
3045 | while (!ts20.isFunctionDeclaration(node)) {
|
3046 | if (hasIgnoreForDiagnosticsMarker(node, sourceFile) && isDiagnosticRequest) {
|
3047 | return null;
|
3048 | }
|
3049 | node = node.parent;
|
3050 | if (node === void 0) {
|
3051 | return null;
|
3052 | }
|
3053 | }
|
3054 | const start = node.getFullStart();
|
3055 | return ts20.forEachLeadingCommentRange(sourceFile.text, start, (pos, end, kind) => {
|
3056 | if (kind !== ts20.SyntaxKind.MultiLineCommentTrivia) {
|
3057 | return null;
|
3058 | }
|
3059 | const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
3060 | return commentText;
|
3061 | }) || null;
|
3062 | }
|
3063 | function checkIfGenericTypeBoundsCanBeEmitted(node, reflector, env) {
|
3064 | const emitter = new TypeParameterEmitter(node.typeParameters, reflector);
|
3065 | return emitter.canEmit((ref) => env.canReferenceType(ref));
|
3066 | }
|
3067 |
|
3068 |
|
3069 | function generateTypeCtorDeclarationFn(node, meta, nodeTypeRef, typeParams) {
|
3070 | const rawTypeArgs = typeParams !== void 0 ? generateGenericArgs(typeParams) : void 0;
|
3071 | const rawType = ts21.createTypeReferenceNode(nodeTypeRef, rawTypeArgs);
|
3072 | const initParam = constructTypeCtorParameter(node, meta, rawType);
|
3073 | const typeParameters = typeParametersWithDefaultTypes(typeParams);
|
3074 | if (meta.body) {
|
3075 | const fnType = ts21.createFunctionTypeNode(typeParameters, [initParam], rawType);
|
3076 | const decl = ts21.createVariableDeclaration(meta.fnName, fnType, ts21.createNonNullExpression(ts21.createNull()));
|
3077 | const declList = ts21.createVariableDeclarationList([decl], ts21.NodeFlags.Const);
|
3078 | return ts21.createVariableStatement(void 0, declList);
|
3079 | } else {
|
3080 | return ts21.createFunctionDeclaration(void 0, [ts21.createModifier(ts21.SyntaxKind.DeclareKeyword)], void 0, meta.fnName, typeParameters, [initParam], rawType, void 0);
|
3081 | }
|
3082 | }
|
3083 | function generateInlineTypeCtor(node, meta) {
|
3084 | const rawTypeArgs = node.typeParameters !== void 0 ? generateGenericArgs(node.typeParameters) : void 0;
|
3085 | const rawType = ts21.createTypeReferenceNode(node.name, rawTypeArgs);
|
3086 | const initParam = constructTypeCtorParameter(node, meta, rawType);
|
3087 | let body = void 0;
|
3088 | if (meta.body) {
|
3089 | body = ts21.createBlock([
|
3090 | ts21.createReturn(ts21.createNonNullExpression(ts21.createNull()))
|
3091 | ]);
|
3092 | }
|
3093 | return ts21.createMethod(void 0, [ts21.createModifier(ts21.SyntaxKind.StaticKeyword)], void 0, meta.fnName, void 0, typeParametersWithDefaultTypes(node.typeParameters), [initParam], rawType, body);
|
3094 | }
|
3095 | function constructTypeCtorParameter(node, meta, rawType) {
|
3096 | let initType = null;
|
3097 | const keys = meta.fields.inputs;
|
3098 | const plainKeys = [];
|
3099 | const coercedKeys = [];
|
3100 | for (const key of keys) {
|
3101 | if (!meta.coercedInputFields.has(key)) {
|
3102 | plainKeys.push(ts21.createLiteralTypeNode(ts21.createStringLiteral(key)));
|
3103 | } else {
|
3104 | coercedKeys.push(ts21.createPropertySignature(void 0, key, void 0, tsCreateTypeQueryForCoercedInput(rawType.typeName, key), void 0));
|
3105 | }
|
3106 | }
|
3107 | if (plainKeys.length > 0) {
|
3108 | const keyTypeUnion = ts21.createUnionTypeNode(plainKeys);
|
3109 | initType = ts21.createTypeReferenceNode("Pick", [rawType, keyTypeUnion]);
|
3110 | }
|
3111 | if (coercedKeys.length > 0) {
|
3112 | const coercedLiteral = ts21.createTypeLiteralNode(coercedKeys);
|
3113 | initType = initType !== null ? ts21.createIntersectionTypeNode([initType, coercedLiteral]) : coercedLiteral;
|
3114 | }
|
3115 | if (initType === null) {
|
3116 | initType = ts21.createTypeLiteralNode([]);
|
3117 | }
|
3118 | return ts21.createParameter(void 0, void 0, void 0, "init", void 0, initType, void 0);
|
3119 | }
|
3120 | function generateGenericArgs(params) {
|
3121 | return params.map((param) => ts21.createTypeReferenceNode(param.name, void 0));
|
3122 | }
|
3123 | function requiresInlineTypeCtor(node, host, env) {
|
3124 | return !checkIfGenericTypeBoundsCanBeEmitted(node, host, env);
|
3125 | }
|
3126 | function typeParametersWithDefaultTypes(params) {
|
3127 | if (params === void 0) {
|
3128 | return void 0;
|
3129 | }
|
3130 | return params.map((param) => {
|
3131 | if (param.default === void 0) {
|
3132 | return ts21.updateTypeParameterDeclaration(param, param.name, param.constraint, ts21.createKeywordTypeNode(ts21.SyntaxKind.AnyKeyword));
|
3133 | } else {
|
3134 | return param;
|
3135 | }
|
3136 | });
|
3137 | }
|
3138 |
|
3139 |
|
3140 | var Environment = class {
|
3141 | constructor(config, importManager, refEmitter, reflector, contextFile) {
|
3142 | this.config = config;
|
3143 | this.importManager = importManager;
|
3144 | this.refEmitter = refEmitter;
|
3145 | this.reflector = reflector;
|
3146 | this.contextFile = contextFile;
|
3147 | this.nextIds = {
|
3148 | pipeInst: 1,
|
3149 | typeCtor: 1
|
3150 | };
|
3151 | this.typeCtors = new Map();
|
3152 | this.typeCtorStatements = [];
|
3153 | this.pipeInsts = new Map();
|
3154 | this.pipeInstStatements = [];
|
3155 | }
|
3156 | typeCtorFor(dir) {
|
3157 | const dirRef = dir.ref;
|
3158 | const node = dirRef.node;
|
3159 | if (this.typeCtors.has(node)) {
|
3160 | return this.typeCtors.get(node);
|
3161 | }
|
3162 | if (requiresInlineTypeCtor(node, this.reflector, this)) {
|
3163 | const ref = this.reference(dirRef);
|
3164 | const typeCtorExpr = ts22.createPropertyAccess(ref, "ngTypeCtor");
|
3165 | this.typeCtors.set(node, typeCtorExpr);
|
3166 | return typeCtorExpr;
|
3167 | } else {
|
3168 | const fnName = `_ctor${this.nextIds.typeCtor++}`;
|
3169 | const nodeTypeRef = this.referenceType(dirRef);
|
3170 | if (!ts22.isTypeReferenceNode(nodeTypeRef)) {
|
3171 | throw new Error(`Expected TypeReferenceNode from reference to ${dirRef.debugName}`);
|
3172 | }
|
3173 | const meta = {
|
3174 | fnName,
|
3175 | body: true,
|
3176 | fields: {
|
3177 | inputs: dir.inputs.classPropertyNames,
|
3178 | outputs: dir.outputs.classPropertyNames,
|
3179 | queries: dir.queries
|
3180 | },
|
3181 | coercedInputFields: dir.coercedInputFields
|
3182 | };
|
3183 | const typeParams = this.emitTypeParameters(node);
|
3184 | const typeCtor = generateTypeCtorDeclarationFn(node, meta, nodeTypeRef.typeName, typeParams);
|
3185 | this.typeCtorStatements.push(typeCtor);
|
3186 | const fnId = ts22.createIdentifier(fnName);
|
3187 | this.typeCtors.set(node, fnId);
|
3188 | return fnId;
|
3189 | }
|
3190 | }
|
3191 | pipeInst(ref) {
|
3192 | if (this.pipeInsts.has(ref.node)) {
|
3193 | return this.pipeInsts.get(ref.node);
|
3194 | }
|
3195 | const pipeType = this.referenceType(ref);
|
3196 | const pipeInstId = ts22.createIdentifier(`_pipe${this.nextIds.pipeInst++}`);
|
3197 | this.pipeInstStatements.push(tsDeclareVariable(pipeInstId, pipeType));
|
3198 | this.pipeInsts.set(ref.node, pipeInstId);
|
3199 | return pipeInstId;
|
3200 | }
|
3201 | reference(ref) {
|
3202 | const ngExpr = this.refEmitter.emit(ref, this.contextFile, ImportFlags.NoAliasing);
|
3203 | assertSuccessfulReferenceEmit(ngExpr, this.contextFile, "class");
|
3204 | return translateExpression(ngExpr.expression, this.importManager);
|
3205 | }
|
3206 | canReferenceType(ref) {
|
3207 | const result = this.refEmitter.emit(ref, this.contextFile, ImportFlags.NoAliasing | ImportFlags.AllowTypeImports | ImportFlags.AllowRelativeDtsImports);
|
3208 | return result.kind === 0;
|
3209 | }
|
3210 | referenceType(ref) {
|
3211 | const ngExpr = this.refEmitter.emit(ref, this.contextFile, ImportFlags.NoAliasing | ImportFlags.AllowTypeImports | ImportFlags.AllowRelativeDtsImports);
|
3212 | assertSuccessfulReferenceEmit(ngExpr, this.contextFile, "symbol");
|
3213 | return translateType(new ExpressionType(ngExpr.expression), this.importManager);
|
3214 | }
|
3215 | emitTypeParameters(declaration) {
|
3216 | const emitter = new TypeParameterEmitter(declaration.typeParameters, this.reflector);
|
3217 | return emitter.emit((ref) => this.referenceType(ref));
|
3218 | }
|
3219 | referenceExternalType(moduleName, name, typeParams) {
|
3220 | const external = new ExternalExpr2({ moduleName, name });
|
3221 | return translateType(new ExpressionType(external, TypeModifier.None, typeParams), this.importManager);
|
3222 | }
|
3223 | getPreludeStatements() {
|
3224 | return [
|
3225 | ...this.pipeInstStatements,
|
3226 | ...this.typeCtorStatements
|
3227 | ];
|
3228 | }
|
3229 | };
|
3230 |
|
3231 |
|
3232 | import { TmplAstElement as TmplAstElement2 } from "@angular/compiler";
|
3233 | import ts23 from "typescript";
|
3234 | var OutOfBandDiagnosticRecorderImpl = class {
|
3235 | constructor(resolver) {
|
3236 | this.resolver = resolver;
|
3237 | this._diagnostics = [];
|
3238 | this.recordedPipes = new Set();
|
3239 | }
|
3240 | get diagnostics() {
|
3241 | return this._diagnostics;
|
3242 | }
|
3243 | missingReferenceTarget(templateId, ref) {
|
3244 | const mapping = this.resolver.getSourceMapping(templateId);
|
3245 | const value = ref.value.trim();
|
3246 | const errorMsg = `No directive found with exportAs '${value}'.`;
|
3247 | this._diagnostics.push(makeTemplateDiagnostic(templateId, mapping, ref.valueSpan || ref.sourceSpan, ts23.DiagnosticCategory.Error, ngErrorCode(ErrorCode.MISSING_REFERENCE_TARGET), errorMsg));
|
3248 | }
|
3249 | missingPipe(templateId, ast) {
|
3250 | if (this.recordedPipes.has(ast)) {
|
3251 | return;
|
3252 | }
|
3253 | const mapping = this.resolver.getSourceMapping(templateId);
|
3254 | const errorMsg = `No pipe found with name '${ast.name}'.`;
|
3255 | const sourceSpan = this.resolver.toParseSourceSpan(templateId, ast.nameSpan);
|
3256 | if (sourceSpan === null) {
|
3257 | throw new Error(`Assertion failure: no SourceLocation found for usage of pipe '${ast.name}'.`);
|
3258 | }
|
3259 | this._diagnostics.push(makeTemplateDiagnostic(templateId, mapping, sourceSpan, ts23.DiagnosticCategory.Error, ngErrorCode(ErrorCode.MISSING_PIPE), errorMsg));
|
3260 | this.recordedPipes.add(ast);
|
3261 | }
|
3262 | illegalAssignmentToTemplateVar(templateId, assignment, target) {
|
3263 | var _a, _b;
|
3264 | const mapping = this.resolver.getSourceMapping(templateId);
|
3265 | const errorMsg = `Cannot use variable '${assignment.name}' as the left-hand side of an assignment expression. Template variables are read-only.`;
|
3266 | const sourceSpan = this.resolver.toParseSourceSpan(templateId, assignment.sourceSpan);
|
3267 | if (sourceSpan === null) {
|
3268 | throw new Error(`Assertion failure: no SourceLocation found for property binding.`);
|
3269 | }
|
3270 | this._diagnostics.push(makeTemplateDiagnostic(templateId, mapping, sourceSpan, ts23.DiagnosticCategory.Error, ngErrorCode(ErrorCode.WRITE_TO_READ_ONLY_VARIABLE), errorMsg, [{
|
3271 | text: `The variable ${assignment.name} is declared here.`,
|
3272 | start: ((_a = target.valueSpan) == null ? void 0 : _a.start.offset) || target.sourceSpan.start.offset,
|
3273 | end: ((_b = target.valueSpan) == null ? void 0 : _b.end.offset) || target.sourceSpan.end.offset,
|
3274 | sourceFile: mapping.node.getSourceFile()
|
3275 | }]));
|
3276 | }
|
3277 | duplicateTemplateVar(templateId, variable, firstDecl) {
|
3278 | const mapping = this.resolver.getSourceMapping(templateId);
|
3279 | const errorMsg = `Cannot redeclare variable '${variable.name}' as it was previously declared elsewhere for the same template.`;
|
3280 | this._diagnostics.push(makeTemplateDiagnostic(templateId, mapping, variable.sourceSpan, ts23.DiagnosticCategory.Error, ngErrorCode(ErrorCode.DUPLICATE_VARIABLE_DECLARATION), errorMsg, [{
|
3281 | text: `The variable '${firstDecl.name}' was first declared here.`,
|
3282 | start: firstDecl.sourceSpan.start.offset,
|
3283 | end: firstDecl.sourceSpan.end.offset,
|
3284 | sourceFile: mapping.node.getSourceFile()
|
3285 | }]));
|
3286 | }
|
3287 | requiresInlineTcb(templateId, node) {
|
3288 | this._diagnostics.push(makeInlineDiagnostic(templateId, ErrorCode.INLINE_TCB_REQUIRED, node.name, `This component requires inline template type-checking, which is not supported by the current environment.`));
|
3289 | }
|
3290 | requiresInlineTypeConstructors(templateId, node, directives) {
|
3291 | let message;
|
3292 | if (directives.length > 1) {
|
3293 | message = `This component uses directives which require inline type constructors, which are not supported by the current environment.`;
|
3294 | } else {
|
3295 | message = `This component uses a directive which requires an inline type constructor, which is not supported by the current environment.`;
|
3296 | }
|
3297 | this._diagnostics.push(makeInlineDiagnostic(templateId, ErrorCode.INLINE_TYPE_CTOR_REQUIRED, node.name, message, directives.map((dir) => makeRelatedInformation(dir.name, `Requires an inline type constructor.`))));
|
3298 | }
|
3299 | suboptimalTypeInference(templateId, variables) {
|
3300 | const mapping = this.resolver.getSourceMapping(templateId);
|
3301 | let diagnosticVar = null;
|
3302 | for (const variable of variables) {
|
3303 | if (diagnosticVar === null || (variable.value === "" || variable.value === "$implicit")) {
|
3304 | diagnosticVar = variable;
|
3305 | }
|
3306 | }
|
3307 | if (diagnosticVar === null) {
|
3308 | return;
|
3309 | }
|
3310 | let varIdentification = `'${diagnosticVar.name}'`;
|
3311 | if (variables.length === 2) {
|
3312 | varIdentification += ` (and 1 other)`;
|
3313 | } else if (variables.length > 2) {
|
3314 | varIdentification += ` (and ${variables.length - 1} others)`;
|
3315 | }
|
3316 | const message = `This structural directive supports advanced type inference, but the current compiler configuration prevents its usage. The variable ${varIdentification} will have type 'any' as a result.
|
3317 |
|
3318 | Consider enabling the 'strictTemplates' option in your tsconfig.json for better type inference within this template.`;
|
3319 | this._diagnostics.push(makeTemplateDiagnostic(templateId, mapping, diagnosticVar.keySpan, ts23.DiagnosticCategory.Suggestion, ngErrorCode(ErrorCode.SUGGEST_SUBOPTIMAL_TYPE_INFERENCE), message));
|
3320 | }
|
3321 | splitTwoWayBinding(templateId, input, output, inputConsumer, outputConsumer) {
|
3322 | const mapping = this.resolver.getSourceMapping(templateId);
|
3323 | const errorMsg = `The property and event halves of the two-way binding '${input.name}' are not bound to the same target.
|
3324 | Find more at https://angular.io/guide/two-way-binding#how-two-way-binding-works`;
|
3325 | const relatedMessages = [];
|
3326 | relatedMessages.push({
|
3327 | text: `The property half of the binding is to the '${inputConsumer.name.text}' component.`,
|
3328 | start: inputConsumer.name.getStart(),
|
3329 | end: inputConsumer.name.getEnd(),
|
3330 | sourceFile: inputConsumer.name.getSourceFile()
|
3331 | });
|
3332 | if (outputConsumer instanceof TmplAstElement2) {
|
3333 | let message = `The event half of the binding is to a native event called '${input.name}' on the <${outputConsumer.name}> DOM element.`;
|
3334 | if (!mapping.node.getSourceFile().isDeclarationFile) {
|
3335 | message += `
|
3336 |
|
3337 | Are you missing an output declaration called '${output.name}'?`;
|
3338 | }
|
3339 | relatedMessages.push({
|
3340 | text: message,
|
3341 | start: outputConsumer.sourceSpan.start.offset + 1,
|
3342 | end: outputConsumer.sourceSpan.start.offset + outputConsumer.name.length + 1,
|
3343 | sourceFile: mapping.node.getSourceFile()
|
3344 | });
|
3345 | } else {
|
3346 | relatedMessages.push({
|
3347 | text: `The event half of the binding is to the '${outputConsumer.name.text}' component.`,
|
3348 | start: outputConsumer.name.getStart(),
|
3349 | end: outputConsumer.name.getEnd(),
|
3350 | sourceFile: outputConsumer.name.getSourceFile()
|
3351 | });
|
3352 | }
|
3353 | this._diagnostics.push(makeTemplateDiagnostic(templateId, mapping, input.keySpan, ts23.DiagnosticCategory.Error, ngErrorCode(ErrorCode.SPLIT_TWO_WAY_BINDING), errorMsg, relatedMessages));
|
3354 | }
|
3355 | };
|
3356 | function makeInlineDiagnostic(templateId, code, node, messageText, relatedInformation) {
|
3357 | return __spreadProps(__spreadValues({}, makeDiagnostic(code, node, messageText, relatedInformation)), {
|
3358 | componentFile: node.getSourceFile(),
|
3359 | templateId
|
3360 | });
|
3361 | }
|
3362 |
|
3363 |
|
3364 | import ts24 from "typescript";
|
3365 | var TypeCheckShimGenerator = class {
|
3366 | constructor() {
|
3367 | this.extensionPrefix = "ngtypecheck";
|
3368 | this.shouldEmit = false;
|
3369 | }
|
3370 | generateShimForFile(sf, genFilePath, priorShimSf) {
|
3371 | if (priorShimSf !== null) {
|
3372 | return priorShimSf;
|
3373 | }
|
3374 | return ts24.createSourceFile(genFilePath, "export const USED_FOR_NG_TYPE_CHECKING = true;", ts24.ScriptTarget.Latest, true, ts24.ScriptKind.TS);
|
3375 | }
|
3376 | static shimFor(fileName) {
|
3377 | return absoluteFrom(fileName.replace(/\.tsx?$/, ".ngtypecheck.ts"));
|
3378 | }
|
3379 | };
|
3380 |
|
3381 |
|
3382 | import { BindingPipe, Call as Call2, DYNAMIC_TYPE, ImplicitReceiver as ImplicitReceiver4, PropertyRead as PropertyRead4, PropertyWrite as PropertyWrite3, SafeCall, SafePropertyRead as SafePropertyRead3, ThisReceiver, TmplAstBoundAttribute, TmplAstBoundText, TmplAstElement as TmplAstElement3, TmplAstIcu, TmplAstReference as TmplAstReference3, TmplAstTemplate as TmplAstTemplate2, TmplAstTextAttribute as TmplAstTextAttribute2, TmplAstVariable as TmplAstVariable2 } from "@angular/compiler";
|
3383 | import ts27 from "typescript";
|
3384 |
|
3385 |
|
3386 | import { AbsoluteSourceSpan as AbsoluteSourceSpan3 } from "@angular/compiler";
|
3387 | import ts25 from "typescript";
|
3388 | function wrapForDiagnostics(expr) {
|
3389 | return ts25.createParen(expr);
|
3390 | }
|
3391 | function wrapForTypeChecker(expr) {
|
3392 | return ts25.createParen(expr);
|
3393 | }
|
3394 | function addParseSpanInfo(node, span) {
|
3395 | let commentText;
|
3396 | if (span instanceof AbsoluteSourceSpan3) {
|
3397 | commentText = `${span.start},${span.end}`;
|
3398 | } else {
|
3399 | commentText = `${span.start.offset},${span.end.offset}`;
|
3400 | }
|
3401 | ts25.addSyntheticTrailingComment(node, ts25.SyntaxKind.MultiLineCommentTrivia, commentText, false);
|
3402 | }
|
3403 | function addTemplateId(tcb, id) {
|
3404 | ts25.addSyntheticLeadingComment(tcb, ts25.SyntaxKind.MultiLineCommentTrivia, id, true);
|
3405 | }
|
3406 | function shouldReportDiagnostic(diagnostic) {
|
3407 | const { code } = diagnostic;
|
3408 | if (code === 6133) {
|
3409 | return false;
|
3410 | } else if (code === 6199) {
|
3411 | return false;
|
3412 | } else if (code === 2695) {
|
3413 | return false;
|
3414 | } else if (code === 7006) {
|
3415 | return false;
|
3416 | }
|
3417 | return true;
|
3418 | }
|
3419 | function translateDiagnostic(diagnostic, resolver) {
|
3420 | if (diagnostic.file === void 0 || diagnostic.start === void 0) {
|
3421 | return null;
|
3422 | }
|
3423 | const fullMapping = getTemplateMapping(diagnostic.file, diagnostic.start, resolver, true);
|
3424 | if (fullMapping === null) {
|
3425 | return null;
|
3426 | }
|
3427 | const { sourceLocation, templateSourceMapping, span } = fullMapping;
|
3428 | return makeTemplateDiagnostic(sourceLocation.id, templateSourceMapping, span, diagnostic.category, diagnostic.code, diagnostic.messageText);
|
3429 | }
|
3430 |
|
3431 |
|
3432 | import { ASTWithSource as ASTWithSource2, Call, EmptyExpr as EmptyExpr2, PropertyRead as PropertyRead3, SafeKeyedRead, SafePropertyRead as SafePropertyRead2 } from "@angular/compiler";
|
3433 | import ts26 from "typescript";
|
3434 | var NULL_AS_ANY = ts26.createAsExpression(ts26.createNull(), ts26.createKeywordTypeNode(ts26.SyntaxKind.AnyKeyword));
|
3435 | var UNDEFINED = ts26.createIdentifier("undefined");
|
3436 | var UNARY_OPS = new Map([
|
3437 | ["+", ts26.SyntaxKind.PlusToken],
|
3438 | ["-", ts26.SyntaxKind.MinusToken]
|
3439 | ]);
|
3440 | var BINARY_OPS = new Map([
|
3441 | ["+", ts26.SyntaxKind.PlusToken],
|
3442 | ["-", ts26.SyntaxKind.MinusToken],
|
3443 | ["<", ts26.SyntaxKind.LessThanToken],
|
3444 | [">", ts26.SyntaxKind.GreaterThanToken],
|
3445 | ["<=", ts26.SyntaxKind.LessThanEqualsToken],
|
3446 | [">=", ts26.SyntaxKind.GreaterThanEqualsToken],
|
3447 | ["==", ts26.SyntaxKind.EqualsEqualsToken],
|
3448 | ["===", ts26.SyntaxKind.EqualsEqualsEqualsToken],
|
3449 | ["*", ts26.SyntaxKind.AsteriskToken],
|
3450 | ["/", ts26.SyntaxKind.SlashToken],
|
3451 | ["%", ts26.SyntaxKind.PercentToken],
|
3452 | ["!=", ts26.SyntaxKind.ExclamationEqualsToken],
|
3453 | ["!==", ts26.SyntaxKind.ExclamationEqualsEqualsToken],
|
3454 | ["||", ts26.SyntaxKind.BarBarToken],
|
3455 | ["&&", ts26.SyntaxKind.AmpersandAmpersandToken],
|
3456 | ["&", ts26.SyntaxKind.AmpersandToken],
|
3457 | ["|", ts26.SyntaxKind.BarToken],
|
3458 | ["??", ts26.SyntaxKind.QuestionQuestionToken]
|
3459 | ]);
|
3460 | function astToTypescript(ast, maybeResolve, config) {
|
3461 | const translator = new AstTranslator(maybeResolve, config);
|
3462 | return translator.translate(ast);
|
3463 | }
|
3464 | var AstTranslator = class {
|
3465 | constructor(maybeResolve, config) {
|
3466 | this.maybeResolve = maybeResolve;
|
3467 | this.config = config;
|
3468 | }
|
3469 | translate(ast) {
|
3470 | if (ast instanceof ASTWithSource2) {
|
3471 | ast = ast.ast;
|
3472 | }
|
3473 | if (ast instanceof EmptyExpr2) {
|
3474 | const res = ts26.factory.createIdentifier("undefined");
|
3475 | addParseSpanInfo(res, ast.sourceSpan);
|
3476 | return res;
|
3477 | }
|
3478 | const resolved = this.maybeResolve(ast);
|
3479 | if (resolved !== null) {
|
3480 | return resolved;
|
3481 | }
|
3482 | return ast.visit(this);
|
3483 | }
|
3484 | visitUnary(ast) {
|
3485 | const expr = this.translate(ast.expr);
|
3486 | const op = UNARY_OPS.get(ast.operator);
|
3487 | if (op === void 0) {
|
3488 | throw new Error(`Unsupported Unary.operator: ${ast.operator}`);
|
3489 | }
|
3490 | const node = wrapForDiagnostics(ts26.createPrefix(op, expr));
|
3491 | addParseSpanInfo(node, ast.sourceSpan);
|
3492 | return node;
|
3493 | }
|
3494 | visitBinary(ast) {
|
3495 | const lhs = wrapForDiagnostics(this.translate(ast.left));
|
3496 | const rhs = wrapForDiagnostics(this.translate(ast.right));
|
3497 | const op = BINARY_OPS.get(ast.operation);
|
3498 | if (op === void 0) {
|
3499 | throw new Error(`Unsupported Binary.operation: ${ast.operation}`);
|
3500 | }
|
3501 | const node = ts26.createBinary(lhs, op, rhs);
|
3502 | addParseSpanInfo(node, ast.sourceSpan);
|
3503 | return node;
|
3504 | }
|
3505 | visitChain(ast) {
|
3506 | const elements = ast.expressions.map((expr) => this.translate(expr));
|
3507 | const node = wrapForDiagnostics(ts26.createCommaList(elements));
|
3508 | addParseSpanInfo(node, ast.sourceSpan);
|
3509 | return node;
|
3510 | }
|
3511 | visitConditional(ast) {
|
3512 | const condExpr = this.translate(ast.condition);
|
3513 | const trueExpr = this.translate(ast.trueExp);
|
3514 | const falseExpr = wrapForTypeChecker(this.translate(ast.falseExp));
|
3515 | const node = ts26.createParen(ts26.createConditional(condExpr, trueExpr, falseExpr));
|
3516 | addParseSpanInfo(node, ast.sourceSpan);
|
3517 | return node;
|
3518 | }
|
3519 | visitImplicitReceiver(ast) {
|
3520 | throw new Error("Method not implemented.");
|
3521 | }
|
3522 | visitThisReceiver(ast) {
|
3523 | throw new Error("Method not implemented.");
|
3524 | }
|
3525 | visitInterpolation(ast) {
|
3526 | return ast.expressions.reduce((lhs, ast2) => ts26.createBinary(lhs, ts26.SyntaxKind.PlusToken, wrapForTypeChecker(this.translate(ast2))), ts26.createLiteral(""));
|
3527 | }
|
3528 | visitKeyedRead(ast) {
|
3529 | const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
3530 | const key = this.translate(ast.key);
|
3531 | const node = ts26.createElementAccess(receiver, key);
|
3532 | addParseSpanInfo(node, ast.sourceSpan);
|
3533 | return node;
|
3534 | }
|
3535 | visitKeyedWrite(ast) {
|
3536 | const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
3537 | const left = ts26.createElementAccess(receiver, this.translate(ast.key));
|
3538 | const right = wrapForTypeChecker(this.translate(ast.value));
|
3539 | const node = wrapForDiagnostics(ts26.createBinary(left, ts26.SyntaxKind.EqualsToken, right));
|
3540 | addParseSpanInfo(node, ast.sourceSpan);
|
3541 | return node;
|
3542 | }
|
3543 | visitLiteralArray(ast) {
|
3544 | const elements = ast.expressions.map((expr) => this.translate(expr));
|
3545 | const literal = ts26.createArrayLiteral(elements);
|
3546 | const node = this.config.strictLiteralTypes ? literal : tsCastToAny(literal);
|
3547 | addParseSpanInfo(node, ast.sourceSpan);
|
3548 | return node;
|
3549 | }
|
3550 | visitLiteralMap(ast) {
|
3551 | const properties = ast.keys.map(({ key }, idx) => {
|
3552 | const value = this.translate(ast.values[idx]);
|
3553 | return ts26.createPropertyAssignment(ts26.createStringLiteral(key), value);
|
3554 | });
|
3555 | const literal = ts26.createObjectLiteral(properties, true);
|
3556 | const node = this.config.strictLiteralTypes ? literal : tsCastToAny(literal);
|
3557 | addParseSpanInfo(node, ast.sourceSpan);
|
3558 | return node;
|
3559 | }
|
3560 | visitLiteralPrimitive(ast) {
|
3561 | let node;
|
3562 | if (ast.value === void 0) {
|
3563 | node = ts26.createIdentifier("undefined");
|
3564 | } else if (ast.value === null) {
|
3565 | node = ts26.createNull();
|
3566 | } else {
|
3567 | node = ts26.createLiteral(ast.value);
|
3568 | }
|
3569 | addParseSpanInfo(node, ast.sourceSpan);
|
3570 | return node;
|
3571 | }
|
3572 | visitNonNullAssert(ast) {
|
3573 | const expr = wrapForDiagnostics(this.translate(ast.expression));
|
3574 | const node = ts26.createNonNullExpression(expr);
|
3575 | addParseSpanInfo(node, ast.sourceSpan);
|
3576 | return node;
|
3577 | }
|
3578 | visitPipe(ast) {
|
3579 | throw new Error("Method not implemented.");
|
3580 | }
|
3581 | visitPrefixNot(ast) {
|
3582 | const expression = wrapForDiagnostics(this.translate(ast.expression));
|
3583 | const node = ts26.createLogicalNot(expression);
|
3584 | addParseSpanInfo(node, ast.sourceSpan);
|
3585 | return node;
|
3586 | }
|
3587 | visitPropertyRead(ast) {
|
3588 | const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
3589 | const name = ts26.createPropertyAccess(receiver, ast.name);
|
3590 | addParseSpanInfo(name, ast.nameSpan);
|
3591 | const node = wrapForDiagnostics(name);
|
3592 | addParseSpanInfo(node, ast.sourceSpan);
|
3593 | return node;
|
3594 | }
|
3595 | visitPropertyWrite(ast) {
|
3596 | const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
3597 | const left = ts26.createPropertyAccess(receiver, ast.name);
|
3598 | addParseSpanInfo(left, ast.nameSpan);
|
3599 | const leftWithPath = wrapForDiagnostics(left);
|
3600 | addParseSpanInfo(leftWithPath, ast.sourceSpan);
|
3601 | const right = wrapForTypeChecker(this.translate(ast.value));
|
3602 | const node = wrapForDiagnostics(ts26.createBinary(leftWithPath, ts26.SyntaxKind.EqualsToken, right));
|
3603 | addParseSpanInfo(node, ast.sourceSpan);
|
3604 | return node;
|
3605 | }
|
3606 | visitQuote(ast) {
|
3607 | return NULL_AS_ANY;
|
3608 | }
|
3609 | visitSafePropertyRead(ast) {
|
3610 | let node;
|
3611 | const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
3612 | if (this.config.strictSafeNavigationTypes) {
|
3613 | const expr = ts26.createPropertyAccess(ts26.createNonNullExpression(receiver), ast.name);
|
3614 | addParseSpanInfo(expr, ast.nameSpan);
|
3615 | node = ts26.createParen(ts26.createConditional(NULL_AS_ANY, expr, UNDEFINED));
|
3616 | } else if (VeSafeLhsInferenceBugDetector.veWillInferAnyFor(ast)) {
|
3617 | node = ts26.createPropertyAccess(tsCastToAny(receiver), ast.name);
|
3618 | } else {
|
3619 | const expr = ts26.createPropertyAccess(ts26.createNonNullExpression(receiver), ast.name);
|
3620 | addParseSpanInfo(expr, ast.nameSpan);
|
3621 | node = tsCastToAny(expr);
|
3622 | }
|
3623 | addParseSpanInfo(node, ast.sourceSpan);
|
3624 | return node;
|
3625 | }
|
3626 | visitSafeKeyedRead(ast) {
|
3627 | const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
3628 | const key = this.translate(ast.key);
|
3629 | let node;
|
3630 | if (this.config.strictSafeNavigationTypes) {
|
3631 | const expr = ts26.createElementAccess(ts26.createNonNullExpression(receiver), key);
|
3632 | addParseSpanInfo(expr, ast.sourceSpan);
|
3633 | node = ts26.createParen(ts26.createConditional(NULL_AS_ANY, expr, UNDEFINED));
|
3634 | } else if (VeSafeLhsInferenceBugDetector.veWillInferAnyFor(ast)) {
|
3635 | node = ts26.createElementAccess(tsCastToAny(receiver), key);
|
3636 | } else {
|
3637 | const expr = ts26.createElementAccess(ts26.createNonNullExpression(receiver), key);
|
3638 | addParseSpanInfo(expr, ast.sourceSpan);
|
3639 | node = tsCastToAny(expr);
|
3640 | }
|
3641 | addParseSpanInfo(node, ast.sourceSpan);
|
3642 | return node;
|
3643 | }
|
3644 | visitCall(ast) {
|
3645 | const args = ast.args.map((expr2) => this.translate(expr2));
|
3646 | let expr;
|
3647 | const receiver = ast.receiver;
|
3648 | if (receiver instanceof PropertyRead3) {
|
3649 | const resolved = this.maybeResolve(receiver);
|
3650 | if (resolved !== null) {
|
3651 | expr = resolved;
|
3652 | } else {
|
3653 | const propertyReceiver = wrapForDiagnostics(this.translate(receiver.receiver));
|
3654 | expr = ts26.createPropertyAccess(propertyReceiver, receiver.name);
|
3655 | addParseSpanInfo(expr, receiver.nameSpan);
|
3656 | }
|
3657 | } else {
|
3658 | expr = this.translate(receiver);
|
3659 | }
|
3660 | let node;
|
3661 | if (ast.receiver instanceof SafePropertyRead2 || ast.receiver instanceof SafeKeyedRead) {
|
3662 | node = this.convertToSafeCall(ast, expr, args);
|
3663 | } else {
|
3664 | node = ts26.createCall(expr, void 0, args);
|
3665 | }
|
3666 | addParseSpanInfo(node, ast.sourceSpan);
|
3667 | return node;
|
3668 | }
|
3669 | visitSafeCall(ast) {
|
3670 | const args = ast.args.map((expr2) => this.translate(expr2));
|
3671 | const expr = wrapForDiagnostics(this.translate(ast.receiver));
|
3672 | const node = this.convertToSafeCall(ast, expr, args);
|
3673 | addParseSpanInfo(node, ast.sourceSpan);
|
3674 | return node;
|
3675 | }
|
3676 | convertToSafeCall(ast, expr, args) {
|
3677 | if (this.config.strictSafeNavigationTypes) {
|
3678 | const call = ts26.createCall(ts26.createNonNullExpression(expr), void 0, args);
|
3679 | return ts26.createParen(ts26.createConditional(NULL_AS_ANY, call, UNDEFINED));
|
3680 | }
|
3681 | if (VeSafeLhsInferenceBugDetector.veWillInferAnyFor(ast)) {
|
3682 | return ts26.createCall(tsCastToAny(expr), void 0, args);
|
3683 | }
|
3684 | return tsCastToAny(ts26.createCall(ts26.createNonNullExpression(expr), void 0, args));
|
3685 | }
|
3686 | };
|
3687 | var VeSafeLhsInferenceBugDetector = class {
|
3688 | static veWillInferAnyFor(ast) {
|
3689 | const visitor = VeSafeLhsInferenceBugDetector.SINGLETON;
|
3690 | return ast instanceof Call ? ast.visit(visitor) : ast.receiver.visit(visitor);
|
3691 | }
|
3692 | visitUnary(ast) {
|
3693 | return ast.expr.visit(this);
|
3694 | }
|
3695 | visitBinary(ast) {
|
3696 | return ast.left.visit(this) || ast.right.visit(this);
|
3697 | }
|
3698 | visitChain(ast) {
|
3699 | return false;
|
3700 | }
|
3701 | visitConditional(ast) {
|
3702 | return ast.condition.visit(this) || ast.trueExp.visit(this) || ast.falseExp.visit(this);
|
3703 | }
|
3704 | visitCall(ast) {
|
3705 | return true;
|
3706 | }
|
3707 | visitSafeCall(ast) {
|
3708 | return false;
|
3709 | }
|
3710 | visitImplicitReceiver(ast) {
|
3711 | return false;
|
3712 | }
|
3713 | visitThisReceiver(ast) {
|
3714 | return false;
|
3715 | }
|
3716 | visitInterpolation(ast) {
|
3717 | return ast.expressions.some((exp) => exp.visit(this));
|
3718 | }
|
3719 | visitKeyedRead(ast) {
|
3720 | return false;
|
3721 | }
|
3722 | visitKeyedWrite(ast) {
|
3723 | return false;
|
3724 | }
|
3725 | visitLiteralArray(ast) {
|
3726 | return true;
|
3727 | }
|
3728 | visitLiteralMap(ast) {
|
3729 | return true;
|
3730 | }
|
3731 | visitLiteralPrimitive(ast) {
|
3732 | return false;
|
3733 | }
|
3734 | visitPipe(ast) {
|
3735 | return true;
|
3736 | }
|
3737 | visitPrefixNot(ast) {
|
3738 | return ast.expression.visit(this);
|
3739 | }
|
3740 | visitNonNullAssert(ast) {
|
3741 | return ast.expression.visit(this);
|
3742 | }
|
3743 | visitPropertyRead(ast) {
|
3744 | return false;
|
3745 | }
|
3746 | visitPropertyWrite(ast) {
|
3747 | return false;
|
3748 | }
|
3749 | visitQuote(ast) {
|
3750 | return false;
|
3751 | }
|
3752 | visitSafePropertyRead(ast) {
|
3753 | return false;
|
3754 | }
|
3755 | visitSafeKeyedRead(ast) {
|
3756 | return false;
|
3757 | }
|
3758 | };
|
3759 | VeSafeLhsInferenceBugDetector.SINGLETON = new VeSafeLhsInferenceBugDetector();
|
3760 |
|
3761 |
|
3762 | import { ImplicitReceiver as ImplicitReceiver3, RecursiveAstVisitor as RecursiveAstVisitor2, TmplAstVariable } from "@angular/compiler";
|
3763 | var ExpressionSemanticVisitor = class extends RecursiveAstVisitor2 {
|
3764 | constructor(templateId, boundTarget, oob) {
|
3765 | super();
|
3766 | this.templateId = templateId;
|
3767 | this.boundTarget = boundTarget;
|
3768 | this.oob = oob;
|
3769 | }
|
3770 | visitPropertyWrite(ast, context) {
|
3771 | super.visitPropertyWrite(ast, context);
|
3772 | if (!(ast.receiver instanceof ImplicitReceiver3)) {
|
3773 | return;
|
3774 | }
|
3775 | const target = this.boundTarget.getExpressionTarget(ast);
|
3776 | if (target instanceof TmplAstVariable) {
|
3777 | this.oob.illegalAssignmentToTemplateVar(this.templateId, ast, target);
|
3778 | }
|
3779 | }
|
3780 | static visit(ast, id, boundTarget, oob) {
|
3781 | ast.visit(new ExpressionSemanticVisitor(id, boundTarget, oob));
|
3782 | }
|
3783 | };
|
3784 |
|
3785 |
|
3786 | var TcbGenericContextBehavior;
|
3787 | (function(TcbGenericContextBehavior2) {
|
3788 | TcbGenericContextBehavior2[TcbGenericContextBehavior2["UseEmitter"] = 0] = "UseEmitter";
|
3789 | TcbGenericContextBehavior2[TcbGenericContextBehavior2["CopyClassNodes"] = 1] = "CopyClassNodes";
|
3790 | TcbGenericContextBehavior2[TcbGenericContextBehavior2["FallbackToAny"] = 2] = "FallbackToAny";
|
3791 | })(TcbGenericContextBehavior || (TcbGenericContextBehavior = {}));
|
3792 | function generateTypeCheckBlock(env, ref, name, meta, domSchemaChecker, oobRecorder, genericContextBehavior) {
|
3793 | const tcb = new Context(env, domSchemaChecker, oobRecorder, meta.id, meta.boundTarget, meta.pipes, meta.schemas);
|
3794 | const scope = Scope.forNodes(tcb, null, tcb.boundTarget.target.template, null);
|
3795 | const ctxRawType = env.referenceType(ref);
|
3796 | if (!ts27.isTypeReferenceNode(ctxRawType)) {
|
3797 | throw new Error(`Expected TypeReferenceNode when referencing the ctx param for ${ref.debugName}`);
|
3798 | }
|
3799 | let typeParameters = void 0;
|
3800 | let typeArguments = void 0;
|
3801 | if (ref.node.typeParameters !== void 0) {
|
3802 | if (!env.config.useContextGenericType) {
|
3803 | genericContextBehavior = TcbGenericContextBehavior.FallbackToAny;
|
3804 | }
|
3805 | switch (genericContextBehavior) {
|
3806 | case TcbGenericContextBehavior.UseEmitter:
|
3807 | typeParameters = new TypeParameterEmitter(ref.node.typeParameters, env.reflector).emit((typeRef) => env.referenceType(typeRef));
|
3808 | typeArguments = typeParameters.map((param) => ts27.factory.createTypeReferenceNode(param.name));
|
3809 | break;
|
3810 | case TcbGenericContextBehavior.CopyClassNodes:
|
3811 | typeParameters = [...ref.node.typeParameters];
|
3812 | typeArguments = typeParameters.map((param) => ts27.factory.createTypeReferenceNode(param.name));
|
3813 | break;
|
3814 | case TcbGenericContextBehavior.FallbackToAny:
|
3815 | typeArguments = ref.node.typeParameters.map(() => ts27.factory.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword));
|
3816 | break;
|
3817 | }
|
3818 | }
|
3819 | const paramList = [tcbCtxParam(ref.node, ctxRawType.typeName, typeArguments)];
|
3820 | const scopeStatements = scope.render();
|
3821 | const innerBody = ts27.createBlock([
|
3822 | ...env.getPreludeStatements(),
|
3823 | ...scopeStatements
|
3824 | ]);
|
3825 | const body = ts27.createBlock([ts27.createIf(ts27.createTrue(), innerBody, void 0)]);
|
3826 | const fnDecl = ts27.createFunctionDeclaration(void 0, void 0, void 0, name, env.config.useContextGenericType ? typeParameters : void 0, paramList, void 0, body);
|
3827 | addTemplateId(fnDecl, meta.id);
|
3828 | return fnDecl;
|
3829 | }
|
3830 | var TcbOp = class {
|
3831 | circularFallback() {
|
3832 | return INFER_TYPE_FOR_CIRCULAR_OP_EXPR;
|
3833 | }
|
3834 | };
|
3835 | var TcbElementOp = class extends TcbOp {
|
3836 | constructor(tcb, scope, element) {
|
3837 | super();
|
3838 | this.tcb = tcb;
|
3839 | this.scope = scope;
|
3840 | this.element = element;
|
3841 | }
|
3842 | get optional() {
|
3843 | return true;
|
3844 | }
|
3845 | execute() {
|
3846 | const id = this.tcb.allocateId();
|
3847 | const initializer = tsCreateElement(this.element.name);
|
3848 | addParseSpanInfo(initializer, this.element.startSourceSpan || this.element.sourceSpan);
|
3849 | this.scope.addStatement(tsCreateVariable(id, initializer));
|
3850 | return id;
|
3851 | }
|
3852 | };
|
3853 | var TcbVariableOp = class extends TcbOp {
|
3854 | constructor(tcb, scope, template, variable) {
|
3855 | super();
|
3856 | this.tcb = tcb;
|
3857 | this.scope = scope;
|
3858 | this.template = template;
|
3859 | this.variable = variable;
|
3860 | }
|
3861 | get optional() {
|
3862 | return false;
|
3863 | }
|
3864 | execute() {
|
3865 | const ctx = this.scope.resolve(this.template);
|
3866 | const id = this.tcb.allocateId();
|
3867 | const initializer = ts27.createPropertyAccess(ctx, this.variable.value || "$implicit");
|
3868 | addParseSpanInfo(id, this.variable.keySpan);
|
3869 | let variable;
|
3870 | if (this.variable.valueSpan !== void 0) {
|
3871 | addParseSpanInfo(initializer, this.variable.valueSpan);
|
3872 | variable = tsCreateVariable(id, wrapForTypeChecker(initializer));
|
3873 | } else {
|
3874 | variable = tsCreateVariable(id, initializer);
|
3875 | }
|
3876 | addParseSpanInfo(variable.declarationList.declarations[0], this.variable.sourceSpan);
|
3877 | this.scope.addStatement(variable);
|
3878 | return id;
|
3879 | }
|
3880 | };
|
3881 | var TcbTemplateContextOp = class extends TcbOp {
|
3882 | constructor(tcb, scope) {
|
3883 | super();
|
3884 | this.tcb = tcb;
|
3885 | this.scope = scope;
|
3886 | this.optional = true;
|
3887 | }
|
3888 | execute() {
|
3889 | const ctx = this.tcb.allocateId();
|
3890 | const type = ts27.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword);
|
3891 | this.scope.addStatement(tsDeclareVariable(ctx, type));
|
3892 | return ctx;
|
3893 | }
|
3894 | };
|
3895 | var TcbTemplateBodyOp = class extends TcbOp {
|
3896 | constructor(tcb, scope, template) {
|
3897 | super();
|
3898 | this.tcb = tcb;
|
3899 | this.scope = scope;
|
3900 | this.template = template;
|
3901 | }
|
3902 | get optional() {
|
3903 | return false;
|
3904 | }
|
3905 | execute() {
|
3906 | const directiveGuards = [];
|
3907 | const directives = this.tcb.boundTarget.getDirectivesOfNode(this.template);
|
3908 | if (directives !== null) {
|
3909 | for (const dir of directives) {
|
3910 | const dirInstId = this.scope.resolve(this.template, dir);
|
3911 | const dirId = this.tcb.env.reference(dir.ref);
|
3912 | dir.ngTemplateGuards.forEach((guard2) => {
|
3913 | const boundInput = this.template.inputs.find((i) => i.name === guard2.inputName) || this.template.templateAttrs.find((i) => i instanceof TmplAstBoundAttribute && i.name === guard2.inputName);
|
3914 | if (boundInput !== void 0) {
|
3915 | const expr = tcbExpression(boundInput.value, this.tcb, this.scope);
|
3916 | markIgnoreDiagnostics(expr);
|
3917 | if (guard2.type === "binding") {
|
3918 | directiveGuards.push(expr);
|
3919 | } else {
|
3920 | const guardInvoke = tsCallMethod(dirId, `ngTemplateGuard_${guard2.inputName}`, [
|
3921 | dirInstId,
|
3922 | expr
|
3923 | ]);
|
3924 | addParseSpanInfo(guardInvoke, boundInput.value.sourceSpan);
|
3925 | directiveGuards.push(guardInvoke);
|
3926 | }
|
3927 | }
|
3928 | });
|
3929 | if (dir.hasNgTemplateContextGuard) {
|
3930 | if (this.tcb.env.config.applyTemplateContextGuards) {
|
3931 | const ctx = this.scope.resolve(this.template);
|
3932 | const guardInvoke = tsCallMethod(dirId, "ngTemplateContextGuard", [dirInstId, ctx]);
|
3933 | addParseSpanInfo(guardInvoke, this.template.sourceSpan);
|
3934 | directiveGuards.push(guardInvoke);
|
3935 | } else if (this.template.variables.length > 0 && this.tcb.env.config.suggestionsForSuboptimalTypeInference) {
|
3936 | this.tcb.oobRecorder.suboptimalTypeInference(this.tcb.id, this.template.variables);
|
3937 | }
|
3938 | }
|
3939 | }
|
3940 | }
|
3941 | let guard = null;
|
3942 | if (directiveGuards.length > 0) {
|
3943 | guard = directiveGuards.reduce((expr, dirGuard) => ts27.createBinary(expr, ts27.SyntaxKind.AmpersandAmpersandToken, dirGuard), directiveGuards.pop());
|
3944 | }
|
3945 | const tmplScope = Scope.forNodes(this.tcb, this.scope, this.template, guard);
|
3946 | const statements = tmplScope.render();
|
3947 | if (statements.length === 0) {
|
3948 | return null;
|
3949 | }
|
3950 | let tmplBlock = ts27.createBlock(statements);
|
3951 | if (guard !== null) {
|
3952 | tmplBlock = ts27.createIf(guard, tmplBlock);
|
3953 | }
|
3954 | this.scope.addStatement(tmplBlock);
|
3955 | return null;
|
3956 | }
|
3957 | };
|
3958 | var TcbTextInterpolationOp = class extends TcbOp {
|
3959 | constructor(tcb, scope, binding) {
|
3960 | super();
|
3961 | this.tcb = tcb;
|
3962 | this.scope = scope;
|
3963 | this.binding = binding;
|
3964 | }
|
3965 | get optional() {
|
3966 | return false;
|
3967 | }
|
3968 | execute() {
|
3969 | const expr = tcbExpression(this.binding.value, this.tcb, this.scope);
|
3970 | this.scope.addStatement(ts27.createExpressionStatement(expr));
|
3971 | return null;
|
3972 | }
|
3973 | };
|
3974 | var TcbDirectiveTypeOpBase = class extends TcbOp {
|
3975 | constructor(tcb, scope, node, dir) {
|
3976 | super();
|
3977 | this.tcb = tcb;
|
3978 | this.scope = scope;
|
3979 | this.node = node;
|
3980 | this.dir = dir;
|
3981 | }
|
3982 | get optional() {
|
3983 | return true;
|
3984 | }
|
3985 | execute() {
|
3986 | const dirRef = this.dir.ref;
|
3987 | const rawType = this.tcb.env.referenceType(this.dir.ref);
|
3988 | let type;
|
3989 | if (this.dir.isGeneric === false || dirRef.node.typeParameters === void 0) {
|
3990 | type = rawType;
|
3991 | } else {
|
3992 | if (!ts27.isTypeReferenceNode(rawType)) {
|
3993 | throw new Error(`Expected TypeReferenceNode when referencing the type for ${this.dir.ref.debugName}`);
|
3994 | }
|
3995 | const typeArguments = dirRef.node.typeParameters.map(() => ts27.factory.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword));
|
3996 | type = ts27.factory.createTypeReferenceNode(rawType.typeName, typeArguments);
|
3997 | }
|
3998 | const id = this.tcb.allocateId();
|
3999 | addExpressionIdentifier(type, ExpressionIdentifier.DIRECTIVE);
|
4000 | addParseSpanInfo(type, this.node.startSourceSpan || this.node.sourceSpan);
|
4001 | this.scope.addStatement(tsDeclareVariable(id, type));
|
4002 | return id;
|
4003 | }
|
4004 | };
|
4005 | var TcbNonGenericDirectiveTypeOp = class extends TcbDirectiveTypeOpBase {
|
4006 | execute() {
|
4007 | const dirRef = this.dir.ref;
|
4008 | if (this.dir.isGeneric) {
|
4009 | throw new Error(`Assertion Error: expected ${dirRef.debugName} not to be generic.`);
|
4010 | }
|
4011 | return super.execute();
|
4012 | }
|
4013 | };
|
4014 | var TcbGenericDirectiveTypeWithAnyParamsOp = class extends TcbDirectiveTypeOpBase {
|
4015 | execute() {
|
4016 | const dirRef = this.dir.ref;
|
4017 | if (dirRef.node.typeParameters === void 0) {
|
4018 | throw new Error(`Assertion Error: expected typeParameters when creating a declaration for ${dirRef.debugName}`);
|
4019 | }
|
4020 | return super.execute();
|
4021 | }
|
4022 | };
|
4023 | var TcbReferenceOp = class extends TcbOp {
|
4024 | constructor(tcb, scope, node, host, target) {
|
4025 | super();
|
4026 | this.tcb = tcb;
|
4027 | this.scope = scope;
|
4028 | this.node = node;
|
4029 | this.host = host;
|
4030 | this.target = target;
|
4031 | this.optional = true;
|
4032 | }
|
4033 | execute() {
|
4034 | const id = this.tcb.allocateId();
|
4035 | let initializer = this.target instanceof TmplAstTemplate2 || this.target instanceof TmplAstElement3 ? this.scope.resolve(this.target) : this.scope.resolve(this.host, this.target);
|
4036 | if (this.target instanceof TmplAstElement3 && !this.tcb.env.config.checkTypeOfDomReferences || !this.tcb.env.config.checkTypeOfNonDomReferences) {
|
4037 | initializer = ts27.createAsExpression(initializer, ts27.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword));
|
4038 | } else if (this.target instanceof TmplAstTemplate2) {
|
4039 | initializer = ts27.createAsExpression(initializer, ts27.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword));
|
4040 | initializer = ts27.createAsExpression(initializer, this.tcb.env.referenceExternalType("@angular/core", "TemplateRef", [DYNAMIC_TYPE]));
|
4041 | initializer = ts27.createParen(initializer);
|
4042 | }
|
4043 | addParseSpanInfo(initializer, this.node.sourceSpan);
|
4044 | addParseSpanInfo(id, this.node.keySpan);
|
4045 | this.scope.addStatement(tsCreateVariable(id, initializer));
|
4046 | return id;
|
4047 | }
|
4048 | };
|
4049 | var TcbInvalidReferenceOp = class extends TcbOp {
|
4050 | constructor(tcb, scope) {
|
4051 | super();
|
4052 | this.tcb = tcb;
|
4053 | this.scope = scope;
|
4054 | this.optional = true;
|
4055 | }
|
4056 | execute() {
|
4057 | const id = this.tcb.allocateId();
|
4058 | this.scope.addStatement(tsCreateVariable(id, NULL_AS_ANY));
|
4059 | return id;
|
4060 | }
|
4061 | };
|
4062 | var TcbDirectiveCtorOp = class extends TcbOp {
|
4063 | constructor(tcb, scope, node, dir) {
|
4064 | super();
|
4065 | this.tcb = tcb;
|
4066 | this.scope = scope;
|
4067 | this.node = node;
|
4068 | this.dir = dir;
|
4069 | }
|
4070 | get optional() {
|
4071 | return true;
|
4072 | }
|
4073 | execute() {
|
4074 | const id = this.tcb.allocateId();
|
4075 | addExpressionIdentifier(id, ExpressionIdentifier.DIRECTIVE);
|
4076 | addParseSpanInfo(id, this.node.startSourceSpan || this.node.sourceSpan);
|
4077 | const genericInputs = new Map();
|
4078 | const inputs = getBoundInputs(this.dir, this.node, this.tcb);
|
4079 | for (const input of inputs) {
|
4080 | if (!this.tcb.env.config.checkTypeOfAttributes && input.attribute instanceof TmplAstTextAttribute2) {
|
4081 | continue;
|
4082 | }
|
4083 | for (const fieldName of input.fieldNames) {
|
4084 | if (genericInputs.has(fieldName)) {
|
4085 | continue;
|
4086 | }
|
4087 | const expression = translateInput(input.attribute, this.tcb, this.scope);
|
4088 | genericInputs.set(fieldName, {
|
4089 | type: "binding",
|
4090 | field: fieldName,
|
4091 | expression,
|
4092 | sourceSpan: input.attribute.sourceSpan
|
4093 | });
|
4094 | }
|
4095 | }
|
4096 | for (const [fieldName] of this.dir.inputs) {
|
4097 | if (!genericInputs.has(fieldName)) {
|
4098 | genericInputs.set(fieldName, { type: "unset", field: fieldName });
|
4099 | }
|
4100 | }
|
4101 | const typeCtor = tcbCallTypeCtor(this.dir, this.tcb, Array.from(genericInputs.values()));
|
4102 | markIgnoreDiagnostics(typeCtor);
|
4103 | this.scope.addStatement(tsCreateVariable(id, typeCtor));
|
4104 | return id;
|
4105 | }
|
4106 | circularFallback() {
|
4107 | return new TcbDirectiveCtorCircularFallbackOp(this.tcb, this.scope, this.node, this.dir);
|
4108 | }
|
4109 | };
|
4110 | var TcbDirectiveInputsOp = class extends TcbOp {
|
4111 | constructor(tcb, scope, node, dir) {
|
4112 | super();
|
4113 | this.tcb = tcb;
|
4114 | this.scope = scope;
|
4115 | this.node = node;
|
4116 | this.dir = dir;
|
4117 | }
|
4118 | get optional() {
|
4119 | return false;
|
4120 | }
|
4121 | execute() {
|
4122 | let dirId = null;
|
4123 | const inputs = getBoundInputs(this.dir, this.node, this.tcb);
|
4124 | for (const input of inputs) {
|
4125 | const expr = widenBinding(translateInput(input.attribute, this.tcb, this.scope), this.tcb);
|
4126 | let assignment = wrapForDiagnostics(expr);
|
4127 | for (const fieldName of input.fieldNames) {
|
4128 | let target;
|
4129 | if (this.dir.coercedInputFields.has(fieldName)) {
|
4130 | const dirTypeRef = this.tcb.env.referenceType(this.dir.ref);
|
4131 | if (!ts27.isTypeReferenceNode(dirTypeRef)) {
|
4132 | throw new Error(`Expected TypeReferenceNode from reference to ${this.dir.ref.debugName}`);
|
4133 | }
|
4134 | const id = this.tcb.allocateId();
|
4135 | const type = tsCreateTypeQueryForCoercedInput(dirTypeRef.typeName, fieldName);
|
4136 | this.scope.addStatement(tsDeclareVariable(id, type));
|
4137 | target = id;
|
4138 | } else if (this.dir.undeclaredInputFields.has(fieldName)) {
|
4139 | continue;
|
4140 | } else if (!this.tcb.env.config.honorAccessModifiersForInputBindings && this.dir.restrictedInputFields.has(fieldName)) {
|
4141 | if (dirId === null) {
|
4142 | dirId = this.scope.resolve(this.node, this.dir);
|
4143 | }
|
4144 | const id = this.tcb.allocateId();
|
4145 | const dirTypeRef = this.tcb.env.referenceType(this.dir.ref);
|
4146 | if (!ts27.isTypeReferenceNode(dirTypeRef)) {
|
4147 | throw new Error(`Expected TypeReferenceNode from reference to ${this.dir.ref.debugName}`);
|
4148 | }
|
4149 | const type = ts27.createIndexedAccessTypeNode(ts27.createTypeQueryNode(dirId), ts27.createLiteralTypeNode(ts27.createStringLiteral(fieldName)));
|
4150 | const temp = tsDeclareVariable(id, type);
|
4151 | this.scope.addStatement(temp);
|
4152 | target = id;
|
4153 | } else {
|
4154 | if (dirId === null) {
|
4155 | dirId = this.scope.resolve(this.node, this.dir);
|
4156 | }
|
4157 | target = this.dir.stringLiteralInputFields.has(fieldName) ? ts27.createElementAccess(dirId, ts27.createStringLiteral(fieldName)) : ts27.createPropertyAccess(dirId, ts27.createIdentifier(fieldName));
|
4158 | }
|
4159 | if (input.attribute.keySpan !== void 0) {
|
4160 | addParseSpanInfo(target, input.attribute.keySpan);
|
4161 | }
|
4162 | assignment = ts27.createBinary(target, ts27.SyntaxKind.EqualsToken, assignment);
|
4163 | }
|
4164 | addParseSpanInfo(assignment, input.attribute.sourceSpan);
|
4165 | if (!this.tcb.env.config.checkTypeOfAttributes && input.attribute instanceof TmplAstTextAttribute2) {
|
4166 | markIgnoreDiagnostics(assignment);
|
4167 | }
|
4168 | this.scope.addStatement(ts27.createExpressionStatement(assignment));
|
4169 | }
|
4170 | return null;
|
4171 | }
|
4172 | };
|
4173 | var TcbDirectiveCtorCircularFallbackOp = class extends TcbOp {
|
4174 | constructor(tcb, scope, node, dir) {
|
4175 | super();
|
4176 | this.tcb = tcb;
|
4177 | this.scope = scope;
|
4178 | this.node = node;
|
4179 | this.dir = dir;
|
4180 | }
|
4181 | get optional() {
|
4182 | return false;
|
4183 | }
|
4184 | execute() {
|
4185 | const id = this.tcb.allocateId();
|
4186 | const typeCtor = this.tcb.env.typeCtorFor(this.dir);
|
4187 | const circularPlaceholder = ts27.createCall(typeCtor, void 0, [ts27.createNonNullExpression(ts27.createNull())]);
|
4188 | this.scope.addStatement(tsCreateVariable(id, circularPlaceholder));
|
4189 | return id;
|
4190 | }
|
4191 | };
|
4192 | var TcbDomSchemaCheckerOp = class extends TcbOp {
|
4193 | constructor(tcb, element, checkElement, claimedInputs) {
|
4194 | super();
|
4195 | this.tcb = tcb;
|
4196 | this.element = element;
|
4197 | this.checkElement = checkElement;
|
4198 | this.claimedInputs = claimedInputs;
|
4199 | }
|
4200 | get optional() {
|
4201 | return false;
|
4202 | }
|
4203 | execute() {
|
4204 | if (this.checkElement) {
|
4205 | this.tcb.domSchemaChecker.checkElement(this.tcb.id, this.element, this.tcb.schemas);
|
4206 | }
|
4207 | for (const binding of this.element.inputs) {
|
4208 | if (binding.type === 0 && this.claimedInputs.has(binding.name)) {
|
4209 | continue;
|
4210 | }
|
4211 | if (binding.type === 0) {
|
4212 | if (binding.name !== "style" && binding.name !== "class") {
|
4213 | const propertyName = ATTR_TO_PROP[binding.name] || binding.name;
|
4214 | this.tcb.domSchemaChecker.checkProperty(this.tcb.id, this.element, propertyName, binding.sourceSpan, this.tcb.schemas);
|
4215 | }
|
4216 | }
|
4217 | }
|
4218 | return null;
|
4219 | }
|
4220 | };
|
4221 | var ATTR_TO_PROP = {
|
4222 | "class": "className",
|
4223 | "for": "htmlFor",
|
4224 | "formaction": "formAction",
|
4225 | "innerHtml": "innerHTML",
|
4226 | "readonly": "readOnly",
|
4227 | "tabindex": "tabIndex"
|
4228 | };
|
4229 | var TcbUnclaimedInputsOp = class extends TcbOp {
|
4230 | constructor(tcb, scope, element, claimedInputs) {
|
4231 | super();
|
4232 | this.tcb = tcb;
|
4233 | this.scope = scope;
|
4234 | this.element = element;
|
4235 | this.claimedInputs = claimedInputs;
|
4236 | }
|
4237 | get optional() {
|
4238 | return false;
|
4239 | }
|
4240 | execute() {
|
4241 | let elId = null;
|
4242 | for (const binding of this.element.inputs) {
|
4243 | if (binding.type === 0 && this.claimedInputs.has(binding.name)) {
|
4244 | continue;
|
4245 | }
|
4246 | const expr = widenBinding(tcbExpression(binding.value, this.tcb, this.scope), this.tcb);
|
4247 | if (this.tcb.env.config.checkTypeOfDomBindings && binding.type === 0) {
|
4248 | if (binding.name !== "style" && binding.name !== "class") {
|
4249 | if (elId === null) {
|
4250 | elId = this.scope.resolve(this.element);
|
4251 | }
|
4252 | const propertyName = ATTR_TO_PROP[binding.name] || binding.name;
|
4253 | const prop = ts27.createElementAccess(elId, ts27.createStringLiteral(propertyName));
|
4254 | const stmt = ts27.createBinary(prop, ts27.SyntaxKind.EqualsToken, wrapForDiagnostics(expr));
|
4255 | addParseSpanInfo(stmt, binding.sourceSpan);
|
4256 | this.scope.addStatement(ts27.createExpressionStatement(stmt));
|
4257 | } else {
|
4258 | this.scope.addStatement(ts27.createExpressionStatement(expr));
|
4259 | }
|
4260 | } else {
|
4261 | this.scope.addStatement(ts27.createExpressionStatement(expr));
|
4262 | }
|
4263 | }
|
4264 | return null;
|
4265 | }
|
4266 | };
|
4267 | var TcbDirectiveOutputsOp = class extends TcbOp {
|
4268 | constructor(tcb, scope, node, dir) {
|
4269 | super();
|
4270 | this.tcb = tcb;
|
4271 | this.scope = scope;
|
4272 | this.node = node;
|
4273 | this.dir = dir;
|
4274 | }
|
4275 | get optional() {
|
4276 | return false;
|
4277 | }
|
4278 | execute() {
|
4279 | let dirId = null;
|
4280 | const outputs = this.dir.outputs;
|
4281 | for (const output of this.node.outputs) {
|
4282 | if (output.type !== 0 || !outputs.hasBindingPropertyName(output.name)) {
|
4283 | continue;
|
4284 | }
|
4285 | if (this.tcb.env.config.checkTypeOfOutputEvents && output.name.endsWith("Change")) {
|
4286 | const inputName = output.name.slice(0, -6);
|
4287 | isSplitTwoWayBinding(inputName, output, this.node.inputs, this.tcb);
|
4288 | }
|
4289 | const field = outputs.getByBindingPropertyName(output.name)[0].classPropertyName;
|
4290 | if (dirId === null) {
|
4291 | dirId = this.scope.resolve(this.node, this.dir);
|
4292 | }
|
4293 | const outputField = ts27.createElementAccess(dirId, ts27.createStringLiteral(field));
|
4294 | addParseSpanInfo(outputField, output.keySpan);
|
4295 | if (this.tcb.env.config.checkTypeOfOutputEvents) {
|
4296 | const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 0);
|
4297 | const subscribeFn = ts27.createPropertyAccess(outputField, "subscribe");
|
4298 | const call = ts27.createCall(subscribeFn, void 0, [handler]);
|
4299 | addParseSpanInfo(call, output.sourceSpan);
|
4300 | this.scope.addStatement(ts27.createExpressionStatement(call));
|
4301 | } else {
|
4302 | this.scope.addStatement(ts27.createExpressionStatement(outputField));
|
4303 | const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 1);
|
4304 | this.scope.addStatement(ts27.createExpressionStatement(handler));
|
4305 | }
|
4306 | ExpressionSemanticVisitor.visit(output.handler, this.tcb.id, this.tcb.boundTarget, this.tcb.oobRecorder);
|
4307 | }
|
4308 | return null;
|
4309 | }
|
4310 | };
|
4311 | var TcbUnclaimedOutputsOp = class extends TcbOp {
|
4312 | constructor(tcb, scope, element, claimedOutputs) {
|
4313 | super();
|
4314 | this.tcb = tcb;
|
4315 | this.scope = scope;
|
4316 | this.element = element;
|
4317 | this.claimedOutputs = claimedOutputs;
|
4318 | }
|
4319 | get optional() {
|
4320 | return false;
|
4321 | }
|
4322 | execute() {
|
4323 | let elId = null;
|
4324 | for (const output of this.element.outputs) {
|
4325 | if (this.claimedOutputs.has(output.name)) {
|
4326 | continue;
|
4327 | }
|
4328 | if (this.tcb.env.config.checkTypeOfOutputEvents && output.name.endsWith("Change")) {
|
4329 | const inputName = output.name.slice(0, -6);
|
4330 | if (isSplitTwoWayBinding(inputName, output, this.element.inputs, this.tcb)) {
|
4331 | continue;
|
4332 | }
|
4333 | }
|
4334 | if (output.type === 1) {
|
4335 | const eventType = this.tcb.env.config.checkTypeOfAnimationEvents ? this.tcb.env.referenceExternalType("@angular/animations", "AnimationEvent") : 1;
|
4336 | const handler = tcbCreateEventHandler(output, this.tcb, this.scope, eventType);
|
4337 | this.scope.addStatement(ts27.createExpressionStatement(handler));
|
4338 | } else if (this.tcb.env.config.checkTypeOfDomEvents) {
|
4339 | const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 0);
|
4340 | if (elId === null) {
|
4341 | elId = this.scope.resolve(this.element);
|
4342 | }
|
4343 | const propertyAccess = ts27.createPropertyAccess(elId, "addEventListener");
|
4344 | addParseSpanInfo(propertyAccess, output.keySpan);
|
4345 | const call = ts27.createCall(propertyAccess, void 0, [ts27.createStringLiteral(output.name), handler]);
|
4346 | addParseSpanInfo(call, output.sourceSpan);
|
4347 | this.scope.addStatement(ts27.createExpressionStatement(call));
|
4348 | } else {
|
4349 | const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 1);
|
4350 | this.scope.addStatement(ts27.createExpressionStatement(handler));
|
4351 | }
|
4352 | ExpressionSemanticVisitor.visit(output.handler, this.tcb.id, this.tcb.boundTarget, this.tcb.oobRecorder);
|
4353 | }
|
4354 | return null;
|
4355 | }
|
4356 | };
|
4357 | var TcbComponentContextCompletionOp = class extends TcbOp {
|
4358 | constructor(scope) {
|
4359 | super();
|
4360 | this.scope = scope;
|
4361 | this.optional = false;
|
4362 | }
|
4363 | execute() {
|
4364 | const ctx = ts27.createIdentifier("ctx");
|
4365 | const ctxDot = ts27.createPropertyAccess(ctx, "");
|
4366 | markIgnoreDiagnostics(ctxDot);
|
4367 | addExpressionIdentifier(ctxDot, ExpressionIdentifier.COMPONENT_COMPLETION);
|
4368 | this.scope.addStatement(ts27.createExpressionStatement(ctxDot));
|
4369 | return null;
|
4370 | }
|
4371 | };
|
4372 | var INFER_TYPE_FOR_CIRCULAR_OP_EXPR = ts27.createNonNullExpression(ts27.createNull());
|
4373 | var Context = class {
|
4374 | constructor(env, domSchemaChecker, oobRecorder, id, boundTarget, pipes, schemas) {
|
4375 | this.env = env;
|
4376 | this.domSchemaChecker = domSchemaChecker;
|
4377 | this.oobRecorder = oobRecorder;
|
4378 | this.id = id;
|
4379 | this.boundTarget = boundTarget;
|
4380 | this.pipes = pipes;
|
4381 | this.schemas = schemas;
|
4382 | this.nextId = 1;
|
4383 | }
|
4384 | allocateId() {
|
4385 | return ts27.createIdentifier(`_t${this.nextId++}`);
|
4386 | }
|
4387 | getPipeByName(name) {
|
4388 | if (!this.pipes.has(name)) {
|
4389 | return null;
|
4390 | }
|
4391 | return this.pipes.get(name);
|
4392 | }
|
4393 | };
|
4394 | var Scope = class {
|
4395 | constructor(tcb, parent = null, guard = null) {
|
4396 | this.tcb = tcb;
|
4397 | this.parent = parent;
|
4398 | this.guard = guard;
|
4399 | this.opQueue = [];
|
4400 | this.elementOpMap = new Map();
|
4401 | this.directiveOpMap = new Map();
|
4402 | this.referenceOpMap = new Map();
|
4403 | this.templateCtxOpMap = new Map();
|
4404 | this.varMap = new Map();
|
4405 | this.statements = [];
|
4406 | }
|
4407 | static forNodes(tcb, parent, templateOrNodes, guard) {
|
4408 | const scope = new Scope(tcb, parent, guard);
|
4409 | if (parent === null && tcb.env.config.enableTemplateTypeChecker) {
|
4410 | scope.opQueue.push(new TcbComponentContextCompletionOp(scope));
|
4411 | }
|
4412 | let children;
|
4413 | if (templateOrNodes instanceof TmplAstTemplate2) {
|
4414 | const varMap = new Map();
|
4415 | for (const v of templateOrNodes.variables) {
|
4416 | if (!varMap.has(v.name)) {
|
4417 | varMap.set(v.name, v);
|
4418 | } else {
|
4419 | const firstDecl = varMap.get(v.name);
|
4420 | tcb.oobRecorder.duplicateTemplateVar(tcb.id, v, firstDecl);
|
4421 | }
|
4422 | const opIndex = scope.opQueue.push(new TcbVariableOp(tcb, scope, templateOrNodes, v)) - 1;
|
4423 | scope.varMap.set(v, opIndex);
|
4424 | }
|
4425 | children = templateOrNodes.children;
|
4426 | } else {
|
4427 | children = templateOrNodes;
|
4428 | }
|
4429 | for (const node of children) {
|
4430 | scope.appendNode(node);
|
4431 | }
|
4432 | return scope;
|
4433 | }
|
4434 | resolve(node, directive) {
|
4435 | const res = this.resolveLocal(node, directive);
|
4436 | if (res !== null) {
|
4437 | const clone = ts27.getMutableClone(res);
|
4438 | ts27.setSyntheticTrailingComments(clone, []);
|
4439 | return clone;
|
4440 | } else if (this.parent !== null) {
|
4441 | return this.parent.resolve(node, directive);
|
4442 | } else {
|
4443 | throw new Error(`Could not resolve ${node} / ${directive}`);
|
4444 | }
|
4445 | }
|
4446 | addStatement(stmt) {
|
4447 | this.statements.push(stmt);
|
4448 | }
|
4449 | render() {
|
4450 | for (let i = 0; i < this.opQueue.length; i++) {
|
4451 | const skipOptional = !this.tcb.env.config.enableTemplateTypeChecker;
|
4452 | this.executeOp(i, skipOptional);
|
4453 | }
|
4454 | return this.statements;
|
4455 | }
|
4456 | guards() {
|
4457 | let parentGuards = null;
|
4458 | if (this.parent !== null) {
|
4459 | parentGuards = this.parent.guards();
|
4460 | }
|
4461 | if (this.guard === null) {
|
4462 | return parentGuards;
|
4463 | } else if (parentGuards === null) {
|
4464 | return this.guard;
|
4465 | } else {
|
4466 | return ts27.createBinary(parentGuards, ts27.SyntaxKind.AmpersandAmpersandToken, this.guard);
|
4467 | }
|
4468 | }
|
4469 | resolveLocal(ref, directive) {
|
4470 | if (ref instanceof TmplAstReference3 && this.referenceOpMap.has(ref)) {
|
4471 | return this.resolveOp(this.referenceOpMap.get(ref));
|
4472 | } else if (ref instanceof TmplAstVariable2 && this.varMap.has(ref)) {
|
4473 | return this.resolveOp(this.varMap.get(ref));
|
4474 | } else if (ref instanceof TmplAstTemplate2 && directive === void 0 && this.templateCtxOpMap.has(ref)) {
|
4475 | return this.resolveOp(this.templateCtxOpMap.get(ref));
|
4476 | } else if ((ref instanceof TmplAstElement3 || ref instanceof TmplAstTemplate2) && directive !== void 0 && this.directiveOpMap.has(ref)) {
|
4477 | const dirMap = this.directiveOpMap.get(ref);
|
4478 | if (dirMap.has(directive)) {
|
4479 | return this.resolveOp(dirMap.get(directive));
|
4480 | } else {
|
4481 | return null;
|
4482 | }
|
4483 | } else if (ref instanceof TmplAstElement3 && this.elementOpMap.has(ref)) {
|
4484 | return this.resolveOp(this.elementOpMap.get(ref));
|
4485 | } else {
|
4486 | return null;
|
4487 | }
|
4488 | }
|
4489 | resolveOp(opIndex) {
|
4490 | const res = this.executeOp(opIndex, false);
|
4491 | if (res === null) {
|
4492 | throw new Error(`Error resolving operation, got null`);
|
4493 | }
|
4494 | return res;
|
4495 | }
|
4496 | executeOp(opIndex, skipOptional) {
|
4497 | const op = this.opQueue[opIndex];
|
4498 | if (!(op instanceof TcbOp)) {
|
4499 | return op;
|
4500 | }
|
4501 | if (skipOptional && op.optional) {
|
4502 | return null;
|
4503 | }
|
4504 | this.opQueue[opIndex] = op.circularFallback();
|
4505 | const res = op.execute();
|
4506 | this.opQueue[opIndex] = res;
|
4507 | return res;
|
4508 | }
|
4509 | appendNode(node) {
|
4510 | if (node instanceof TmplAstElement3) {
|
4511 | const opIndex = this.opQueue.push(new TcbElementOp(this.tcb, this, node)) - 1;
|
4512 | this.elementOpMap.set(node, opIndex);
|
4513 | this.appendDirectivesAndInputsOfNode(node);
|
4514 | this.appendOutputsOfNode(node);
|
4515 | for (const child of node.children) {
|
4516 | this.appendNode(child);
|
4517 | }
|
4518 | this.checkAndAppendReferencesOfNode(node);
|
4519 | } else if (node instanceof TmplAstTemplate2) {
|
4520 | this.appendDirectivesAndInputsOfNode(node);
|
4521 | this.appendOutputsOfNode(node);
|
4522 | const ctxIndex = this.opQueue.push(new TcbTemplateContextOp(this.tcb, this)) - 1;
|
4523 | this.templateCtxOpMap.set(node, ctxIndex);
|
4524 | if (this.tcb.env.config.checkTemplateBodies) {
|
4525 | this.opQueue.push(new TcbTemplateBodyOp(this.tcb, this, node));
|
4526 | } else if (this.tcb.env.config.alwaysCheckSchemaInTemplateBodies) {
|
4527 | this.appendDeepSchemaChecks(node.children);
|
4528 | }
|
4529 | this.checkAndAppendReferencesOfNode(node);
|
4530 | } else if (node instanceof TmplAstBoundText) {
|
4531 | this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, node));
|
4532 | } else if (node instanceof TmplAstIcu) {
|
4533 | this.appendIcuExpressions(node);
|
4534 | }
|
4535 | }
|
4536 | checkAndAppendReferencesOfNode(node) {
|
4537 | for (const ref of node.references) {
|
4538 | const target = this.tcb.boundTarget.getReferenceTarget(ref);
|
4539 | let ctxIndex;
|
4540 | if (target === null) {
|
4541 | this.tcb.oobRecorder.missingReferenceTarget(this.tcb.id, ref);
|
4542 | ctxIndex = this.opQueue.push(new TcbInvalidReferenceOp(this.tcb, this)) - 1;
|
4543 | } else if (target instanceof TmplAstTemplate2 || target instanceof TmplAstElement3) {
|
4544 | ctxIndex = this.opQueue.push(new TcbReferenceOp(this.tcb, this, ref, node, target)) - 1;
|
4545 | } else {
|
4546 | ctxIndex = this.opQueue.push(new TcbReferenceOp(this.tcb, this, ref, node, target.directive)) - 1;
|
4547 | }
|
4548 | this.referenceOpMap.set(ref, ctxIndex);
|
4549 | }
|
4550 | }
|
4551 | appendDirectivesAndInputsOfNode(node) {
|
4552 | const claimedInputs = new Set();
|
4553 | const directives = this.tcb.boundTarget.getDirectivesOfNode(node);
|
4554 | if (directives === null || directives.length === 0) {
|
4555 | if (node instanceof TmplAstElement3) {
|
4556 | this.opQueue.push(new TcbUnclaimedInputsOp(this.tcb, this, node, claimedInputs));
|
4557 | this.opQueue.push(new TcbDomSchemaCheckerOp(this.tcb, node, true, claimedInputs));
|
4558 | }
|
4559 | return;
|
4560 | }
|
4561 | const dirMap = new Map();
|
4562 | for (const dir of directives) {
|
4563 | let directiveOp;
|
4564 | const host = this.tcb.env.reflector;
|
4565 | const dirRef = dir.ref;
|
4566 | if (!dir.isGeneric) {
|
4567 | directiveOp = new TcbNonGenericDirectiveTypeOp(this.tcb, this, node, dir);
|
4568 | } else if (!requiresInlineTypeCtor(dirRef.node, host, this.tcb.env) || this.tcb.env.config.useInlineTypeConstructors) {
|
4569 | directiveOp = new TcbDirectiveCtorOp(this.tcb, this, node, dir);
|
4570 | } else {
|
4571 | directiveOp = new TcbGenericDirectiveTypeWithAnyParamsOp(this.tcb, this, node, dir);
|
4572 | }
|
4573 | const dirIndex = this.opQueue.push(directiveOp) - 1;
|
4574 | dirMap.set(dir, dirIndex);
|
4575 | this.opQueue.push(new TcbDirectiveInputsOp(this.tcb, this, node, dir));
|
4576 | }
|
4577 | this.directiveOpMap.set(node, dirMap);
|
4578 | if (node instanceof TmplAstElement3) {
|
4579 | for (const dir of directives) {
|
4580 | for (const propertyName of dir.inputs.propertyNames) {
|
4581 | claimedInputs.add(propertyName);
|
4582 | }
|
4583 | }
|
4584 | this.opQueue.push(new TcbUnclaimedInputsOp(this.tcb, this, node, claimedInputs));
|
4585 | const checkElement = directives.length === 0;
|
4586 | this.opQueue.push(new TcbDomSchemaCheckerOp(this.tcb, node, checkElement, claimedInputs));
|
4587 | }
|
4588 | }
|
4589 | appendOutputsOfNode(node) {
|
4590 | const claimedOutputs = new Set();
|
4591 | const directives = this.tcb.boundTarget.getDirectivesOfNode(node);
|
4592 | if (directives === null || directives.length === 0) {
|
4593 | if (node instanceof TmplAstElement3) {
|
4594 | this.opQueue.push(new TcbUnclaimedOutputsOp(this.tcb, this, node, claimedOutputs));
|
4595 | }
|
4596 | return;
|
4597 | }
|
4598 | for (const dir of directives) {
|
4599 | this.opQueue.push(new TcbDirectiveOutputsOp(this.tcb, this, node, dir));
|
4600 | }
|
4601 | if (node instanceof TmplAstElement3) {
|
4602 | for (const dir of directives) {
|
4603 | for (const outputProperty of dir.outputs.propertyNames) {
|
4604 | claimedOutputs.add(outputProperty);
|
4605 | }
|
4606 | }
|
4607 | this.opQueue.push(new TcbUnclaimedOutputsOp(this.tcb, this, node, claimedOutputs));
|
4608 | }
|
4609 | }
|
4610 | appendDeepSchemaChecks(nodes) {
|
4611 | for (const node of nodes) {
|
4612 | if (!(node instanceof TmplAstElement3 || node instanceof TmplAstTemplate2)) {
|
4613 | continue;
|
4614 | }
|
4615 | if (node instanceof TmplAstElement3) {
|
4616 | const claimedInputs = new Set();
|
4617 | const directives = this.tcb.boundTarget.getDirectivesOfNode(node);
|
4618 | let hasDirectives;
|
4619 | if (directives === null || directives.length === 0) {
|
4620 | hasDirectives = false;
|
4621 | } else {
|
4622 | hasDirectives = true;
|
4623 | for (const dir of directives) {
|
4624 | for (const propertyName of dir.inputs.propertyNames) {
|
4625 | claimedInputs.add(propertyName);
|
4626 | }
|
4627 | }
|
4628 | }
|
4629 | this.opQueue.push(new TcbDomSchemaCheckerOp(this.tcb, node, !hasDirectives, claimedInputs));
|
4630 | }
|
4631 | this.appendDeepSchemaChecks(node.children);
|
4632 | }
|
4633 | }
|
4634 | appendIcuExpressions(node) {
|
4635 | for (const variable of Object.values(node.vars)) {
|
4636 | this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, variable));
|
4637 | }
|
4638 | for (const placeholder of Object.values(node.placeholders)) {
|
4639 | if (placeholder instanceof TmplAstBoundText) {
|
4640 | this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, placeholder));
|
4641 | }
|
4642 | }
|
4643 | }
|
4644 | };
|
4645 | function tcbCtxParam(node, name, typeArguments) {
|
4646 | const type = ts27.factory.createTypeReferenceNode(name, typeArguments);
|
4647 | return ts27.factory.createParameterDeclaration(void 0, void 0, void 0, "ctx", void 0, type, void 0);
|
4648 | }
|
4649 | function tcbExpression(ast, tcb, scope) {
|
4650 | const translator = new TcbExpressionTranslator(tcb, scope);
|
4651 | return translator.translate(ast);
|
4652 | }
|
4653 | var TcbExpressionTranslator = class {
|
4654 | constructor(tcb, scope) {
|
4655 | this.tcb = tcb;
|
4656 | this.scope = scope;
|
4657 | }
|
4658 | translate(ast) {
|
4659 | return astToTypescript(ast, (ast2) => this.resolve(ast2), this.tcb.env.config);
|
4660 | }
|
4661 | resolve(ast) {
|
4662 | if (ast instanceof PropertyRead4 && ast.receiver instanceof ImplicitReceiver4) {
|
4663 | return this.resolveTarget(ast);
|
4664 | } else if (ast instanceof PropertyWrite3 && ast.receiver instanceof ImplicitReceiver4) {
|
4665 | const target = this.resolveTarget(ast);
|
4666 | if (target === null) {
|
4667 | return null;
|
4668 | }
|
4669 | const expr = this.translate(ast.value);
|
4670 | const result = ts27.createParen(ts27.createBinary(target, ts27.SyntaxKind.EqualsToken, expr));
|
4671 | addParseSpanInfo(result, ast.sourceSpan);
|
4672 | return result;
|
4673 | } else if (ast instanceof ImplicitReceiver4) {
|
4674 | return ts27.createIdentifier("ctx");
|
4675 | } else if (ast instanceof BindingPipe) {
|
4676 | const expr = this.translate(ast.exp);
|
4677 | const pipeRef = this.tcb.getPipeByName(ast.name);
|
4678 | let pipe;
|
4679 | if (pipeRef === null) {
|
4680 | this.tcb.oobRecorder.missingPipe(this.tcb.id, ast);
|
4681 | pipe = NULL_AS_ANY;
|
4682 | } else {
|
4683 | pipe = this.tcb.env.pipeInst(pipeRef);
|
4684 | }
|
4685 | const args = ast.args.map((arg) => this.translate(arg));
|
4686 | let methodAccess = ts27.factory.createPropertyAccessExpression(pipe, "transform");
|
4687 | addParseSpanInfo(methodAccess, ast.nameSpan);
|
4688 | if (!this.tcb.env.config.checkTypeOfPipes) {
|
4689 | methodAccess = ts27.factory.createAsExpression(methodAccess, ts27.factory.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword));
|
4690 | }
|
4691 | const result = ts27.createCall(methodAccess, void 0, [expr, ...args]);
|
4692 | addParseSpanInfo(result, ast.sourceSpan);
|
4693 | return result;
|
4694 | } else if ((ast instanceof Call2 || ast instanceof SafeCall) && (ast.receiver instanceof PropertyRead4 || ast.receiver instanceof SafePropertyRead3)) {
|
4695 | if (ast.receiver.receiver instanceof ImplicitReceiver4 && !(ast.receiver.receiver instanceof ThisReceiver) && ast.receiver.name === "$any" && ast.args.length === 1) {
|
4696 | const expr = this.translate(ast.args[0]);
|
4697 | const exprAsAny = ts27.createAsExpression(expr, ts27.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword));
|
4698 | const result = ts27.createParen(exprAsAny);
|
4699 | addParseSpanInfo(result, ast.sourceSpan);
|
4700 | return result;
|
4701 | }
|
4702 | const receiver = this.resolveTarget(ast);
|
4703 | if (receiver === null) {
|
4704 | return null;
|
4705 | }
|
4706 | const method = wrapForDiagnostics(receiver);
|
4707 | addParseSpanInfo(method, ast.receiver.nameSpan);
|
4708 | const args = ast.args.map((arg) => this.translate(arg));
|
4709 | const node = ts27.createCall(method, void 0, args);
|
4710 | addParseSpanInfo(node, ast.sourceSpan);
|
4711 | return node;
|
4712 | } else {
|
4713 | return null;
|
4714 | }
|
4715 | }
|
4716 | resolveTarget(ast) {
|
4717 | const binding = this.tcb.boundTarget.getExpressionTarget(ast);
|
4718 | if (binding === null) {
|
4719 | return null;
|
4720 | }
|
4721 | const expr = this.scope.resolve(binding);
|
4722 | addParseSpanInfo(expr, ast.sourceSpan);
|
4723 | return expr;
|
4724 | }
|
4725 | };
|
4726 | function tcbCallTypeCtor(dir, tcb, inputs) {
|
4727 | const typeCtor = tcb.env.typeCtorFor(dir);
|
4728 | const members = inputs.map((input) => {
|
4729 | const propertyName = ts27.createStringLiteral(input.field);
|
4730 | if (input.type === "binding") {
|
4731 | const expr = widenBinding(input.expression, tcb);
|
4732 | const assignment = ts27.createPropertyAssignment(propertyName, wrapForDiagnostics(expr));
|
4733 | addParseSpanInfo(assignment, input.sourceSpan);
|
4734 | return assignment;
|
4735 | } else {
|
4736 | return ts27.createPropertyAssignment(propertyName, NULL_AS_ANY);
|
4737 | }
|
4738 | });
|
4739 | return ts27.createCall(typeCtor, void 0, [ts27.createObjectLiteral(members)]);
|
4740 | }
|
4741 | function getBoundInputs(directive, node, tcb) {
|
4742 | const boundInputs = [];
|
4743 | const processAttribute = (attr) => {
|
4744 | if (attr instanceof TmplAstBoundAttribute && attr.type !== 0) {
|
4745 | return;
|
4746 | }
|
4747 | const inputs = directive.inputs.getByBindingPropertyName(attr.name);
|
4748 | if (inputs === null) {
|
4749 | return;
|
4750 | }
|
4751 | const fieldNames = inputs.map((input) => input.classPropertyName);
|
4752 | boundInputs.push({ attribute: attr, fieldNames });
|
4753 | };
|
4754 | node.inputs.forEach(processAttribute);
|
4755 | node.attributes.forEach(processAttribute);
|
4756 | if (node instanceof TmplAstTemplate2) {
|
4757 | node.templateAttrs.forEach(processAttribute);
|
4758 | }
|
4759 | return boundInputs;
|
4760 | }
|
4761 | function translateInput(attr, tcb, scope) {
|
4762 | if (attr instanceof TmplAstBoundAttribute) {
|
4763 | return tcbExpression(attr.value, tcb, scope);
|
4764 | } else {
|
4765 | return ts27.createStringLiteral(attr.value);
|
4766 | }
|
4767 | }
|
4768 | function widenBinding(expr, tcb) {
|
4769 | if (!tcb.env.config.checkTypeOfInputBindings) {
|
4770 | return tsCastToAny(expr);
|
4771 | } else if (!tcb.env.config.strictNullInputBindings) {
|
4772 | if (ts27.isObjectLiteralExpression(expr) || ts27.isArrayLiteralExpression(expr)) {
|
4773 | return expr;
|
4774 | } else {
|
4775 | return ts27.createNonNullExpression(expr);
|
4776 | }
|
4777 | } else {
|
4778 | return expr;
|
4779 | }
|
4780 | }
|
4781 | var EVENT_PARAMETER = "$event";
|
4782 | function tcbCreateEventHandler(event, tcb, scope, eventType) {
|
4783 | const handler = tcbEventHandlerExpression(event.handler, tcb, scope);
|
4784 | let eventParamType;
|
4785 | if (eventType === 0) {
|
4786 | eventParamType = void 0;
|
4787 | } else if (eventType === 1) {
|
4788 | eventParamType = ts27.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword);
|
4789 | } else {
|
4790 | eventParamType = eventType;
|
4791 | }
|
4792 | const guards = scope.guards();
|
4793 | let body = ts27.createExpressionStatement(handler);
|
4794 | if (guards !== null) {
|
4795 | body = ts27.createIf(guards, body);
|
4796 | }
|
4797 | const eventParam = ts27.createParameter(void 0, void 0, void 0, EVENT_PARAMETER, void 0, eventParamType);
|
4798 | addExpressionIdentifier(eventParam, ExpressionIdentifier.EVENT_PARAMETER);
|
4799 | return ts27.createFunctionExpression(void 0, void 0, void 0, void 0, [eventParam], ts27.createKeywordTypeNode(ts27.SyntaxKind.AnyKeyword), ts27.createBlock([body]));
|
4800 | }
|
4801 | function tcbEventHandlerExpression(ast, tcb, scope) {
|
4802 | const translator = new TcbEventHandlerTranslator(tcb, scope);
|
4803 | return translator.translate(ast);
|
4804 | }
|
4805 | function isSplitTwoWayBinding(inputName, output, inputs, tcb) {
|
4806 | const input = inputs.find((input2) => input2.name === inputName);
|
4807 | if (input === void 0 || input.sourceSpan !== output.sourceSpan) {
|
4808 | return false;
|
4809 | }
|
4810 | const inputConsumer = tcb.boundTarget.getConsumerOfBinding(input);
|
4811 | const outputConsumer = tcb.boundTarget.getConsumerOfBinding(output);
|
4812 | if (outputConsumer === null || inputConsumer.ref === void 0 || outputConsumer instanceof TmplAstTemplate2) {
|
4813 | return false;
|
4814 | }
|
4815 | if (outputConsumer instanceof TmplAstElement3) {
|
4816 | tcb.oobRecorder.splitTwoWayBinding(tcb.id, input, output, inputConsumer.ref.node, outputConsumer);
|
4817 | return true;
|
4818 | } else if (outputConsumer.ref !== inputConsumer.ref) {
|
4819 | tcb.oobRecorder.splitTwoWayBinding(tcb.id, input, output, inputConsumer.ref.node, outputConsumer.ref.node);
|
4820 | return true;
|
4821 | }
|
4822 | return false;
|
4823 | }
|
4824 | var TcbEventHandlerTranslator = class extends TcbExpressionTranslator {
|
4825 | resolve(ast) {
|
4826 | if (ast instanceof PropertyRead4 && ast.receiver instanceof ImplicitReceiver4 && !(ast.receiver instanceof ThisReceiver) && ast.name === EVENT_PARAMETER) {
|
4827 | const event = ts27.createIdentifier(EVENT_PARAMETER);
|
4828 | addParseSpanInfo(event, ast.nameSpan);
|
4829 | return event;
|
4830 | }
|
4831 | return super.resolve(ast);
|
4832 | }
|
4833 | };
|
4834 |
|
4835 |
|
4836 | import ts28 from "typescript";
|
4837 | var TypeCheckFile = class extends Environment {
|
4838 | constructor(fileName, config, refEmitter, reflector, compilerHost) {
|
4839 | super(config, new ImportManager(new NoopImportRewriter(), "i"), refEmitter, reflector, ts28.createSourceFile(compilerHost.getCanonicalFileName(fileName), "", ts28.ScriptTarget.Latest, true));
|
4840 | this.fileName = fileName;
|
4841 | this.nextTcbId = 1;
|
4842 | this.tcbStatements = [];
|
4843 | }
|
4844 | addTypeCheckBlock(ref, meta, domSchemaChecker, oobRecorder, genericContextBehavior) {
|
4845 | const fnId = ts28.createIdentifier(`_tcb${this.nextTcbId++}`);
|
4846 | const fn = generateTypeCheckBlock(this, ref, fnId, meta, domSchemaChecker, oobRecorder, genericContextBehavior);
|
4847 | this.tcbStatements.push(fn);
|
4848 | }
|
4849 | render(removeComments) {
|
4850 | let source = this.importManager.getAllImports(this.contextFile.fileName).map((i) => `import * as ${i.qualifier.text} from '${i.specifier}';`).join("\n") + "\n\n";
|
4851 | const printer = ts28.createPrinter({ removeComments });
|
4852 | source += "\n";
|
4853 | for (const stmt of this.pipeInstStatements) {
|
4854 | source += printer.printNode(ts28.EmitHint.Unspecified, stmt, this.contextFile) + "\n";
|
4855 | }
|
4856 | for (const stmt of this.typeCtorStatements) {
|
4857 | source += printer.printNode(ts28.EmitHint.Unspecified, stmt, this.contextFile) + "\n";
|
4858 | }
|
4859 | source += "\n";
|
4860 | for (const stmt of this.tcbStatements) {
|
4861 | source += printer.printNode(ts28.EmitHint.Unspecified, stmt, this.contextFile) + "\n";
|
4862 | }
|
4863 | source += "\nexport const IS_A_MODULE = true;\n";
|
4864 | return source;
|
4865 | }
|
4866 | getPreludeStatements() {
|
4867 | return [];
|
4868 | }
|
4869 | };
|
4870 |
|
4871 |
|
4872 | var InliningMode;
|
4873 | (function(InliningMode2) {
|
4874 | InliningMode2[InliningMode2["InlineOps"] = 0] = "InlineOps";
|
4875 | InliningMode2[InliningMode2["Error"] = 1] = "Error";
|
4876 | })(InliningMode || (InliningMode = {}));
|
4877 | var TypeCheckContextImpl = class {
|
4878 | constructor(config, compilerHost, refEmitter, reflector, host, inlining, perf) {
|
4879 | this.config = config;
|
4880 | this.compilerHost = compilerHost;
|
4881 | this.refEmitter = refEmitter;
|
4882 | this.reflector = reflector;
|
4883 | this.host = host;
|
4884 | this.inlining = inlining;
|
4885 | this.perf = perf;
|
4886 | this.fileMap = new Map();
|
4887 | this.opMap = new Map();
|
4888 | this.typeCtorPending = new Set();
|
4889 | if (inlining === InliningMode.Error && config.useInlineTypeConstructors) {
|
4890 | throw new Error(`AssertionError: invalid inlining configuration.`);
|
4891 | }
|
4892 | }
|
4893 | addTemplate(ref, binder, template, pipes, schemas, sourceMapping, file, parseErrors) {
|
4894 | if (!this.host.shouldCheckComponent(ref.node)) {
|
4895 | return;
|
4896 | }
|
4897 | const fileData = this.dataForFile(ref.node.getSourceFile());
|
4898 | const shimData = this.pendingShimForComponent(ref.node);
|
4899 | const templateId = fileData.sourceManager.getTemplateId(ref.node);
|
4900 | const templateDiagnostics = [];
|
4901 | if (parseErrors !== null) {
|
4902 | templateDiagnostics.push(...this.getTemplateDiagnostics(parseErrors, templateId, sourceMapping));
|
4903 | }
|
4904 | const boundTarget = binder.bind({ template });
|
4905 | if (this.inlining === InliningMode.InlineOps) {
|
4906 | for (const dir of boundTarget.getUsedDirectives()) {
|
4907 | const dirRef = dir.ref;
|
4908 | const dirNode = dirRef.node;
|
4909 | if (!dir.isGeneric || !requiresInlineTypeCtor(dirNode, this.reflector, shimData.file)) {
|
4910 | continue;
|
4911 | }
|
4912 | this.addInlineTypeCtor(fileData, dirNode.getSourceFile(), dirRef, {
|
4913 | fnName: "ngTypeCtor",
|
4914 | body: !dirNode.getSourceFile().isDeclarationFile,
|
4915 | fields: {
|
4916 | inputs: dir.inputs.classPropertyNames,
|
4917 | outputs: dir.outputs.classPropertyNames,
|
4918 | queries: dir.queries
|
4919 | },
|
4920 | coercedInputFields: dir.coercedInputFields
|
4921 | });
|
4922 | }
|
4923 | }
|
4924 | shimData.templates.set(templateId, {
|
4925 | template,
|
4926 | boundTarget,
|
4927 | templateDiagnostics
|
4928 | });
|
4929 | const inliningRequirement = requiresInlineTypeCheckBlock(ref.node, shimData.file, pipes, this.reflector);
|
4930 | if (this.inlining === InliningMode.Error && inliningRequirement === TcbInliningRequirement.MustInline) {
|
4931 | shimData.oobRecorder.requiresInlineTcb(templateId, ref.node);
|
4932 | this.perf.eventCount(PerfEvent.SkipGenerateTcbNoInline);
|
4933 | return;
|
4934 | }
|
4935 | const meta = {
|
4936 | id: fileData.sourceManager.captureSource(ref.node, sourceMapping, file),
|
4937 | boundTarget,
|
4938 | pipes,
|
4939 | schemas
|
4940 | };
|
4941 | this.perf.eventCount(PerfEvent.GenerateTcb);
|
4942 | if (inliningRequirement !== TcbInliningRequirement.None && this.inlining === InliningMode.InlineOps) {
|
4943 | this.addInlineTypeCheckBlock(fileData, shimData, ref, meta);
|
4944 | } else if (inliningRequirement === TcbInliningRequirement.ShouldInlineForGenericBounds && this.inlining === InliningMode.Error) {
|
4945 | shimData.file.addTypeCheckBlock(ref, meta, shimData.domSchemaChecker, shimData.oobRecorder, TcbGenericContextBehavior.FallbackToAny);
|
4946 | } else {
|
4947 | shimData.file.addTypeCheckBlock(ref, meta, shimData.domSchemaChecker, shimData.oobRecorder, TcbGenericContextBehavior.UseEmitter);
|
4948 | }
|
4949 | }
|
4950 | addInlineTypeCtor(fileData, sf, ref, ctorMeta) {
|
4951 | if (this.typeCtorPending.has(ref.node)) {
|
4952 | return;
|
4953 | }
|
4954 | this.typeCtorPending.add(ref.node);
|
4955 | if (!this.opMap.has(sf)) {
|
4956 | this.opMap.set(sf, []);
|
4957 | }
|
4958 | const ops = this.opMap.get(sf);
|
4959 | ops.push(new TypeCtorOp(ref, ctorMeta));
|
4960 | fileData.hasInlines = true;
|
4961 | }
|
4962 | transform(sf) {
|
4963 | if (!this.opMap.has(sf)) {
|
4964 | return null;
|
4965 | }
|
4966 | const importManager = new ImportManager(new NoopImportRewriter(), "_i");
|
4967 | const ops = this.opMap.get(sf).sort(orderOps);
|
4968 | const textParts = splitStringAtPoints(sf.text, ops.map((op) => op.splitPoint));
|
4969 | const printer = ts29.createPrinter({ omitTrailingSemicolon: true });
|
4970 | let code = textParts[0];
|
4971 | ops.forEach((op, idx) => {
|
4972 | const text = op.execute(importManager, sf, this.refEmitter, printer);
|
4973 | code += "\n\n" + text + textParts[idx + 1];
|
4974 | });
|
4975 | let imports = importManager.getAllImports(sf.fileName).map((i) => `import * as ${i.qualifier.text} from '${i.specifier}';`).join("\n");
|
4976 | code = imports + "\n" + code;
|
4977 | return code;
|
4978 | }
|
4979 | finalize() {
|
4980 | const updates = new Map();
|
4981 | for (const originalSf of this.opMap.keys()) {
|
4982 | const newText = this.transform(originalSf);
|
4983 | if (newText !== null) {
|
4984 | updates.set(absoluteFromSourceFile(originalSf), {
|
4985 | newText,
|
4986 | originalFile: originalSf
|
4987 | });
|
4988 | }
|
4989 | }
|
4990 | for (const [sfPath, pendingFileData] of this.fileMap) {
|
4991 | for (const pendingShimData of pendingFileData.shimData.values()) {
|
4992 | this.host.recordShimData(sfPath, {
|
4993 | genesisDiagnostics: [
|
4994 | ...pendingShimData.domSchemaChecker.diagnostics,
|
4995 | ...pendingShimData.oobRecorder.diagnostics
|
4996 | ],
|
4997 | hasInlines: pendingFileData.hasInlines,
|
4998 | path: pendingShimData.file.fileName,
|
4999 | templates: pendingShimData.templates
|
5000 | });
|
5001 | const sfText = pendingShimData.file.render(false);
|
5002 | updates.set(pendingShimData.file.fileName, {
|
5003 | newText: sfText,
|
5004 | originalFile: null
|
5005 | });
|
5006 | }
|
5007 | }
|
5008 | return updates;
|
5009 | }
|
5010 | addInlineTypeCheckBlock(fileData, shimData, ref, tcbMeta) {
|
5011 | const sf = ref.node.getSourceFile();
|
5012 | if (!this.opMap.has(sf)) {
|
5013 | this.opMap.set(sf, []);
|
5014 | }
|
5015 | const ops = this.opMap.get(sf);
|
5016 | ops.push(new InlineTcbOp(ref, tcbMeta, this.config, this.reflector, shimData.domSchemaChecker, shimData.oobRecorder));
|
5017 | fileData.hasInlines = true;
|
5018 | }
|
5019 | pendingShimForComponent(node) {
|
5020 | const fileData = this.dataForFile(node.getSourceFile());
|
5021 | const shimPath = TypeCheckShimGenerator.shimFor(absoluteFromSourceFile(node.getSourceFile()));
|
5022 | if (!fileData.shimData.has(shimPath)) {
|
5023 | fileData.shimData.set(shimPath, {
|
5024 | domSchemaChecker: new RegistryDomSchemaChecker(fileData.sourceManager),
|
5025 | oobRecorder: new OutOfBandDiagnosticRecorderImpl(fileData.sourceManager),
|
5026 | file: new TypeCheckFile(shimPath, this.config, this.refEmitter, this.reflector, this.compilerHost),
|
5027 | templates: new Map()
|
5028 | });
|
5029 | }
|
5030 | return fileData.shimData.get(shimPath);
|
5031 | }
|
5032 | dataForFile(sf) {
|
5033 | const sfPath = absoluteFromSourceFile(sf);
|
5034 | if (!this.fileMap.has(sfPath)) {
|
5035 | const data = {
|
5036 | hasInlines: false,
|
5037 | sourceManager: this.host.getSourceManager(sfPath),
|
5038 | shimData: new Map()
|
5039 | };
|
5040 | this.fileMap.set(sfPath, data);
|
5041 | }
|
5042 | return this.fileMap.get(sfPath);
|
5043 | }
|
5044 | getTemplateDiagnostics(parseErrors, templateId, sourceMapping) {
|
5045 | return parseErrors.map((error) => {
|
5046 | const span = error.span;
|
5047 | if (span.start.offset === span.end.offset) {
|
5048 | span.end.offset++;
|
5049 | }
|
5050 | return makeTemplateDiagnostic(templateId, sourceMapping, span, ts29.DiagnosticCategory.Error, ngErrorCode(ErrorCode.TEMPLATE_PARSE_ERROR), error.msg);
|
5051 | });
|
5052 | }
|
5053 | };
|
5054 | var InlineTcbOp = class {
|
5055 | constructor(ref, meta, config, reflector, domSchemaChecker, oobRecorder) {
|
5056 | this.ref = ref;
|
5057 | this.meta = meta;
|
5058 | this.config = config;
|
5059 | this.reflector = reflector;
|
5060 | this.domSchemaChecker = domSchemaChecker;
|
5061 | this.oobRecorder = oobRecorder;
|
5062 | }
|
5063 | get splitPoint() {
|
5064 | return this.ref.node.end + 1;
|
5065 | }
|
5066 | execute(im, sf, refEmitter, printer) {
|
5067 | const env = new Environment(this.config, im, refEmitter, this.reflector, sf);
|
5068 | const fnName = ts29.createIdentifier(`_tcb_${this.ref.node.pos}`);
|
5069 | const fn = generateTypeCheckBlock(env, this.ref, fnName, this.meta, this.domSchemaChecker, this.oobRecorder, TcbGenericContextBehavior.CopyClassNodes);
|
5070 | return printer.printNode(ts29.EmitHint.Unspecified, fn, sf);
|
5071 | }
|
5072 | };
|
5073 | var TypeCtorOp = class {
|
5074 | constructor(ref, meta) {
|
5075 | this.ref = ref;
|
5076 | this.meta = meta;
|
5077 | }
|
5078 | get splitPoint() {
|
5079 | return this.ref.node.end - 1;
|
5080 | }
|
5081 | execute(im, sf, refEmitter, printer) {
|
5082 | const tcb = generateInlineTypeCtor(this.ref.node, this.meta);
|
5083 | return printer.printNode(ts29.EmitHint.Unspecified, tcb, sf);
|
5084 | }
|
5085 | };
|
5086 | function orderOps(op1, op2) {
|
5087 | return op1.splitPoint - op2.splitPoint;
|
5088 | }
|
5089 | function splitStringAtPoints(str, points) {
|
5090 | const splits = [];
|
5091 | let start = 0;
|
5092 | for (let i = 0; i < points.length; i++) {
|
5093 | const point = points[i];
|
5094 | splits.push(str.substring(start, point));
|
5095 | start = point;
|
5096 | }
|
5097 | splits.push(str.substring(start));
|
5098 | return splits;
|
5099 | }
|
5100 |
|
5101 |
|
5102 | import { ParseLocation, ParseSourceSpan } from "@angular/compiler";
|
5103 |
|
5104 |
|
5105 | var LF_CHAR = 10;
|
5106 | var CR_CHAR = 13;
|
5107 | var LINE_SEP_CHAR = 8232;
|
5108 | var PARAGRAPH_CHAR = 8233;
|
5109 | function getLineAndCharacterFromPosition(lineStartsMap, position) {
|
5110 | const lineIndex = findClosestLineStartPosition(lineStartsMap, position);
|
5111 | return { character: position - lineStartsMap[lineIndex], line: lineIndex };
|
5112 | }
|
5113 | function computeLineStartsMap(text) {
|
5114 | const result = [0];
|
5115 | let pos = 0;
|
5116 | while (pos < text.length) {
|
5117 | const char = text.charCodeAt(pos++);
|
5118 | if (char === CR_CHAR) {
|
5119 | if (text.charCodeAt(pos) === LF_CHAR) {
|
5120 | pos++;
|
5121 | }
|
5122 | result.push(pos);
|
5123 | } else if (char === LF_CHAR || char === LINE_SEP_CHAR || char === PARAGRAPH_CHAR) {
|
5124 | result.push(pos);
|
5125 | }
|
5126 | }
|
5127 | result.push(pos);
|
5128 | return result;
|
5129 | }
|
5130 | function findClosestLineStartPosition(linesMap, position, low = 0, high = linesMap.length - 1) {
|
5131 | while (low <= high) {
|
5132 | const pivotIdx = Math.floor((low + high) / 2);
|
5133 | const pivotEl = linesMap[pivotIdx];
|
5134 | if (pivotEl === position) {
|
5135 | return pivotIdx;
|
5136 | } else if (position > pivotEl) {
|
5137 | low = pivotIdx + 1;
|
5138 | } else {
|
5139 | high = pivotIdx - 1;
|
5140 | }
|
5141 | }
|
5142 | return low - 1;
|
5143 | }
|
5144 |
|
5145 |
|
5146 | var TemplateSource = class {
|
5147 | constructor(mapping, file) {
|
5148 | this.mapping = mapping;
|
5149 | this.file = file;
|
5150 | this.lineStarts = null;
|
5151 | }
|
5152 | toParseSourceSpan(start, end) {
|
5153 | const startLoc = this.toParseLocation(start);
|
5154 | const endLoc = this.toParseLocation(end);
|
5155 | return new ParseSourceSpan(startLoc, endLoc);
|
5156 | }
|
5157 | toParseLocation(position) {
|
5158 | const lineStarts = this.acquireLineStarts();
|
5159 | const { line, character } = getLineAndCharacterFromPosition(lineStarts, position);
|
5160 | return new ParseLocation(this.file, position, line, character);
|
5161 | }
|
5162 | acquireLineStarts() {
|
5163 | if (this.lineStarts === null) {
|
5164 | this.lineStarts = computeLineStartsMap(this.file.content);
|
5165 | }
|
5166 | return this.lineStarts;
|
5167 | }
|
5168 | };
|
5169 | var TemplateSourceManager = class {
|
5170 | constructor() {
|
5171 | this.templateSources = new Map();
|
5172 | }
|
5173 | getTemplateId(node) {
|
5174 | return getTemplateId(node);
|
5175 | }
|
5176 | captureSource(node, mapping, file) {
|
5177 | const id = getTemplateId(node);
|
5178 | this.templateSources.set(id, new TemplateSource(mapping, file));
|
5179 | return id;
|
5180 | }
|
5181 | getSourceMapping(id) {
|
5182 | if (!this.templateSources.has(id)) {
|
5183 | throw new Error(`Unexpected unknown template ID: ${id}`);
|
5184 | }
|
5185 | return this.templateSources.get(id).mapping;
|
5186 | }
|
5187 | toParseSourceSpan(id, span) {
|
5188 | if (!this.templateSources.has(id)) {
|
5189 | return null;
|
5190 | }
|
5191 | const templateSource = this.templateSources.get(id);
|
5192 | return templateSource.toParseSourceSpan(span.start, span.end);
|
5193 | }
|
5194 | };
|
5195 |
|
5196 |
|
5197 | import { AST, ASTWithSource as ASTWithSource3, BindingPipe as BindingPipe2, PropertyRead as PropertyRead5, PropertyWrite as PropertyWrite4, SafePropertyRead as SafePropertyRead4, TmplAstBoundAttribute as TmplAstBoundAttribute2, TmplAstBoundEvent, TmplAstElement as TmplAstElement4, TmplAstReference as TmplAstReference4, TmplAstTemplate as TmplAstTemplate3, TmplAstTextAttribute as TmplAstTextAttribute3, TmplAstVariable as TmplAstVariable3 } from "@angular/compiler";
|
5198 | import ts30 from "typescript";
|
5199 | var SymbolBuilder = class {
|
5200 | constructor(tcbPath, tcbIsShim, typeCheckBlock, templateData, componentScopeReader, getTypeChecker) {
|
5201 | this.tcbPath = tcbPath;
|
5202 | this.tcbIsShim = tcbIsShim;
|
5203 | this.typeCheckBlock = typeCheckBlock;
|
5204 | this.templateData = templateData;
|
5205 | this.componentScopeReader = componentScopeReader;
|
5206 | this.getTypeChecker = getTypeChecker;
|
5207 | this.symbolCache = new Map();
|
5208 | }
|
5209 | getSymbol(node) {
|
5210 | if (this.symbolCache.has(node)) {
|
5211 | return this.symbolCache.get(node);
|
5212 | }
|
5213 | let symbol = null;
|
5214 | if (node instanceof TmplAstBoundAttribute2 || node instanceof TmplAstTextAttribute3) {
|
5215 | symbol = this.getSymbolOfInputBinding(node);
|
5216 | } else if (node instanceof TmplAstBoundEvent) {
|
5217 | symbol = this.getSymbolOfBoundEvent(node);
|
5218 | } else if (node instanceof TmplAstElement4) {
|
5219 | symbol = this.getSymbolOfElement(node);
|
5220 | } else if (node instanceof TmplAstTemplate3) {
|
5221 | symbol = this.getSymbolOfAstTemplate(node);
|
5222 | } else if (node instanceof TmplAstVariable3) {
|
5223 | symbol = this.getSymbolOfVariable(node);
|
5224 | } else if (node instanceof TmplAstReference4) {
|
5225 | symbol = this.getSymbolOfReference(node);
|
5226 | } else if (node instanceof BindingPipe2) {
|
5227 | symbol = this.getSymbolOfPipe(node);
|
5228 | } else if (node instanceof AST) {
|
5229 | symbol = this.getSymbolOfTemplateExpression(node);
|
5230 | } else {
|
5231 | }
|
5232 | this.symbolCache.set(node, symbol);
|
5233 | return symbol;
|
5234 | }
|
5235 | getSymbolOfAstTemplate(template) {
|
5236 | const directives = this.getDirectivesOfNode(template);
|
5237 | return { kind: SymbolKind.Template, directives, templateNode: template };
|
5238 | }
|
5239 | getSymbolOfElement(element) {
|
5240 | var _a;
|
5241 | const elementSourceSpan = (_a = element.startSourceSpan) != null ? _a : element.sourceSpan;
|
5242 | const node = findFirstMatchingNode(this.typeCheckBlock, { withSpan: elementSourceSpan, filter: ts30.isVariableDeclaration });
|
5243 | if (node === null) {
|
5244 | return null;
|
5245 | }
|
5246 | const symbolFromDeclaration = this.getSymbolOfTsNode(node);
|
5247 | if (symbolFromDeclaration === null || symbolFromDeclaration.tsSymbol === null) {
|
5248 | return null;
|
5249 | }
|
5250 | const directives = this.getDirectivesOfNode(element);
|
5251 | return __spreadProps(__spreadValues({}, symbolFromDeclaration), {
|
5252 | kind: SymbolKind.Element,
|
5253 | directives,
|
5254 | templateNode: element
|
5255 | });
|
5256 | }
|
5257 | getDirectivesOfNode(element) {
|
5258 | var _a;
|
5259 | const elementSourceSpan = (_a = element.startSourceSpan) != null ? _a : element.sourceSpan;
|
5260 | const tcbSourceFile = this.typeCheckBlock.getSourceFile();
|
5261 | const isDirectiveDeclaration = (node) => (ts30.isTypeNode(node) || ts30.isIdentifier(node)) && ts30.isVariableDeclaration(node.parent) && hasExpressionIdentifier(tcbSourceFile, node, ExpressionIdentifier.DIRECTIVE);
|
5262 | const nodes = findAllMatchingNodes(this.typeCheckBlock, { withSpan: elementSourceSpan, filter: isDirectiveDeclaration });
|
5263 | return nodes.map((node) => {
|
5264 | var _a2;
|
5265 | const symbol = this.getSymbolOfTsNode(node.parent);
|
5266 | if (symbol === null || !isSymbolWithValueDeclaration(symbol.tsSymbol) || !ts30.isClassDeclaration(symbol.tsSymbol.valueDeclaration)) {
|
5267 | return null;
|
5268 | }
|
5269 | const meta = this.getDirectiveMeta(element, symbol.tsSymbol.valueDeclaration);
|
5270 | if (meta === null) {
|
5271 | return null;
|
5272 | }
|
5273 | const ngModule = this.getDirectiveModule(symbol.tsSymbol.valueDeclaration);
|
5274 | if (meta.selector === null) {
|
5275 | return null;
|
5276 | }
|
5277 | const isComponent = (_a2 = meta.isComponent) != null ? _a2 : null;
|
5278 | const directiveSymbol = __spreadProps(__spreadValues({}, symbol), {
|
5279 | tsSymbol: symbol.tsSymbol,
|
5280 | selector: meta.selector,
|
5281 | isComponent,
|
5282 | ngModule,
|
5283 | kind: SymbolKind.Directive,
|
5284 | isStructural: meta.isStructural
|
5285 | });
|
5286 | return directiveSymbol;
|
5287 | }).filter((d) => d !== null);
|
5288 | }
|
5289 | getDirectiveMeta(host, directiveDeclaration) {
|
5290 | var _a;
|
5291 | let directives = this.templateData.boundTarget.getDirectivesOfNode(host);
|
5292 | const firstChild = host.children[0];
|
5293 | if (firstChild instanceof TmplAstElement4) {
|
5294 | const isMicrosyntaxTemplate = host instanceof TmplAstTemplate3 && sourceSpanEqual(firstChild.sourceSpan, host.sourceSpan);
|
5295 | if (isMicrosyntaxTemplate) {
|
5296 | const firstChildDirectives = this.templateData.boundTarget.getDirectivesOfNode(firstChild);
|
5297 | if (firstChildDirectives !== null && directives !== null) {
|
5298 | directives = directives.concat(firstChildDirectives);
|
5299 | } else {
|
5300 | directives = directives != null ? directives : firstChildDirectives;
|
5301 | }
|
5302 | }
|
5303 | }
|
5304 | if (directives === null) {
|
5305 | return null;
|
5306 | }
|
5307 | return (_a = directives.find((m) => m.ref.node === directiveDeclaration)) != null ? _a : null;
|
5308 | }
|
5309 | getDirectiveModule(declaration) {
|
5310 | const scope = this.componentScopeReader.getScopeForComponent(declaration);
|
5311 | if (scope === null) {
|
5312 | return null;
|
5313 | }
|
5314 | return scope.ngModule;
|
5315 | }
|
5316 | getSymbolOfBoundEvent(eventBinding) {
|
5317 | const consumer = this.templateData.boundTarget.getConsumerOfBinding(eventBinding);
|
5318 | if (consumer === null) {
|
5319 | return null;
|
5320 | }
|
5321 | let expectedAccess;
|
5322 | if (consumer instanceof TmplAstTemplate3 || consumer instanceof TmplAstElement4) {
|
5323 | expectedAccess = "addEventListener";
|
5324 | } else {
|
5325 | const bindingPropertyNames = consumer.outputs.getByBindingPropertyName(eventBinding.name);
|
5326 | if (bindingPropertyNames === null || bindingPropertyNames.length === 0) {
|
5327 | return null;
|
5328 | }
|
5329 | expectedAccess = bindingPropertyNames[0].classPropertyName;
|
5330 | }
|
5331 | function filter(n) {
|
5332 | if (!isAccessExpression(n)) {
|
5333 | return false;
|
5334 | }
|
5335 | if (ts30.isPropertyAccessExpression(n)) {
|
5336 | return n.name.getText() === expectedAccess;
|
5337 | } else {
|
5338 | return ts30.isStringLiteral(n.argumentExpression) && n.argumentExpression.text === expectedAccess;
|
5339 | }
|
5340 | }
|
5341 | const outputFieldAccesses = findAllMatchingNodes(this.typeCheckBlock, { withSpan: eventBinding.keySpan, filter });
|
5342 | const bindings = [];
|
5343 | for (const outputFieldAccess of outputFieldAccesses) {
|
5344 | if (consumer instanceof TmplAstTemplate3 || consumer instanceof TmplAstElement4) {
|
5345 | if (!ts30.isPropertyAccessExpression(outputFieldAccess)) {
|
5346 | continue;
|
5347 | }
|
5348 | const addEventListener = outputFieldAccess.name;
|
5349 | const tsSymbol = this.getTypeChecker().getSymbolAtLocation(addEventListener);
|
5350 | const tsType = this.getTypeChecker().getTypeAtLocation(addEventListener);
|
5351 | const positionInFile = this.getTcbPositionForNode(addEventListener);
|
5352 | const target = this.getSymbol(consumer);
|
5353 | if (target === null || tsSymbol === void 0) {
|
5354 | continue;
|
5355 | }
|
5356 | bindings.push({
|
5357 | kind: SymbolKind.Binding,
|
5358 | tsSymbol,
|
5359 | tsType,
|
5360 | target,
|
5361 | tcbLocation: {
|
5362 | tcbPath: this.tcbPath,
|
5363 | isShimFile: this.tcbIsShim,
|
5364 | positionInFile
|
5365 | }
|
5366 | });
|
5367 | } else {
|
5368 | if (!ts30.isElementAccessExpression(outputFieldAccess)) {
|
5369 | continue;
|
5370 | }
|
5371 | const tsSymbol = this.getTypeChecker().getSymbolAtLocation(outputFieldAccess.argumentExpression);
|
5372 | if (tsSymbol === void 0) {
|
5373 | continue;
|
5374 | }
|
5375 | const target = this.getDirectiveSymbolForAccessExpression(outputFieldAccess, consumer);
|
5376 | if (target === null) {
|
5377 | continue;
|
5378 | }
|
5379 | const positionInFile = this.getTcbPositionForNode(outputFieldAccess);
|
5380 | const tsType = this.getTypeChecker().getTypeAtLocation(outputFieldAccess);
|
5381 | bindings.push({
|
5382 | kind: SymbolKind.Binding,
|
5383 | tsSymbol,
|
5384 | tsType,
|
5385 | target,
|
5386 | tcbLocation: {
|
5387 | tcbPath: this.tcbPath,
|
5388 | isShimFile: this.tcbIsShim,
|
5389 | positionInFile
|
5390 | }
|
5391 | });
|
5392 | }
|
5393 | }
|
5394 | if (bindings.length === 0) {
|
5395 | return null;
|
5396 | }
|
5397 | return { kind: SymbolKind.Output, bindings };
|
5398 | }
|
5399 | getSymbolOfInputBinding(binding) {
|
5400 | const consumer = this.templateData.boundTarget.getConsumerOfBinding(binding);
|
5401 | if (consumer === null) {
|
5402 | return null;
|
5403 | }
|
5404 | if (consumer instanceof TmplAstElement4 || consumer instanceof TmplAstTemplate3) {
|
5405 | const host = this.getSymbol(consumer);
|
5406 | return host !== null ? { kind: SymbolKind.DomBinding, host } : null;
|
5407 | }
|
5408 | const nodes = findAllMatchingNodes(this.typeCheckBlock, { withSpan: binding.sourceSpan, filter: isAssignment });
|
5409 | const bindings = [];
|
5410 | for (const node of nodes) {
|
5411 | if (!isAccessExpression(node.left)) {
|
5412 | continue;
|
5413 | }
|
5414 | const symbolInfo = this.getSymbolOfTsNode(node.left);
|
5415 | if (symbolInfo === null || symbolInfo.tsSymbol === null) {
|
5416 | continue;
|
5417 | }
|
5418 | const target = this.getDirectiveSymbolForAccessExpression(node.left, consumer);
|
5419 | if (target === null) {
|
5420 | continue;
|
5421 | }
|
5422 | bindings.push(__spreadProps(__spreadValues({}, symbolInfo), {
|
5423 | tsSymbol: symbolInfo.tsSymbol,
|
5424 | kind: SymbolKind.Binding,
|
5425 | target
|
5426 | }));
|
5427 | }
|
5428 | if (bindings.length === 0) {
|
5429 | return null;
|
5430 | }
|
5431 | return { kind: SymbolKind.Input, bindings };
|
5432 | }
|
5433 | getDirectiveSymbolForAccessExpression(node, { isComponent, selector, isStructural }) {
|
5434 | var _a;
|
5435 | const tsSymbol = this.getTypeChecker().getSymbolAtLocation(node.expression);
|
5436 | if ((tsSymbol == null ? void 0 : tsSymbol.declarations) === void 0 || tsSymbol.declarations.length === 0 || selector === null) {
|
5437 | return null;
|
5438 | }
|
5439 | const [declaration] = tsSymbol.declarations;
|
5440 | if (!ts30.isVariableDeclaration(declaration) || !hasExpressionIdentifier(declaration.getSourceFile(), (_a = declaration.type) != null ? _a : declaration.name, ExpressionIdentifier.DIRECTIVE)) {
|
5441 | return null;
|
5442 | }
|
5443 | const symbol = this.getSymbolOfTsNode(declaration);
|
5444 | if (symbol === null || !isSymbolWithValueDeclaration(symbol.tsSymbol) || !ts30.isClassDeclaration(symbol.tsSymbol.valueDeclaration)) {
|
5445 | return null;
|
5446 | }
|
5447 | const ngModule = this.getDirectiveModule(symbol.tsSymbol.valueDeclaration);
|
5448 | return {
|
5449 | kind: SymbolKind.Directive,
|
5450 | tsSymbol: symbol.tsSymbol,
|
5451 | tsType: symbol.tsType,
|
5452 | tcbLocation: symbol.tcbLocation,
|
5453 | isComponent,
|
5454 | isStructural,
|
5455 | selector,
|
5456 | ngModule
|
5457 | };
|
5458 | }
|
5459 | getSymbolOfVariable(variable) {
|
5460 | const node = findFirstMatchingNode(this.typeCheckBlock, { withSpan: variable.sourceSpan, filter: ts30.isVariableDeclaration });
|
5461 | if (node === null || node.initializer === void 0) {
|
5462 | return null;
|
5463 | }
|
5464 | const expressionSymbol = this.getSymbolOfTsNode(node.initializer);
|
5465 | if (expressionSymbol === null) {
|
5466 | return null;
|
5467 | }
|
5468 | return {
|
5469 | tsType: expressionSymbol.tsType,
|
5470 | tsSymbol: expressionSymbol.tsSymbol,
|
5471 | initializerLocation: expressionSymbol.tcbLocation,
|
5472 | kind: SymbolKind.Variable,
|
5473 | declaration: variable,
|
5474 | localVarLocation: {
|
5475 | tcbPath: this.tcbPath,
|
5476 | isShimFile: this.tcbIsShim,
|
5477 | positionInFile: this.getTcbPositionForNode(node.name)
|
5478 | }
|
5479 | };
|
5480 | }
|
5481 | getSymbolOfReference(ref) {
|
5482 | const target = this.templateData.boundTarget.getReferenceTarget(ref);
|
5483 | let node = findFirstMatchingNode(this.typeCheckBlock, { withSpan: ref.sourceSpan, filter: ts30.isVariableDeclaration });
|
5484 | if (node === null || target === null || node.initializer === void 0) {
|
5485 | return null;
|
5486 | }
|
5487 | const originalDeclaration = ts30.isParenthesizedExpression(node.initializer) && ts30.isAsExpression(node.initializer.expression) ? this.getTypeChecker().getSymbolAtLocation(node.name) : this.getTypeChecker().getSymbolAtLocation(node.initializer);
|
5488 | if (originalDeclaration === void 0 || originalDeclaration.valueDeclaration === void 0) {
|
5489 | return null;
|
5490 | }
|
5491 | const symbol = this.getSymbolOfTsNode(originalDeclaration.valueDeclaration);
|
5492 | if (symbol === null || symbol.tsSymbol === null) {
|
5493 | return null;
|
5494 | }
|
5495 | const referenceVarTcbLocation = {
|
5496 | tcbPath: this.tcbPath,
|
5497 | isShimFile: this.tcbIsShim,
|
5498 | positionInFile: this.getTcbPositionForNode(node)
|
5499 | };
|
5500 | if (target instanceof TmplAstTemplate3 || target instanceof TmplAstElement4) {
|
5501 | return {
|
5502 | kind: SymbolKind.Reference,
|
5503 | tsSymbol: symbol.tsSymbol,
|
5504 | tsType: symbol.tsType,
|
5505 | target,
|
5506 | declaration: ref,
|
5507 | targetLocation: symbol.tcbLocation,
|
5508 | referenceVarLocation: referenceVarTcbLocation
|
5509 | };
|
5510 | } else {
|
5511 | if (!ts30.isClassDeclaration(target.directive.ref.node)) {
|
5512 | return null;
|
5513 | }
|
5514 | return {
|
5515 | kind: SymbolKind.Reference,
|
5516 | tsSymbol: symbol.tsSymbol,
|
5517 | tsType: symbol.tsType,
|
5518 | declaration: ref,
|
5519 | target: target.directive.ref.node,
|
5520 | targetLocation: symbol.tcbLocation,
|
5521 | referenceVarLocation: referenceVarTcbLocation
|
5522 | };
|
5523 | }
|
5524 | }
|
5525 | getSymbolOfPipe(expression) {
|
5526 | const methodAccess = findFirstMatchingNode(this.typeCheckBlock, { withSpan: expression.nameSpan, filter: ts30.isPropertyAccessExpression });
|
5527 | if (methodAccess === null) {
|
5528 | return null;
|
5529 | }
|
5530 | const pipeVariableNode = methodAccess.expression;
|
5531 | const pipeDeclaration = this.getTypeChecker().getSymbolAtLocation(pipeVariableNode);
|
5532 | if (pipeDeclaration === void 0 || pipeDeclaration.valueDeclaration === void 0) {
|
5533 | return null;
|
5534 | }
|
5535 | const pipeInstance = this.getSymbolOfTsNode(pipeDeclaration.valueDeclaration);
|
5536 | if (pipeInstance === null || !isSymbolWithValueDeclaration(pipeInstance.tsSymbol)) {
|
5537 | return null;
|
5538 | }
|
5539 | const symbolInfo = this.getSymbolOfTsNode(methodAccess);
|
5540 | if (symbolInfo === null) {
|
5541 | return null;
|
5542 | }
|
5543 | return __spreadProps(__spreadValues({
|
5544 | kind: SymbolKind.Pipe
|
5545 | }, symbolInfo), {
|
5546 | classSymbol: __spreadProps(__spreadValues({}, pipeInstance), {
|
5547 | tsSymbol: pipeInstance.tsSymbol
|
5548 | })
|
5549 | });
|
5550 | }
|
5551 | getSymbolOfTemplateExpression(expression) {
|
5552 | if (expression instanceof ASTWithSource3) {
|
5553 | expression = expression.ast;
|
5554 | }
|
5555 | const expressionTarget = this.templateData.boundTarget.getExpressionTarget(expression);
|
5556 | if (expressionTarget !== null) {
|
5557 | return this.getSymbol(expressionTarget);
|
5558 | }
|
5559 | let withSpan = expression.sourceSpan;
|
5560 | if (expression instanceof PropertyWrite4) {
|
5561 | withSpan = expression.nameSpan;
|
5562 | }
|
5563 | let node = null;
|
5564 | if (expression instanceof PropertyRead5) {
|
5565 | node = findFirstMatchingNode(this.typeCheckBlock, { withSpan, filter: ts30.isPropertyAccessExpression });
|
5566 | }
|
5567 | if (node === null) {
|
5568 | node = findFirstMatchingNode(this.typeCheckBlock, { withSpan, filter: anyNodeFilter });
|
5569 | }
|
5570 | if (node === null) {
|
5571 | return null;
|
5572 | }
|
5573 | while (ts30.isParenthesizedExpression(node)) {
|
5574 | node = node.expression;
|
5575 | }
|
5576 | if (expression instanceof SafePropertyRead4 && ts30.isConditionalExpression(node)) {
|
5577 | const whenTrueSymbol = this.getSymbolOfTsNode(node.whenTrue);
|
5578 | if (whenTrueSymbol === null) {
|
5579 | return null;
|
5580 | }
|
5581 | return __spreadProps(__spreadValues({}, whenTrueSymbol), {
|
5582 | kind: SymbolKind.Expression,
|
5583 | tsType: this.getTypeChecker().getTypeAtLocation(node)
|
5584 | });
|
5585 | } else {
|
5586 | const symbolInfo = this.getSymbolOfTsNode(node);
|
5587 | return symbolInfo === null ? null : __spreadProps(__spreadValues({}, symbolInfo), { kind: SymbolKind.Expression });
|
5588 | }
|
5589 | }
|
5590 | getSymbolOfTsNode(node) {
|
5591 | var _a;
|
5592 | while (ts30.isParenthesizedExpression(node)) {
|
5593 | node = node.expression;
|
5594 | }
|
5595 | let tsSymbol;
|
5596 | if (ts30.isPropertyAccessExpression(node)) {
|
5597 | tsSymbol = this.getTypeChecker().getSymbolAtLocation(node.name);
|
5598 | } else if (ts30.isElementAccessExpression(node)) {
|
5599 | tsSymbol = this.getTypeChecker().getSymbolAtLocation(node.argumentExpression);
|
5600 | } else {
|
5601 | tsSymbol = this.getTypeChecker().getSymbolAtLocation(node);
|
5602 | }
|
5603 | const positionInFile = this.getTcbPositionForNode(node);
|
5604 | const type = this.getTypeChecker().getTypeAtLocation(node);
|
5605 | return {
|
5606 | tsSymbol: (_a = tsSymbol != null ? tsSymbol : type.symbol) != null ? _a : null,
|
5607 | tsType: type,
|
5608 | tcbLocation: {
|
5609 | tcbPath: this.tcbPath,
|
5610 | isShimFile: this.tcbIsShim,
|
5611 | positionInFile
|
5612 | }
|
5613 | };
|
5614 | }
|
5615 | getTcbPositionForNode(node) {
|
5616 | if (ts30.isTypeReferenceNode(node)) {
|
5617 | return this.getTcbPositionForNode(node.typeName);
|
5618 | } else if (ts30.isQualifiedName(node)) {
|
5619 | return node.right.getStart();
|
5620 | } else if (ts30.isPropertyAccessExpression(node)) {
|
5621 | return node.name.getStart();
|
5622 | } else if (ts30.isElementAccessExpression(node)) {
|
5623 | return node.argumentExpression.getStart();
|
5624 | } else {
|
5625 | return node.getStart();
|
5626 | }
|
5627 | }
|
5628 | };
|
5629 | function anyNodeFilter(n) {
|
5630 | return true;
|
5631 | }
|
5632 | function sourceSpanEqual(a, b) {
|
5633 | return a.start.offset === b.start.offset && a.end.offset === b.end.offset;
|
5634 | }
|
5635 |
|
5636 |
|
5637 | var REGISTRY2 = new DomElementSchemaRegistry2();
|
5638 | var TemplateTypeCheckerImpl = class {
|
5639 | constructor(originalProgram, programDriver, typeCheckAdapter, config, refEmitter, reflector, compilerHost, priorBuild, componentScopeReader, typeCheckScopeRegistry, perf) {
|
5640 | this.originalProgram = originalProgram;
|
5641 | this.programDriver = programDriver;
|
5642 | this.typeCheckAdapter = typeCheckAdapter;
|
5643 | this.config = config;
|
5644 | this.refEmitter = refEmitter;
|
5645 | this.reflector = reflector;
|
5646 | this.compilerHost = compilerHost;
|
5647 | this.priorBuild = priorBuild;
|
5648 | this.componentScopeReader = componentScopeReader;
|
5649 | this.typeCheckScopeRegistry = typeCheckScopeRegistry;
|
5650 | this.perf = perf;
|
5651 | this.state = new Map();
|
5652 | this.completionCache = new Map();
|
5653 | this.symbolBuilderCache = new Map();
|
5654 | this.scopeCache = new Map();
|
5655 | this.elementTagCache = new Map();
|
5656 | this.isComplete = false;
|
5657 | }
|
5658 | getTemplate(component) {
|
5659 | const { data } = this.getLatestComponentState(component);
|
5660 | if (data === null) {
|
5661 | return null;
|
5662 | }
|
5663 | return data.template;
|
5664 | }
|
5665 | getLatestComponentState(component) {
|
5666 | this.ensureShimForComponent(component);
|
5667 | const sf = component.getSourceFile();
|
5668 | const sfPath = absoluteFromSourceFile(sf);
|
5669 | const shimPath = TypeCheckShimGenerator.shimFor(sfPath);
|
5670 | const fileRecord = this.getFileData(sfPath);
|
5671 | if (!fileRecord.shimData.has(shimPath)) {
|
5672 | return { data: null, tcb: null, tcbPath: shimPath, tcbIsShim: true };
|
5673 | }
|
5674 | const templateId = fileRecord.sourceManager.getTemplateId(component);
|
5675 | const shimRecord = fileRecord.shimData.get(shimPath);
|
5676 | const id = fileRecord.sourceManager.getTemplateId(component);
|
5677 | const program = this.programDriver.getProgram();
|
5678 | const shimSf = getSourceFileOrNull(program, shimPath);
|
5679 | if (shimSf === null || !fileRecord.shimData.has(shimPath)) {
|
5680 | throw new Error(`Error: no shim file in program: ${shimPath}`);
|
5681 | }
|
5682 | let tcb = findTypeCheckBlock(shimSf, id, false);
|
5683 | let tcbPath = shimPath;
|
5684 | if (tcb === null) {
|
5685 | const inlineSf = getSourceFileOrError(program, sfPath);
|
5686 | tcb = findTypeCheckBlock(inlineSf, id, false);
|
5687 | if (tcb !== null) {
|
5688 | tcbPath = sfPath;
|
5689 | }
|
5690 | }
|
5691 | let data = null;
|
5692 | if (shimRecord.templates.has(templateId)) {
|
5693 | data = shimRecord.templates.get(templateId);
|
5694 | }
|
5695 | return { data, tcb, tcbPath, tcbIsShim: tcbPath === shimPath };
|
5696 | }
|
5697 | isTrackedTypeCheckFile(filePath) {
|
5698 | return this.getFileAndShimRecordsForPath(filePath) !== null;
|
5699 | }
|
5700 | getFileRecordForTcbLocation({ tcbPath, isShimFile }) {
|
5701 | if (!isShimFile) {
|
5702 | if (this.state.has(tcbPath)) {
|
5703 | return this.state.get(tcbPath);
|
5704 | } else {
|
5705 | return null;
|
5706 | }
|
5707 | }
|
5708 | const records = this.getFileAndShimRecordsForPath(tcbPath);
|
5709 | if (records !== null) {
|
5710 | return records.fileRecord;
|
5711 | } else {
|
5712 | return null;
|
5713 | }
|
5714 | }
|
5715 | getFileAndShimRecordsForPath(shimPath) {
|
5716 | for (const fileRecord of this.state.values()) {
|
5717 | if (fileRecord.shimData.has(shimPath)) {
|
5718 | return { fileRecord, shimRecord: fileRecord.shimData.get(shimPath) };
|
5719 | }
|
5720 | }
|
5721 | return null;
|
5722 | }
|
5723 | getTemplateMappingAtTcbLocation(tcbLocation) {
|
5724 | const fileRecord = this.getFileRecordForTcbLocation(tcbLocation);
|
5725 | if (fileRecord === null) {
|
5726 | return null;
|
5727 | }
|
5728 | const shimSf = this.programDriver.getProgram().getSourceFile(tcbLocation.tcbPath);
|
5729 | if (shimSf === void 0) {
|
5730 | return null;
|
5731 | }
|
5732 | return getTemplateMapping(shimSf, tcbLocation.positionInFile, fileRecord.sourceManager, false);
|
5733 | }
|
5734 | generateAllTypeCheckBlocks() {
|
5735 | this.ensureAllShimsForAllFiles();
|
5736 | }
|
5737 | getDiagnosticsForFile(sf, optimizeFor) {
|
5738 | switch (optimizeFor) {
|
5739 | case OptimizeFor.WholeProgram:
|
5740 | this.ensureAllShimsForAllFiles();
|
5741 | break;
|
5742 | case OptimizeFor.SingleFile:
|
5743 | this.ensureAllShimsForOneFile(sf);
|
5744 | break;
|
5745 | }
|
5746 | return this.perf.inPhase(PerfPhase.TtcDiagnostics, () => {
|
5747 | const sfPath = absoluteFromSourceFile(sf);
|
5748 | const fileRecord = this.state.get(sfPath);
|
5749 | const typeCheckProgram = this.programDriver.getProgram();
|
5750 | const diagnostics = [];
|
5751 | if (fileRecord.hasInlines) {
|
5752 | const inlineSf = getSourceFileOrError(typeCheckProgram, sfPath);
|
5753 | diagnostics.push(...typeCheckProgram.getSemanticDiagnostics(inlineSf).map((diag) => convertDiagnostic(diag, fileRecord.sourceManager)));
|
5754 | }
|
5755 | for (const [shimPath, shimRecord] of fileRecord.shimData) {
|
5756 | const shimSf = getSourceFileOrError(typeCheckProgram, shimPath);
|
5757 | diagnostics.push(...typeCheckProgram.getSemanticDiagnostics(shimSf).map((diag) => convertDiagnostic(diag, fileRecord.sourceManager)));
|
5758 | diagnostics.push(...shimRecord.genesisDiagnostics);
|
5759 | for (const templateData of shimRecord.templates.values()) {
|
5760 | diagnostics.push(...templateData.templateDiagnostics);
|
5761 | }
|
5762 | }
|
5763 | return diagnostics.filter((diag) => diag !== null);
|
5764 | });
|
5765 | }
|
5766 | getDiagnosticsForComponent(component) {
|
5767 | this.ensureShimForComponent(component);
|
5768 | return this.perf.inPhase(PerfPhase.TtcDiagnostics, () => {
|
5769 | const sf = component.getSourceFile();
|
5770 | const sfPath = absoluteFromSourceFile(sf);
|
5771 | const shimPath = TypeCheckShimGenerator.shimFor(sfPath);
|
5772 | const fileRecord = this.getFileData(sfPath);
|
5773 | if (!fileRecord.shimData.has(shimPath)) {
|
5774 | return [];
|
5775 | }
|
5776 | const templateId = fileRecord.sourceManager.getTemplateId(component);
|
5777 | const shimRecord = fileRecord.shimData.get(shimPath);
|
5778 | const typeCheckProgram = this.programDriver.getProgram();
|
5779 | const diagnostics = [];
|
5780 | if (shimRecord.hasInlines) {
|
5781 | const inlineSf = getSourceFileOrError(typeCheckProgram, sfPath);
|
5782 | diagnostics.push(...typeCheckProgram.getSemanticDiagnostics(inlineSf).map((diag) => convertDiagnostic(diag, fileRecord.sourceManager)));
|
5783 | }
|
5784 | const shimSf = getSourceFileOrError(typeCheckProgram, shimPath);
|
5785 | diagnostics.push(...typeCheckProgram.getSemanticDiagnostics(shimSf).map((diag) => convertDiagnostic(diag, fileRecord.sourceManager)));
|
5786 | diagnostics.push(...shimRecord.genesisDiagnostics);
|
5787 | for (const templateData of shimRecord.templates.values()) {
|
5788 | diagnostics.push(...templateData.templateDiagnostics);
|
5789 | }
|
5790 | return diagnostics.filter((diag) => diag !== null && diag.templateId === templateId);
|
5791 | });
|
5792 | }
|
5793 | getTypeCheckBlock(component) {
|
5794 | return this.getLatestComponentState(component).tcb;
|
5795 | }
|
5796 | getGlobalCompletions(context, component, node) {
|
5797 | const engine = this.getOrCreateCompletionEngine(component);
|
5798 | if (engine === null) {
|
5799 | return null;
|
5800 | }
|
5801 | return this.perf.inPhase(PerfPhase.TtcAutocompletion, () => engine.getGlobalCompletions(context, node));
|
5802 | }
|
5803 | getExpressionCompletionLocation(ast, component) {
|
5804 | const engine = this.getOrCreateCompletionEngine(component);
|
5805 | if (engine === null) {
|
5806 | return null;
|
5807 | }
|
5808 | return this.perf.inPhase(PerfPhase.TtcAutocompletion, () => engine.getExpressionCompletionLocation(ast));
|
5809 | }
|
5810 | getLiteralCompletionLocation(node, component) {
|
5811 | const engine = this.getOrCreateCompletionEngine(component);
|
5812 | if (engine === null) {
|
5813 | return null;
|
5814 | }
|
5815 | return this.perf.inPhase(PerfPhase.TtcAutocompletion, () => engine.getLiteralCompletionLocation(node));
|
5816 | }
|
5817 | invalidateClass(clazz) {
|
5818 | this.completionCache.delete(clazz);
|
5819 | this.symbolBuilderCache.delete(clazz);
|
5820 | this.scopeCache.delete(clazz);
|
5821 | this.elementTagCache.delete(clazz);
|
5822 | const sf = clazz.getSourceFile();
|
5823 | const sfPath = absoluteFromSourceFile(sf);
|
5824 | const shimPath = TypeCheckShimGenerator.shimFor(sfPath);
|
5825 | const fileData = this.getFileData(sfPath);
|
5826 | const templateId = fileData.sourceManager.getTemplateId(clazz);
|
5827 | fileData.shimData.delete(shimPath);
|
5828 | fileData.isComplete = false;
|
5829 | this.isComplete = false;
|
5830 | }
|
5831 | makeTemplateDiagnostic(clazz, sourceSpan, category, errorCode, message, relatedInformation) {
|
5832 | const sfPath = absoluteFromSourceFile(clazz.getSourceFile());
|
5833 | const fileRecord = this.state.get(sfPath);
|
5834 | const templateId = fileRecord.sourceManager.getTemplateId(clazz);
|
5835 | const mapping = fileRecord.sourceManager.getSourceMapping(templateId);
|
5836 | return __spreadProps(__spreadValues({}, makeTemplateDiagnostic(templateId, mapping, sourceSpan, category, ngErrorCode(errorCode), message, relatedInformation)), {
|
5837 | __ngCode: errorCode
|
5838 | });
|
5839 | }
|
5840 | getOrCreateCompletionEngine(component) {
|
5841 | if (this.completionCache.has(component)) {
|
5842 | return this.completionCache.get(component);
|
5843 | }
|
5844 | const { tcb, data, tcbPath, tcbIsShim } = this.getLatestComponentState(component);
|
5845 | if (tcb === null || data === null) {
|
5846 | return null;
|
5847 | }
|
5848 | const engine = new CompletionEngine(tcb, data, tcbPath, tcbIsShim);
|
5849 | this.completionCache.set(component, engine);
|
5850 | return engine;
|
5851 | }
|
5852 | maybeAdoptPriorResultsForFile(sf) {
|
5853 | const sfPath = absoluteFromSourceFile(sf);
|
5854 | if (this.state.has(sfPath)) {
|
5855 | const existingResults = this.state.get(sfPath);
|
5856 | if (existingResults.isComplete) {
|
5857 | return;
|
5858 | }
|
5859 | }
|
5860 | const previousResults = this.priorBuild.priorTypeCheckingResultsFor(sf);
|
5861 | if (previousResults === null || !previousResults.isComplete) {
|
5862 | return;
|
5863 | }
|
5864 | this.perf.eventCount(PerfEvent.ReuseTypeCheckFile);
|
5865 | this.state.set(sfPath, previousResults);
|
5866 | }
|
5867 | ensureAllShimsForAllFiles() {
|
5868 | if (this.isComplete) {
|
5869 | return;
|
5870 | }
|
5871 | this.perf.inPhase(PerfPhase.TcbGeneration, () => {
|
5872 | const host = new WholeProgramTypeCheckingHost(this);
|
5873 | const ctx = this.newContext(host);
|
5874 | for (const sf of this.originalProgram.getSourceFiles()) {
|
5875 | if (sf.isDeclarationFile || isShim(sf)) {
|
5876 | continue;
|
5877 | }
|
5878 | this.maybeAdoptPriorResultsForFile(sf);
|
5879 | const sfPath = absoluteFromSourceFile(sf);
|
5880 | const fileData = this.getFileData(sfPath);
|
5881 | if (fileData.isComplete) {
|
5882 | continue;
|
5883 | }
|
5884 | this.typeCheckAdapter.typeCheck(sf, ctx);
|
5885 | fileData.isComplete = true;
|
5886 | }
|
5887 | this.updateFromContext(ctx);
|
5888 | this.isComplete = true;
|
5889 | });
|
5890 | }
|
5891 | ensureAllShimsForOneFile(sf) {
|
5892 | this.perf.inPhase(PerfPhase.TcbGeneration, () => {
|
5893 | this.maybeAdoptPriorResultsForFile(sf);
|
5894 | const sfPath = absoluteFromSourceFile(sf);
|
5895 | const fileData = this.getFileData(sfPath);
|
5896 | if (fileData.isComplete) {
|
5897 | return;
|
5898 | }
|
5899 | const host = new SingleFileTypeCheckingHost(sfPath, fileData, this);
|
5900 | const ctx = this.newContext(host);
|
5901 | this.typeCheckAdapter.typeCheck(sf, ctx);
|
5902 | fileData.isComplete = true;
|
5903 | this.updateFromContext(ctx);
|
5904 | });
|
5905 | }
|
5906 | ensureShimForComponent(component) {
|
5907 | const sf = component.getSourceFile();
|
5908 | const sfPath = absoluteFromSourceFile(sf);
|
5909 | const shimPath = TypeCheckShimGenerator.shimFor(sfPath);
|
5910 | this.maybeAdoptPriorResultsForFile(sf);
|
5911 | const fileData = this.getFileData(sfPath);
|
5912 | if (fileData.shimData.has(shimPath)) {
|
5913 | return;
|
5914 | }
|
5915 | const host = new SingleShimTypeCheckingHost(sfPath, fileData, this, shimPath);
|
5916 | const ctx = this.newContext(host);
|
5917 | this.typeCheckAdapter.typeCheck(sf, ctx);
|
5918 | this.updateFromContext(ctx);
|
5919 | }
|
5920 | newContext(host) {
|
5921 | const inlining = this.programDriver.supportsInlineOperations ? InliningMode.InlineOps : InliningMode.Error;
|
5922 | return new TypeCheckContextImpl(this.config, this.compilerHost, this.refEmitter, this.reflector, host, inlining, this.perf);
|
5923 | }
|
5924 | clearAllShimDataUsingInlines() {
|
5925 | for (const fileData of this.state.values()) {
|
5926 | if (!fileData.hasInlines) {
|
5927 | continue;
|
5928 | }
|
5929 | for (const [shimFile, shimData] of fileData.shimData.entries()) {
|
5930 | if (shimData.hasInlines) {
|
5931 | fileData.shimData.delete(shimFile);
|
5932 | }
|
5933 | }
|
5934 | fileData.hasInlines = false;
|
5935 | fileData.isComplete = false;
|
5936 | this.isComplete = false;
|
5937 | }
|
5938 | }
|
5939 | updateFromContext(ctx) {
|
5940 | const updates = ctx.finalize();
|
5941 | return this.perf.inPhase(PerfPhase.TcbUpdateProgram, () => {
|
5942 | if (updates.size > 0) {
|
5943 | this.perf.eventCount(PerfEvent.UpdateTypeCheckProgram);
|
5944 | }
|
5945 | this.programDriver.updateFiles(updates, UpdateMode.Incremental);
|
5946 | this.priorBuild.recordSuccessfulTypeCheck(this.state);
|
5947 | this.perf.memory(PerfCheckpoint.TtcUpdateProgram);
|
5948 | });
|
5949 | }
|
5950 | getFileData(path2) {
|
5951 | if (!this.state.has(path2)) {
|
5952 | this.state.set(path2, {
|
5953 | hasInlines: false,
|
5954 | sourceManager: new TemplateSourceManager(),
|
5955 | isComplete: false,
|
5956 | shimData: new Map()
|
5957 | });
|
5958 | }
|
5959 | return this.state.get(path2);
|
5960 | }
|
5961 | getSymbolOfNode(node, component) {
|
5962 | const builder = this.getOrCreateSymbolBuilder(component);
|
5963 | if (builder === null) {
|
5964 | return null;
|
5965 | }
|
5966 | return this.perf.inPhase(PerfPhase.TtcSymbol, () => builder.getSymbol(node));
|
5967 | }
|
5968 | getOrCreateSymbolBuilder(component) {
|
5969 | if (this.symbolBuilderCache.has(component)) {
|
5970 | return this.symbolBuilderCache.get(component);
|
5971 | }
|
5972 | const { tcb, data, tcbPath, tcbIsShim } = this.getLatestComponentState(component);
|
5973 | if (tcb === null || data === null) {
|
5974 | return null;
|
5975 | }
|
5976 | const builder = new SymbolBuilder(tcbPath, tcbIsShim, tcb, data, this.componentScopeReader, () => this.programDriver.getProgram().getTypeChecker());
|
5977 | this.symbolBuilderCache.set(component, builder);
|
5978 | return builder;
|
5979 | }
|
5980 | getDirectivesInScope(component) {
|
5981 | const data = this.getScopeData(component);
|
5982 | if (data === null) {
|
5983 | return null;
|
5984 | }
|
5985 | return data.directives;
|
5986 | }
|
5987 | getPipesInScope(component) {
|
5988 | const data = this.getScopeData(component);
|
5989 | if (data === null) {
|
5990 | return null;
|
5991 | }
|
5992 | return data.pipes;
|
5993 | }
|
5994 | getDirectiveMetadata(dir) {
|
5995 | if (!isNamedClassDeclaration(dir)) {
|
5996 | return null;
|
5997 | }
|
5998 | return this.typeCheckScopeRegistry.getTypeCheckDirectiveMetadata(new Reference(dir));
|
5999 | }
|
6000 | getPotentialElementTags(component) {
|
6001 | if (this.elementTagCache.has(component)) {
|
6002 | return this.elementTagCache.get(component);
|
6003 | }
|
6004 | const tagMap = new Map();
|
6005 | for (const tag of REGISTRY2.allKnownElementNames()) {
|
6006 | tagMap.set(tag, null);
|
6007 | }
|
6008 | const scope = this.getScopeData(component);
|
6009 | if (scope !== null) {
|
6010 | for (const directive of scope.directives) {
|
6011 | for (const selector of CssSelector2.parse(directive.selector)) {
|
6012 | if (selector.element === null || tagMap.has(selector.element)) {
|
6013 | continue;
|
6014 | }
|
6015 | tagMap.set(selector.element, directive);
|
6016 | }
|
6017 | }
|
6018 | }
|
6019 | this.elementTagCache.set(component, tagMap);
|
6020 | return tagMap;
|
6021 | }
|
6022 | getPotentialDomBindings(tagName) {
|
6023 | const attributes = REGISTRY2.allKnownAttributesOfElement(tagName);
|
6024 | return attributes.map((attribute) => ({
|
6025 | attribute,
|
6026 | property: REGISTRY2.getMappedPropName(attribute)
|
6027 | }));
|
6028 | }
|
6029 | getPotentialDomEvents(tagName) {
|
6030 | return REGISTRY2.allKnownEventsOfElement(tagName);
|
6031 | }
|
6032 | getScopeData(component) {
|
6033 | if (this.scopeCache.has(component)) {
|
6034 | return this.scopeCache.get(component);
|
6035 | }
|
6036 | if (!isNamedClassDeclaration(component)) {
|
6037 | throw new Error(`AssertionError: components must have names`);
|
6038 | }
|
6039 | const scope = this.componentScopeReader.getScopeForComponent(component);
|
6040 | if (scope === null) {
|
6041 | return null;
|
6042 | }
|
6043 | const data = {
|
6044 | directives: [],
|
6045 | pipes: [],
|
6046 | isPoisoned: scope.compilation.isPoisoned
|
6047 | };
|
6048 | const typeChecker = this.programDriver.getProgram().getTypeChecker();
|
6049 | for (const dir of scope.compilation.directives) {
|
6050 | if (dir.selector === null) {
|
6051 | continue;
|
6052 | }
|
6053 | const tsSymbol = typeChecker.getSymbolAtLocation(dir.ref.node.name);
|
6054 | if (!isSymbolWithValueDeclaration(tsSymbol)) {
|
6055 | continue;
|
6056 | }
|
6057 | let ngModule = null;
|
6058 | const moduleScopeOfDir = this.componentScopeReader.getScopeForComponent(dir.ref.node);
|
6059 | if (moduleScopeOfDir !== null) {
|
6060 | ngModule = moduleScopeOfDir.ngModule;
|
6061 | }
|
6062 | data.directives.push({
|
6063 | isComponent: dir.isComponent,
|
6064 | isStructural: dir.isStructural,
|
6065 | selector: dir.selector,
|
6066 | tsSymbol,
|
6067 | ngModule
|
6068 | });
|
6069 | }
|
6070 | for (const pipe of scope.compilation.pipes) {
|
6071 | const tsSymbol = typeChecker.getSymbolAtLocation(pipe.ref.node.name);
|
6072 | if (tsSymbol === void 0) {
|
6073 | continue;
|
6074 | }
|
6075 | data.pipes.push({
|
6076 | name: pipe.name,
|
6077 | tsSymbol
|
6078 | });
|
6079 | }
|
6080 | this.scopeCache.set(component, data);
|
6081 | return data;
|
6082 | }
|
6083 | };
|
6084 | function convertDiagnostic(diag, sourceResolver) {
|
6085 | if (!shouldReportDiagnostic(diag)) {
|
6086 | return null;
|
6087 | }
|
6088 | return translateDiagnostic(diag, sourceResolver);
|
6089 | }
|
6090 | var WholeProgramTypeCheckingHost = class {
|
6091 | constructor(impl) {
|
6092 | this.impl = impl;
|
6093 | }
|
6094 | getSourceManager(sfPath) {
|
6095 | return this.impl.getFileData(sfPath).sourceManager;
|
6096 | }
|
6097 | shouldCheckComponent(node) {
|
6098 | const sfPath = absoluteFromSourceFile(node.getSourceFile());
|
6099 | const shimPath = TypeCheckShimGenerator.shimFor(sfPath);
|
6100 | const fileData = this.impl.getFileData(sfPath);
|
6101 | return !fileData.shimData.has(shimPath);
|
6102 | }
|
6103 | recordShimData(sfPath, data) {
|
6104 | const fileData = this.impl.getFileData(sfPath);
|
6105 | fileData.shimData.set(data.path, data);
|
6106 | if (data.hasInlines) {
|
6107 | fileData.hasInlines = true;
|
6108 | }
|
6109 | }
|
6110 | recordComplete(sfPath) {
|
6111 | this.impl.getFileData(sfPath).isComplete = true;
|
6112 | }
|
6113 | };
|
6114 | var SingleFileTypeCheckingHost = class {
|
6115 | constructor(sfPath, fileData, impl) {
|
6116 | this.sfPath = sfPath;
|
6117 | this.fileData = fileData;
|
6118 | this.impl = impl;
|
6119 | this.seenInlines = false;
|
6120 | }
|
6121 | assertPath(sfPath) {
|
6122 | if (this.sfPath !== sfPath) {
|
6123 | throw new Error(`AssertionError: querying TypeCheckingHost outside of assigned file`);
|
6124 | }
|
6125 | }
|
6126 | getSourceManager(sfPath) {
|
6127 | this.assertPath(sfPath);
|
6128 | return this.fileData.sourceManager;
|
6129 | }
|
6130 | shouldCheckComponent(node) {
|
6131 | if (this.sfPath !== absoluteFromSourceFile(node.getSourceFile())) {
|
6132 | return false;
|
6133 | }
|
6134 | const shimPath = TypeCheckShimGenerator.shimFor(this.sfPath);
|
6135 | return !this.fileData.shimData.has(shimPath);
|
6136 | }
|
6137 | recordShimData(sfPath, data) {
|
6138 | this.assertPath(sfPath);
|
6139 | if (data.hasInlines && !this.seenInlines) {
|
6140 | this.impl.clearAllShimDataUsingInlines();
|
6141 | this.seenInlines = true;
|
6142 | }
|
6143 | this.fileData.shimData.set(data.path, data);
|
6144 | if (data.hasInlines) {
|
6145 | this.fileData.hasInlines = true;
|
6146 | }
|
6147 | }
|
6148 | recordComplete(sfPath) {
|
6149 | this.assertPath(sfPath);
|
6150 | this.fileData.isComplete = true;
|
6151 | }
|
6152 | };
|
6153 | var SingleShimTypeCheckingHost = class extends SingleFileTypeCheckingHost {
|
6154 | constructor(sfPath, fileData, impl, shimPath) {
|
6155 | super(sfPath, fileData, impl);
|
6156 | this.shimPath = shimPath;
|
6157 | }
|
6158 | shouldCheckNode(node) {
|
6159 | if (this.sfPath !== absoluteFromSourceFile(node.getSourceFile())) {
|
6160 | return false;
|
6161 | }
|
6162 | const shimPath = TypeCheckShimGenerator.shimFor(this.sfPath);
|
6163 | if (shimPath !== this.shimPath) {
|
6164 | return false;
|
6165 | }
|
6166 | return !this.fileData.shimData.has(shimPath);
|
6167 | }
|
6168 | };
|
6169 |
|
6170 |
|
6171 | import { TmplAstBoundEvent as TmplAstBoundEvent2 } from "@angular/compiler";
|
6172 |
|
6173 |
|
6174 | import { ASTWithSource as ASTWithSource4, RecursiveAstVisitor as RecursiveAstVisitor3 } from "@angular/compiler";
|
6175 | var TemplateCheckWithVisitor = class {
|
6176 | run(ctx, component, template) {
|
6177 | const visitor = new TemplateVisitor2(ctx, component, this);
|
6178 | return visitor.getDiagnostics(template);
|
6179 | }
|
6180 | };
|
6181 | var TemplateVisitor2 = class extends RecursiveAstVisitor3 {
|
6182 | constructor(ctx, component, check) {
|
6183 | super();
|
6184 | this.ctx = ctx;
|
6185 | this.component = component;
|
6186 | this.check = check;
|
6187 | this.diagnostics = [];
|
6188 | }
|
6189 | visit(node, context) {
|
6190 | this.diagnostics.push(...this.check.visitNode(this.ctx, this.component, node));
|
6191 | node.visit(this);
|
6192 | }
|
6193 | visitAllNodes(nodes) {
|
6194 | for (const node of nodes) {
|
6195 | this.visit(node);
|
6196 | }
|
6197 | }
|
6198 | visitAst(ast) {
|
6199 | if (ast instanceof ASTWithSource4) {
|
6200 | ast = ast.ast;
|
6201 | }
|
6202 | this.visit(ast);
|
6203 | }
|
6204 | visitElement(element) {
|
6205 | this.visitAllNodes(element.attributes);
|
6206 | this.visitAllNodes(element.inputs);
|
6207 | this.visitAllNodes(element.outputs);
|
6208 | this.visitAllNodes(element.references);
|
6209 | this.visitAllNodes(element.children);
|
6210 | }
|
6211 | visitTemplate(template) {
|
6212 | this.visitAllNodes(template.attributes);
|
6213 | if (template.tagName === "ng-template") {
|
6214 | this.visitAllNodes(template.inputs);
|
6215 | this.visitAllNodes(template.outputs);
|
6216 | this.visitAllNodes(template.templateAttrs);
|
6217 | }
|
6218 | this.visitAllNodes(template.variables);
|
6219 | this.visitAllNodes(template.references);
|
6220 | this.visitAllNodes(template.children);
|
6221 | }
|
6222 | visitContent(content) {
|
6223 | }
|
6224 | visitVariable(variable) {
|
6225 | }
|
6226 | visitReference(reference) {
|
6227 | }
|
6228 | visitTextAttribute(attribute) {
|
6229 | }
|
6230 | visitBoundAttribute(attribute) {
|
6231 | this.visitAst(attribute.value);
|
6232 | }
|
6233 | visitBoundEvent(attribute) {
|
6234 | this.visitAst(attribute.handler);
|
6235 | }
|
6236 | visitText(text) {
|
6237 | }
|
6238 | visitBoundText(text) {
|
6239 | this.visitAst(text.value);
|
6240 | }
|
6241 | visitIcu(icu) {
|
6242 | }
|
6243 | getDiagnostics(template) {
|
6244 | this.diagnostics = [];
|
6245 | this.visitAllNodes(template);
|
6246 | return this.diagnostics;
|
6247 | }
|
6248 | };
|
6249 |
|
6250 |
|
6251 | var InvalidBananaInBoxCheck = class extends TemplateCheckWithVisitor {
|
6252 | constructor() {
|
6253 | super(...arguments);
|
6254 | this.code = ErrorCode.INVALID_BANANA_IN_BOX;
|
6255 | }
|
6256 | visitNode(ctx, component, node) {
|
6257 | if (!(node instanceof TmplAstBoundEvent2))
|
6258 | return [];
|
6259 | const name = node.name;
|
6260 | if (!name.startsWith("[") || !name.endsWith("]"))
|
6261 | return [];
|
6262 | const boundSyntax = node.sourceSpan.toString();
|
6263 | const expectedBoundSyntax = boundSyntax.replace(`(${name})`, `[(${name.slice(1, -1)})]`);
|
6264 | const diagnostic = ctx.makeTemplateDiagnostic(node.sourceSpan, `In the two-way binding syntax the parentheses should be inside the brackets, ex. '${expectedBoundSyntax}'.
|
6265 | Find more at https://angular.io/guide/two-way-binding`);
|
6266 | return [diagnostic];
|
6267 | }
|
6268 | };
|
6269 | var factory = {
|
6270 | code: ErrorCode.INVALID_BANANA_IN_BOX,
|
6271 | name: ExtendedTemplateDiagnosticName.INVALID_BANANA_IN_BOX,
|
6272 | create: () => new InvalidBananaInBoxCheck()
|
6273 | };
|
6274 |
|
6275 |
|
6276 | import { Binary } from "@angular/compiler";
|
6277 | import ts31 from "typescript";
|
6278 | var NullishCoalescingNotNullableCheck = class extends TemplateCheckWithVisitor {
|
6279 | constructor() {
|
6280 | super(...arguments);
|
6281 | this.code = ErrorCode.NULLISH_COALESCING_NOT_NULLABLE;
|
6282 | }
|
6283 | visitNode(ctx, component, node) {
|
6284 | if (!(node instanceof Binary) || node.operation !== "??")
|
6285 | return [];
|
6286 | const symbolLeft = ctx.templateTypeChecker.getSymbolOfNode(node.left, component);
|
6287 | if (symbolLeft === null || symbolLeft.kind !== SymbolKind.Expression) {
|
6288 | return [];
|
6289 | }
|
6290 | const typeLeft = symbolLeft.tsType;
|
6291 | if (typeLeft.flags & (ts31.TypeFlags.Any | ts31.TypeFlags.Unknown)) {
|
6292 | return [];
|
6293 | }
|
6294 | if (typeLeft.getNonNullableType() !== typeLeft)
|
6295 | return [];
|
6296 | const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
|
6297 | if (symbol.kind !== SymbolKind.Expression) {
|
6298 | return [];
|
6299 | }
|
6300 | const templateMapping = ctx.templateTypeChecker.getTemplateMappingAtTcbLocation(symbol.tcbLocation);
|
6301 | if (templateMapping === null) {
|
6302 | return [];
|
6303 | }
|
6304 | const diagnostic = ctx.makeTemplateDiagnostic(templateMapping.span, `The left side of this nullish coalescing operation does not include 'null' or 'undefined' in its type, therefore the '??' operator can be safely removed.`);
|
6305 | return [diagnostic];
|
6306 | }
|
6307 | };
|
6308 | var factory2 = {
|
6309 | code: ErrorCode.NULLISH_COALESCING_NOT_NULLABLE,
|
6310 | name: ExtendedTemplateDiagnosticName.NULLISH_COALESCING_NOT_NULLABLE,
|
6311 | create: (options) => {
|
6312 | const strictNullChecks = options.strictNullChecks === void 0 ? !!options.strict : !!options.strictNullChecks;
|
6313 | if (!strictNullChecks) {
|
6314 | return null;
|
6315 | }
|
6316 | return new NullishCoalescingNotNullableCheck();
|
6317 | }
|
6318 | };
|
6319 |
|
6320 |
|
6321 | import ts32 from "typescript";
|
6322 |
|
6323 |
|
6324 | var DiagnosticCategoryLabel;
|
6325 | (function(DiagnosticCategoryLabel2) {
|
6326 | DiagnosticCategoryLabel2["Warning"] = "warning";
|
6327 | DiagnosticCategoryLabel2["Error"] = "error";
|
6328 | DiagnosticCategoryLabel2["Suppress"] = "suppress";
|
6329 | })(DiagnosticCategoryLabel || (DiagnosticCategoryLabel = {}));
|
6330 |
|
6331 |
|
6332 | var ExtendedTemplateCheckerImpl = class {
|
6333 | constructor(templateTypeChecker, typeChecker, templateCheckFactories, options) {
|
6334 | var _a, _b, _c, _d, _e;
|
6335 | this.partialCtx = { templateTypeChecker, typeChecker };
|
6336 | this.templateChecks = new Map();
|
6337 | for (const factory3 of templateCheckFactories) {
|
6338 | const category = diagnosticLabelToCategory((_e = (_d = (_b = (_a = options == null ? void 0 : options.extendedDiagnostics) == null ? void 0 : _a.checks) == null ? void 0 : _b[factory3.name]) != null ? _d : (_c = options == null ? void 0 : options.extendedDiagnostics) == null ? void 0 : _c.defaultCategory) != null ? _e : DiagnosticCategoryLabel.Warning);
|
6339 | if (category === null) {
|
6340 | continue;
|
6341 | }
|
6342 | const check = factory3.create(options);
|
6343 | if (check === null) {
|
6344 | continue;
|
6345 | }
|
6346 | this.templateChecks.set(check, category);
|
6347 | }
|
6348 | }
|
6349 | getDiagnosticsForComponent(component) {
|
6350 | const template = this.partialCtx.templateTypeChecker.getTemplate(component);
|
6351 | if (template === null) {
|
6352 | return [];
|
6353 | }
|
6354 | const diagnostics = [];
|
6355 | for (const [check, category] of this.templateChecks.entries()) {
|
6356 | const ctx = __spreadProps(__spreadValues({}, this.partialCtx), {
|
6357 | makeTemplateDiagnostic: (span, message, relatedInformation) => {
|
6358 | return this.partialCtx.templateTypeChecker.makeTemplateDiagnostic(component, span, category, check.code, message, relatedInformation);
|
6359 | }
|
6360 | });
|
6361 | diagnostics.push(...check.run(ctx, component, template));
|
6362 | }
|
6363 | return diagnostics;
|
6364 | }
|
6365 | };
|
6366 | function diagnosticLabelToCategory(label) {
|
6367 | switch (label) {
|
6368 | case DiagnosticCategoryLabel.Warning:
|
6369 | return ts32.DiagnosticCategory.Warning;
|
6370 | case DiagnosticCategoryLabel.Error:
|
6371 | return ts32.DiagnosticCategory.Error;
|
6372 | case DiagnosticCategoryLabel.Suppress:
|
6373 | return null;
|
6374 | default:
|
6375 | return assertNever(label);
|
6376 | }
|
6377 | }
|
6378 | function assertNever(value) {
|
6379 | throw new Error(`Unexpected call to 'assertNever()' with value:
|
6380 | ${value}`);
|
6381 | }
|
6382 |
|
6383 |
|
6384 | var ALL_DIAGNOSTIC_FACTORIES = [
|
6385 | factory,
|
6386 | factory2
|
6387 | ];
|
6388 |
|
6389 |
|
6390 | var CompilationTicketKind;
|
6391 | (function(CompilationTicketKind2) {
|
6392 | CompilationTicketKind2[CompilationTicketKind2["Fresh"] = 0] = "Fresh";
|
6393 | CompilationTicketKind2[CompilationTicketKind2["IncrementalTypeScript"] = 1] = "IncrementalTypeScript";
|
6394 | CompilationTicketKind2[CompilationTicketKind2["IncrementalResource"] = 2] = "IncrementalResource";
|
6395 | })(CompilationTicketKind || (CompilationTicketKind = {}));
|
6396 | function freshCompilationTicket(tsProgram, options, incrementalBuildStrategy, programDriver, perfRecorder, enableTemplateTypeChecker, usePoisonedData) {
|
6397 | return {
|
6398 | kind: CompilationTicketKind.Fresh,
|
6399 | tsProgram,
|
6400 | options,
|
6401 | incrementalBuildStrategy,
|
6402 | programDriver,
|
6403 | enableTemplateTypeChecker,
|
6404 | usePoisonedData,
|
6405 | perfRecorder: perfRecorder != null ? perfRecorder : ActivePerfRecorder.zeroedToNow()
|
6406 | };
|
6407 | }
|
6408 | function incrementalFromCompilerTicket(oldCompiler, newProgram, incrementalBuildStrategy, programDriver, modifiedResourceFiles, perfRecorder) {
|
6409 | const oldProgram = oldCompiler.getCurrentProgram();
|
6410 | const oldState = oldCompiler.incrementalStrategy.getIncrementalState(oldProgram);
|
6411 | if (oldState === null) {
|
6412 | return freshCompilationTicket(newProgram, oldCompiler.options, incrementalBuildStrategy, programDriver, perfRecorder, oldCompiler.enableTemplateTypeChecker, oldCompiler.usePoisonedData);
|
6413 | }
|
6414 | if (perfRecorder === null) {
|
6415 | perfRecorder = ActivePerfRecorder.zeroedToNow();
|
6416 | }
|
6417 | const incrementalCompilation = IncrementalCompilation.incremental(newProgram, versionMapFromProgram(newProgram, programDriver), oldProgram, oldState, modifiedResourceFiles, perfRecorder);
|
6418 | return {
|
6419 | kind: CompilationTicketKind.IncrementalTypeScript,
|
6420 | enableTemplateTypeChecker: oldCompiler.enableTemplateTypeChecker,
|
6421 | usePoisonedData: oldCompiler.usePoisonedData,
|
6422 | options: oldCompiler.options,
|
6423 | incrementalBuildStrategy,
|
6424 | incrementalCompilation,
|
6425 | programDriver,
|
6426 | newProgram,
|
6427 | perfRecorder
|
6428 | };
|
6429 | }
|
6430 | function incrementalFromStateTicket(oldProgram, oldState, newProgram, options, incrementalBuildStrategy, programDriver, modifiedResourceFiles, perfRecorder, enableTemplateTypeChecker, usePoisonedData) {
|
6431 | if (perfRecorder === null) {
|
6432 | perfRecorder = ActivePerfRecorder.zeroedToNow();
|
6433 | }
|
6434 | const incrementalCompilation = IncrementalCompilation.incremental(newProgram, versionMapFromProgram(newProgram, programDriver), oldProgram, oldState, modifiedResourceFiles, perfRecorder);
|
6435 | return {
|
6436 | kind: CompilationTicketKind.IncrementalTypeScript,
|
6437 | newProgram,
|
6438 | options,
|
6439 | incrementalBuildStrategy,
|
6440 | incrementalCompilation,
|
6441 | programDriver,
|
6442 | enableTemplateTypeChecker,
|
6443 | usePoisonedData,
|
6444 | perfRecorder
|
6445 | };
|
6446 | }
|
6447 | var NgCompiler = class {
|
6448 | constructor(adapter, options, inputProgram, programDriver, incrementalStrategy, incrementalCompilation, enableTemplateTypeChecker, usePoisonedData, livePerfRecorder) {
|
6449 | this.adapter = adapter;
|
6450 | this.options = options;
|
6451 | this.inputProgram = inputProgram;
|
6452 | this.programDriver = programDriver;
|
6453 | this.incrementalStrategy = incrementalStrategy;
|
6454 | this.incrementalCompilation = incrementalCompilation;
|
6455 | this.enableTemplateTypeChecker = enableTemplateTypeChecker;
|
6456 | this.usePoisonedData = usePoisonedData;
|
6457 | this.livePerfRecorder = livePerfRecorder;
|
6458 | this.compilation = null;
|
6459 | this.constructionDiagnostics = [];
|
6460 | this.nonTemplateDiagnostics = null;
|
6461 | this.delegatingPerfRecorder = new DelegatingPerfRecorder(this.perfRecorder);
|
6462 | this.constructionDiagnostics.push(...this.adapter.constructionDiagnostics, ...verifyCompatibleTypeCheckOptions(this.options));
|
6463 | this.currentProgram = inputProgram;
|
6464 | this.closureCompilerEnabled = !!this.options.annotateForClosureCompiler;
|
6465 | this.entryPoint = adapter.entryPoint !== null ? getSourceFileOrNull(inputProgram, adapter.entryPoint) : null;
|
6466 | const moduleResolutionCache = ts33.createModuleResolutionCache(this.adapter.getCurrentDirectory(), this.adapter.getCanonicalFileName.bind(this.adapter));
|
6467 | this.moduleResolver = new ModuleResolver(inputProgram, this.options, this.adapter, moduleResolutionCache);
|
6468 | this.resourceManager = new AdapterResourceLoader(adapter, this.options);
|
6469 | this.cycleAnalyzer = new CycleAnalyzer(new ImportGraph(inputProgram.getTypeChecker(), this.delegatingPerfRecorder));
|
6470 | this.incrementalStrategy.setIncrementalState(this.incrementalCompilation.state, inputProgram);
|
6471 | this.ignoreForDiagnostics = new Set(inputProgram.getSourceFiles().filter((sf) => this.adapter.isShim(sf)));
|
6472 | this.ignoreForEmit = this.adapter.ignoreForEmit;
|
6473 | let dtsFileCount = 0;
|
6474 | let nonDtsFileCount = 0;
|
6475 | for (const sf of inputProgram.getSourceFiles()) {
|
6476 | if (sf.isDeclarationFile) {
|
6477 | dtsFileCount++;
|
6478 | } else {
|
6479 | nonDtsFileCount++;
|
6480 | }
|
6481 | }
|
6482 | livePerfRecorder.eventCount(PerfEvent.InputDtsFile, dtsFileCount);
|
6483 | livePerfRecorder.eventCount(PerfEvent.InputTsFile, nonDtsFileCount);
|
6484 | }
|
6485 | static fromTicket(ticket, adapter) {
|
6486 | switch (ticket.kind) {
|
6487 | case CompilationTicketKind.Fresh:
|
6488 | return new NgCompiler(adapter, ticket.options, ticket.tsProgram, ticket.programDriver, ticket.incrementalBuildStrategy, IncrementalCompilation.fresh(ticket.tsProgram, versionMapFromProgram(ticket.tsProgram, ticket.programDriver)), ticket.enableTemplateTypeChecker, ticket.usePoisonedData, ticket.perfRecorder);
|
6489 | case CompilationTicketKind.IncrementalTypeScript:
|
6490 | return new NgCompiler(adapter, ticket.options, ticket.newProgram, ticket.programDriver, ticket.incrementalBuildStrategy, ticket.incrementalCompilation, ticket.enableTemplateTypeChecker, ticket.usePoisonedData, ticket.perfRecorder);
|
6491 | case CompilationTicketKind.IncrementalResource:
|
6492 | const compiler = ticket.compiler;
|
6493 | compiler.updateWithChangedResources(ticket.modifiedResourceFiles, ticket.perfRecorder);
|
6494 | return compiler;
|
6495 | }
|
6496 | }
|
6497 | get perfRecorder() {
|
6498 | return this.livePerfRecorder;
|
6499 | }
|
6500 | get incrementalDriver() {
|
6501 | return this.incrementalCompilation;
|
6502 | }
|
6503 | updateWithChangedResources(changedResources, perfRecorder) {
|
6504 | this.livePerfRecorder = perfRecorder;
|
6505 | this.delegatingPerfRecorder.target = perfRecorder;
|
6506 | perfRecorder.inPhase(PerfPhase.ResourceUpdate, () => {
|
6507 | if (this.compilation === null) {
|
6508 | return;
|
6509 | }
|
6510 | this.resourceManager.invalidate();
|
6511 | const classesToUpdate = new Set();
|
6512 | for (const resourceFile of changedResources) {
|
6513 | for (const templateClass of this.getComponentsWithTemplateFile(resourceFile)) {
|
6514 | classesToUpdate.add(templateClass);
|
6515 | }
|
6516 | for (const styleClass of this.getComponentsWithStyleFile(resourceFile)) {
|
6517 | classesToUpdate.add(styleClass);
|
6518 | }
|
6519 | }
|
6520 | for (const clazz of classesToUpdate) {
|
6521 | this.compilation.traitCompiler.updateResources(clazz);
|
6522 | if (!ts33.isClassDeclaration(clazz)) {
|
6523 | continue;
|
6524 | }
|
6525 | this.compilation.templateTypeChecker.invalidateClass(clazz);
|
6526 | }
|
6527 | });
|
6528 | }
|
6529 | getResourceDependencies(file) {
|
6530 | this.ensureAnalyzed();
|
6531 | return this.incrementalCompilation.depGraph.getResourceDependencies(file);
|
6532 | }
|
6533 | getDiagnostics() {
|
6534 | const diagnostics = [];
|
6535 | diagnostics.push(...this.getNonTemplateDiagnostics(), ...this.getTemplateDiagnostics());
|
6536 | if (this.options.strictTemplates) {
|
6537 | diagnostics.push(...this.getExtendedTemplateDiagnostics());
|
6538 | }
|
6539 | return this.addMessageTextDetails(diagnostics);
|
6540 | }
|
6541 | getDiagnosticsForFile(file, optimizeFor) {
|
6542 | const diagnostics = [];
|
6543 | diagnostics.push(...this.getNonTemplateDiagnostics().filter((diag) => diag.file === file), ...this.getTemplateDiagnosticsForFile(file, optimizeFor));
|
6544 | if (this.options.strictTemplates) {
|
6545 | diagnostics.push(...this.getExtendedTemplateDiagnostics(file));
|
6546 | }
|
6547 | return this.addMessageTextDetails(diagnostics);
|
6548 | }
|
6549 | getDiagnosticsForComponent(component) {
|
6550 | const compilation = this.ensureAnalyzed();
|
6551 | const ttc = compilation.templateTypeChecker;
|
6552 | const diagnostics = [];
|
6553 | diagnostics.push(...ttc.getDiagnosticsForComponent(component));
|
6554 | const extendedTemplateChecker = compilation.extendedTemplateChecker;
|
6555 | if (this.options.strictTemplates && extendedTemplateChecker) {
|
6556 | diagnostics.push(...extendedTemplateChecker.getDiagnosticsForComponent(component));
|
6557 | }
|
6558 | return this.addMessageTextDetails(diagnostics);
|
6559 | }
|
6560 | addMessageTextDetails(diagnostics) {
|
6561 | return diagnostics.map((diag) => {
|
6562 | if (diag.code && COMPILER_ERRORS_WITH_GUIDES.has(ngErrorCode(diag.code))) {
|
6563 | return __spreadProps(__spreadValues({}, diag), {
|
6564 | messageText: diag.messageText + `. Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/NG${ngErrorCode(diag.code)}`
|
6565 | });
|
6566 | }
|
6567 | return diag;
|
6568 | });
|
6569 | }
|
6570 | getOptionDiagnostics() {
|
6571 | return this.constructionDiagnostics;
|
6572 | }
|
6573 | getCurrentProgram() {
|
6574 | return this.currentProgram;
|
6575 | }
|
6576 | getTemplateTypeChecker() {
|
6577 | if (!this.enableTemplateTypeChecker) {
|
6578 | throw new Error("The `TemplateTypeChecker` does not work without `enableTemplateTypeChecker`.");
|
6579 | }
|
6580 | return this.ensureAnalyzed().templateTypeChecker;
|
6581 | }
|
6582 | getComponentsWithTemplateFile(templateFilePath) {
|
6583 | const { resourceRegistry } = this.ensureAnalyzed();
|
6584 | return resourceRegistry.getComponentsWithTemplate(resolve(templateFilePath));
|
6585 | }
|
6586 | getComponentsWithStyleFile(styleFilePath) {
|
6587 | const { resourceRegistry } = this.ensureAnalyzed();
|
6588 | return resourceRegistry.getComponentsWithStyle(resolve(styleFilePath));
|
6589 | }
|
6590 | getComponentResources(classDecl) {
|
6591 | if (!isNamedClassDeclaration(classDecl)) {
|
6592 | return null;
|
6593 | }
|
6594 | const { resourceRegistry } = this.ensureAnalyzed();
|
6595 | const styles = resourceRegistry.getStyles(classDecl);
|
6596 | const template = resourceRegistry.getTemplate(classDecl);
|
6597 | if (template === null) {
|
6598 | return null;
|
6599 | }
|
6600 | return { styles, template };
|
6601 | }
|
6602 | getMeta(classDecl) {
|
6603 | var _a;
|
6604 | if (!isNamedClassDeclaration(classDecl)) {
|
6605 | return null;
|
6606 | }
|
6607 | const ref = new Reference(classDecl);
|
6608 | const { metaReader } = this.ensureAnalyzed();
|
6609 | const meta = (_a = metaReader.getPipeMetadata(ref)) != null ? _a : metaReader.getDirectiveMetadata(ref);
|
6610 | if (meta === null) {
|
6611 | return null;
|
6612 | }
|
6613 | return meta;
|
6614 | }
|
6615 | async analyzeAsync() {
|
6616 | if (this.compilation !== null) {
|
6617 | return;
|
6618 | }
|
6619 | await this.perfRecorder.inPhase(PerfPhase.Analysis, async () => {
|
6620 | this.compilation = this.makeCompilation();
|
6621 | const promises = [];
|
6622 | for (const sf of this.inputProgram.getSourceFiles()) {
|
6623 | if (sf.isDeclarationFile) {
|
6624 | continue;
|
6625 | }
|
6626 | let analysisPromise = this.compilation.traitCompiler.analyzeAsync(sf);
|
6627 | if (analysisPromise !== void 0) {
|
6628 | promises.push(analysisPromise);
|
6629 | }
|
6630 | }
|
6631 | await Promise.all(promises);
|
6632 | this.perfRecorder.memory(PerfCheckpoint.Analysis);
|
6633 | this.resolveCompilation(this.compilation.traitCompiler);
|
6634 | });
|
6635 | }
|
6636 | prepareEmit() {
|
6637 | const compilation = this.ensureAnalyzed();
|
6638 | const coreImportsFrom = compilation.isCore ? getR3SymbolsFile(this.inputProgram) : null;
|
6639 | let importRewriter;
|
6640 | if (coreImportsFrom !== null) {
|
6641 | importRewriter = new R3SymbolsImportRewriter(coreImportsFrom.fileName);
|
6642 | } else {
|
6643 | importRewriter = new NoopImportRewriter();
|
6644 | }
|
6645 | const defaultImportTracker = new DefaultImportTracker();
|
6646 | const before = [
|
6647 | ivyTransformFactory(compilation.traitCompiler, compilation.reflector, importRewriter, defaultImportTracker, this.delegatingPerfRecorder, compilation.isCore, this.closureCompilerEnabled),
|
6648 | aliasTransformFactory(compilation.traitCompiler.exportStatements),
|
6649 | defaultImportTracker.importPreservingTransformer()
|
6650 | ];
|
6651 | const afterDeclarations = [];
|
6652 | if (compilation.dtsTransforms !== null) {
|
6653 | afterDeclarations.push(declarationTransformFactory(compilation.dtsTransforms, importRewriter));
|
6654 | }
|
6655 | if (compilation.aliasingHost !== null && compilation.aliasingHost.aliasExportsInDts) {
|
6656 | afterDeclarations.push(aliasTransformFactory(compilation.traitCompiler.exportStatements));
|
6657 | }
|
6658 | if (this.adapter.factoryTracker !== null) {
|
6659 | before.push(generatedFactoryTransform(this.adapter.factoryTracker.sourceInfo, importRewriter));
|
6660 | }
|
6661 | return { transformers: { before, afterDeclarations } };
|
6662 | }
|
6663 | getIndexedComponents() {
|
6664 | const compilation = this.ensureAnalyzed();
|
6665 | const context = new IndexingContext();
|
6666 | compilation.traitCompiler.index(context);
|
6667 | return generateAnalysis(context);
|
6668 | }
|
6669 | xi18n(ctx) {
|
6670 | const compilation = this.ensureAnalyzed();
|
6671 | compilation.traitCompiler.xi18n(ctx);
|
6672 | }
|
6673 | ensureAnalyzed() {
|
6674 | if (this.compilation === null) {
|
6675 | this.analyzeSync();
|
6676 | }
|
6677 | return this.compilation;
|
6678 | }
|
6679 | analyzeSync() {
|
6680 | this.perfRecorder.inPhase(PerfPhase.Analysis, () => {
|
6681 | this.compilation = this.makeCompilation();
|
6682 | for (const sf of this.inputProgram.getSourceFiles()) {
|
6683 | if (sf.isDeclarationFile) {
|
6684 | continue;
|
6685 | }
|
6686 | this.compilation.traitCompiler.analyzeSync(sf);
|
6687 | }
|
6688 | this.perfRecorder.memory(PerfCheckpoint.Analysis);
|
6689 | this.resolveCompilation(this.compilation.traitCompiler);
|
6690 | });
|
6691 | }
|
6692 | resolveCompilation(traitCompiler) {
|
6693 | this.perfRecorder.inPhase(PerfPhase.Resolve, () => {
|
6694 | traitCompiler.resolve();
|
6695 | this.incrementalCompilation.recordSuccessfulAnalysis(traitCompiler);
|
6696 | this.perfRecorder.memory(PerfCheckpoint.Resolve);
|
6697 | });
|
6698 | }
|
6699 | get fullTemplateTypeCheck() {
|
6700 | const strictTemplates = !!this.options.strictTemplates;
|
6701 | return strictTemplates || !!this.options.fullTemplateTypeCheck;
|
6702 | }
|
6703 | getTypeCheckingConfig() {
|
6704 | const strictTemplates = !!this.options.strictTemplates;
|
6705 | const useInlineTypeConstructors = this.programDriver.supportsInlineOperations;
|
6706 | let typeCheckingConfig;
|
6707 | if (this.fullTemplateTypeCheck) {
|
6708 | typeCheckingConfig = {
|
6709 | applyTemplateContextGuards: strictTemplates,
|
6710 | checkQueries: false,
|
6711 | checkTemplateBodies: true,
|
6712 | alwaysCheckSchemaInTemplateBodies: true,
|
6713 | checkTypeOfInputBindings: strictTemplates,
|
6714 | honorAccessModifiersForInputBindings: false,
|
6715 | strictNullInputBindings: strictTemplates,
|
6716 | checkTypeOfAttributes: strictTemplates,
|
6717 | checkTypeOfDomBindings: false,
|
6718 | checkTypeOfOutputEvents: strictTemplates,
|
6719 | checkTypeOfAnimationEvents: strictTemplates,
|
6720 | checkTypeOfDomEvents: strictTemplates,
|
6721 | checkTypeOfDomReferences: strictTemplates,
|
6722 | checkTypeOfNonDomReferences: true,
|
6723 | checkTypeOfPipes: true,
|
6724 | strictSafeNavigationTypes: strictTemplates,
|
6725 | useContextGenericType: strictTemplates,
|
6726 | strictLiteralTypes: true,
|
6727 | enableTemplateTypeChecker: this.enableTemplateTypeChecker,
|
6728 | useInlineTypeConstructors,
|
6729 | suggestionsForSuboptimalTypeInference: this.enableTemplateTypeChecker && !strictTemplates
|
6730 | };
|
6731 | } else {
|
6732 | typeCheckingConfig = {
|
6733 | applyTemplateContextGuards: false,
|
6734 | checkQueries: false,
|
6735 | checkTemplateBodies: false,
|
6736 | alwaysCheckSchemaInTemplateBodies: this.closureCompilerEnabled,
|
6737 | checkTypeOfInputBindings: false,
|
6738 | strictNullInputBindings: false,
|
6739 | honorAccessModifiersForInputBindings: false,
|
6740 | checkTypeOfAttributes: false,
|
6741 | checkTypeOfDomBindings: false,
|
6742 | checkTypeOfOutputEvents: false,
|
6743 | checkTypeOfAnimationEvents: false,
|
6744 | checkTypeOfDomEvents: false,
|
6745 | checkTypeOfDomReferences: false,
|
6746 | checkTypeOfNonDomReferences: false,
|
6747 | checkTypeOfPipes: false,
|
6748 | strictSafeNavigationTypes: false,
|
6749 | useContextGenericType: false,
|
6750 | strictLiteralTypes: false,
|
6751 | enableTemplateTypeChecker: this.enableTemplateTypeChecker,
|
6752 | useInlineTypeConstructors,
|
6753 | suggestionsForSuboptimalTypeInference: false
|
6754 | };
|
6755 | }
|
6756 | if (this.options.strictInputTypes !== void 0) {
|
6757 | typeCheckingConfig.checkTypeOfInputBindings = this.options.strictInputTypes;
|
6758 | typeCheckingConfig.applyTemplateContextGuards = this.options.strictInputTypes;
|
6759 | }
|
6760 | if (this.options.strictInputAccessModifiers !== void 0) {
|
6761 | typeCheckingConfig.honorAccessModifiersForInputBindings = this.options.strictInputAccessModifiers;
|
6762 | }
|
6763 | if (this.options.strictNullInputTypes !== void 0) {
|
6764 | typeCheckingConfig.strictNullInputBindings = this.options.strictNullInputTypes;
|
6765 | }
|
6766 | if (this.options.strictOutputEventTypes !== void 0) {
|
6767 | typeCheckingConfig.checkTypeOfOutputEvents = this.options.strictOutputEventTypes;
|
6768 | typeCheckingConfig.checkTypeOfAnimationEvents = this.options.strictOutputEventTypes;
|
6769 | }
|
6770 | if (this.options.strictDomEventTypes !== void 0) {
|
6771 | typeCheckingConfig.checkTypeOfDomEvents = this.options.strictDomEventTypes;
|
6772 | }
|
6773 | if (this.options.strictSafeNavigationTypes !== void 0) {
|
6774 | typeCheckingConfig.strictSafeNavigationTypes = this.options.strictSafeNavigationTypes;
|
6775 | }
|
6776 | if (this.options.strictDomLocalRefTypes !== void 0) {
|
6777 | typeCheckingConfig.checkTypeOfDomReferences = this.options.strictDomLocalRefTypes;
|
6778 | }
|
6779 | if (this.options.strictAttributeTypes !== void 0) {
|
6780 | typeCheckingConfig.checkTypeOfAttributes = this.options.strictAttributeTypes;
|
6781 | }
|
6782 | if (this.options.strictContextGenerics !== void 0) {
|
6783 | typeCheckingConfig.useContextGenericType = this.options.strictContextGenerics;
|
6784 | }
|
6785 | if (this.options.strictLiteralTypes !== void 0) {
|
6786 | typeCheckingConfig.strictLiteralTypes = this.options.strictLiteralTypes;
|
6787 | }
|
6788 | return typeCheckingConfig;
|
6789 | }
|
6790 | getTemplateDiagnostics() {
|
6791 | const compilation = this.ensureAnalyzed();
|
6792 | const diagnostics = [];
|
6793 | for (const sf of this.inputProgram.getSourceFiles()) {
|
6794 | if (sf.isDeclarationFile || this.adapter.isShim(sf)) {
|
6795 | continue;
|
6796 | }
|
6797 | diagnostics.push(...compilation.templateTypeChecker.getDiagnosticsForFile(sf, OptimizeFor.WholeProgram));
|
6798 | }
|
6799 | const program = this.programDriver.getProgram();
|
6800 | this.incrementalStrategy.setIncrementalState(this.incrementalCompilation.state, program);
|
6801 | this.currentProgram = program;
|
6802 | return diagnostics;
|
6803 | }
|
6804 | getTemplateDiagnosticsForFile(sf, optimizeFor) {
|
6805 | const compilation = this.ensureAnalyzed();
|
6806 | const diagnostics = [];
|
6807 | if (!sf.isDeclarationFile && !this.adapter.isShim(sf)) {
|
6808 | diagnostics.push(...compilation.templateTypeChecker.getDiagnosticsForFile(sf, optimizeFor));
|
6809 | }
|
6810 | const program = this.programDriver.getProgram();
|
6811 | this.incrementalStrategy.setIncrementalState(this.incrementalCompilation.state, program);
|
6812 | this.currentProgram = program;
|
6813 | return diagnostics;
|
6814 | }
|
6815 | getNonTemplateDiagnostics() {
|
6816 | if (this.nonTemplateDiagnostics === null) {
|
6817 | const compilation = this.ensureAnalyzed();
|
6818 | this.nonTemplateDiagnostics = [...compilation.traitCompiler.diagnostics];
|
6819 | if (this.entryPoint !== null && compilation.exportReferenceGraph !== null) {
|
6820 | this.nonTemplateDiagnostics.push(...checkForPrivateExports(this.entryPoint, this.inputProgram.getTypeChecker(), compilation.exportReferenceGraph));
|
6821 | }
|
6822 | }
|
6823 | return this.nonTemplateDiagnostics;
|
6824 | }
|
6825 | getExtendedTemplateDiagnostics(sf) {
|
6826 | const diagnostics = [];
|
6827 | const compilation = this.ensureAnalyzed();
|
6828 | const extendedTemplateChecker = compilation.extendedTemplateChecker;
|
6829 | if (!extendedTemplateChecker) {
|
6830 | return [];
|
6831 | }
|
6832 | if (sf !== void 0) {
|
6833 | return compilation.traitCompiler.extendedTemplateCheck(sf, extendedTemplateChecker);
|
6834 | }
|
6835 | for (const sf2 of this.inputProgram.getSourceFiles()) {
|
6836 | diagnostics.push(...compilation.traitCompiler.extendedTemplateCheck(sf2, extendedTemplateChecker));
|
6837 | }
|
6838 | return diagnostics;
|
6839 | }
|
6840 | makeCompilation() {
|
6841 | const checker = this.inputProgram.getTypeChecker();
|
6842 | const reflector = new TypeScriptReflectionHost(checker);
|
6843 | let refEmitter;
|
6844 | let aliasingHost = null;
|
6845 | if (this.adapter.unifiedModulesHost === null || !this.options._useHostForImportGeneration) {
|
6846 | let localImportStrategy;
|
6847 | if (this.options.rootDir !== void 0 || this.options.rootDirs !== void 0 && this.options.rootDirs.length > 0) {
|
6848 | localImportStrategy = new LogicalProjectStrategy(reflector, new LogicalFileSystem([...this.adapter.rootDirs], this.adapter));
|
6849 | } else {
|
6850 | localImportStrategy = new RelativePathStrategy(reflector);
|
6851 | }
|
6852 | refEmitter = new ReferenceEmitter([
|
6853 | new LocalIdentifierStrategy(),
|
6854 | new AbsoluteModuleStrategy(this.inputProgram, checker, this.moduleResolver, reflector),
|
6855 | localImportStrategy
|
6856 | ]);
|
6857 | if (this.entryPoint === null && this.options.generateDeepReexports === true) {
|
6858 | aliasingHost = new PrivateExportAliasingHost(reflector);
|
6859 | }
|
6860 | } else {
|
6861 | refEmitter = new ReferenceEmitter([
|
6862 | new LocalIdentifierStrategy(),
|
6863 | new AliasStrategy(),
|
6864 | new UnifiedModulesStrategy(reflector, this.adapter.unifiedModulesHost)
|
6865 | ]);
|
6866 | aliasingHost = new UnifiedModulesAliasingHost(this.adapter.unifiedModulesHost);
|
6867 | }
|
6868 | const evaluator = new PartialEvaluator(reflector, checker, this.incrementalCompilation.depGraph);
|
6869 | const dtsReader = new DtsMetadataReader(checker, reflector);
|
6870 | const localMetaRegistry = new LocalMetadataRegistry();
|
6871 | const localMetaReader = localMetaRegistry;
|
6872 | const depScopeReader = new MetadataDtsModuleScopeResolver(dtsReader, aliasingHost);
|
6873 | const scopeRegistry = new LocalModuleScopeRegistry(localMetaReader, depScopeReader, refEmitter, aliasingHost);
|
6874 | const scopeReader = scopeRegistry;
|
6875 | const semanticDepGraphUpdater = this.incrementalCompilation.semanticDepGraphUpdater;
|
6876 | const metaRegistry = new CompoundMetadataRegistry([localMetaRegistry, scopeRegistry]);
|
6877 | const injectableRegistry = new InjectableClassRegistry(reflector);
|
6878 | const metaReader = new CompoundMetadataReader([localMetaReader, dtsReader]);
|
6879 | const typeCheckScopeRegistry = new TypeCheckScopeRegistry(scopeReader, metaReader);
|
6880 | let referencesRegistry;
|
6881 | let exportReferenceGraph = null;
|
6882 | if (this.entryPoint !== null) {
|
6883 | exportReferenceGraph = new ReferenceGraph();
|
6884 | referencesRegistry = new ReferenceGraphAdapter(exportReferenceGraph);
|
6885 | } else {
|
6886 | referencesRegistry = new NoopReferencesRegistry();
|
6887 | }
|
6888 | const dtsTransforms = new DtsTransformRegistry();
|
6889 | const isCore = isAngularCorePackage(this.inputProgram);
|
6890 | const resourceRegistry = new ResourceRegistry();
|
6891 | const compilationMode = this.options.compilationMode === "partial" && !isCore ? CompilationMode.PARTIAL : CompilationMode.FULL;
|
6892 | const cycleHandlingStrategy = compilationMode === CompilationMode.FULL ? 0 : 1;
|
6893 | const handlers = [
|
6894 | new ComponentDecoratorHandler(reflector, evaluator, metaRegistry, metaReader, scopeReader, scopeRegistry, typeCheckScopeRegistry, resourceRegistry, isCore, this.resourceManager, this.adapter.rootDirs, this.options.preserveWhitespaces || false, this.options.i18nUseExternalIds !== false, this.options.enableI18nLegacyMessageIdFormat !== false, this.usePoisonedData, this.options.i18nNormalizeLineEndingsInICUs, this.moduleResolver, this.cycleAnalyzer, cycleHandlingStrategy, refEmitter, this.incrementalCompilation.depGraph, injectableRegistry, semanticDepGraphUpdater, this.closureCompilerEnabled, this.delegatingPerfRecorder),
|
6895 | new DirectiveDecoratorHandler(reflector, evaluator, metaRegistry, scopeRegistry, metaReader, injectableRegistry, isCore, semanticDepGraphUpdater, this.closureCompilerEnabled, false, this.delegatingPerfRecorder),
|
6896 | new PipeDecoratorHandler(reflector, evaluator, metaRegistry, scopeRegistry, injectableRegistry, isCore, this.delegatingPerfRecorder),
|
6897 | new InjectableDecoratorHandler(reflector, isCore, this.options.strictInjectionParameters || false, injectableRegistry, this.delegatingPerfRecorder),
|
6898 | new NgModuleDecoratorHandler(reflector, evaluator, metaReader, metaRegistry, scopeRegistry, referencesRegistry, isCore, refEmitter, this.adapter.factoryTracker, this.closureCompilerEnabled, injectableRegistry, this.delegatingPerfRecorder)
|
6899 | ];
|
6900 | const traitCompiler = new TraitCompiler(handlers, reflector, this.delegatingPerfRecorder, this.incrementalCompilation, this.options.compileNonExportedClasses !== false, compilationMode, dtsTransforms, semanticDepGraphUpdater, this.adapter);
|
6901 | const notifyingDriver = new NotifyingProgramDriverWrapper(this.programDriver, (program) => {
|
6902 | this.incrementalStrategy.setIncrementalState(this.incrementalCompilation.state, program);
|
6903 | this.currentProgram = program;
|
6904 | });
|
6905 | const templateTypeChecker = new TemplateTypeCheckerImpl(this.inputProgram, notifyingDriver, traitCompiler, this.getTypeCheckingConfig(), refEmitter, reflector, this.adapter, this.incrementalCompilation, scopeRegistry, typeCheckScopeRegistry, this.delegatingPerfRecorder);
|
6906 | const extendedTemplateChecker = this.constructionDiagnostics.length === 0 ? new ExtendedTemplateCheckerImpl(templateTypeChecker, checker, ALL_DIAGNOSTIC_FACTORIES, this.options) : null;
|
6907 | return {
|
6908 | isCore,
|
6909 | traitCompiler,
|
6910 | reflector,
|
6911 | scopeRegistry,
|
6912 | dtsTransforms,
|
6913 | exportReferenceGraph,
|
6914 | metaReader,
|
6915 | typeCheckScopeRegistry,
|
6916 | aliasingHost,
|
6917 | refEmitter,
|
6918 | templateTypeChecker,
|
6919 | resourceRegistry,
|
6920 | extendedTemplateChecker
|
6921 | };
|
6922 | }
|
6923 | };
|
6924 | function isAngularCorePackage(program) {
|
6925 | const r3Symbols = getR3SymbolsFile(program);
|
6926 | if (r3Symbols === null) {
|
6927 | return false;
|
6928 | }
|
6929 | return r3Symbols.statements.some((stmt) => {
|
6930 | if (!ts33.isVariableStatement(stmt)) {
|
6931 | return false;
|
6932 | }
|
6933 | if (stmt.modifiers === void 0 || !stmt.modifiers.some((mod) => mod.kind === ts33.SyntaxKind.ExportKeyword)) {
|
6934 | return false;
|
6935 | }
|
6936 | return stmt.declarationList.declarations.some((decl) => {
|
6937 | if (!ts33.isIdentifier(decl.name) || decl.name.text !== "ITS_JUST_ANGULAR") {
|
6938 | return false;
|
6939 | }
|
6940 | if (decl.initializer === void 0 || decl.initializer.kind !== ts33.SyntaxKind.TrueKeyword) {
|
6941 | return false;
|
6942 | }
|
6943 | return true;
|
6944 | });
|
6945 | });
|
6946 | }
|
6947 | function getR3SymbolsFile(program) {
|
6948 | return program.getSourceFiles().find((file) => file.fileName.indexOf("r3_symbols.ts") >= 0) || null;
|
6949 | }
|
6950 | function* verifyCompatibleTypeCheckOptions(options) {
|
6951 | var _a, _b, _c;
|
6952 | if (options.fullTemplateTypeCheck === false && options.strictTemplates === true) {
|
6953 | yield makeConfigDiagnostic({
|
6954 | category: ts33.DiagnosticCategory.Error,
|
6955 | code: ErrorCode.CONFIG_STRICT_TEMPLATES_IMPLIES_FULL_TEMPLATE_TYPECHECK,
|
6956 | messageText: `
|
6957 | Angular compiler option "strictTemplates" is enabled, however "fullTemplateTypeCheck" is disabled.
|
6958 |
|
6959 | Having the "strictTemplates" flag enabled implies that "fullTemplateTypeCheck" is also enabled, so
|
6960 | the latter can not be explicitly disabled.
|
6961 |
|
6962 | One of the following actions is required:
|
6963 | 1. Remove the "fullTemplateTypeCheck" option.
|
6964 | 2. Remove "strictTemplates" or set it to 'false'.
|
6965 |
|
6966 | More information about the template type checking compiler options can be found in the documentation:
|
6967 | https://angular.io/guide/template-typecheck
|
6968 | `.trim()
|
6969 | });
|
6970 | }
|
6971 | if (options.extendedDiagnostics && options.strictTemplates === false) {
|
6972 | yield makeConfigDiagnostic({
|
6973 | category: ts33.DiagnosticCategory.Error,
|
6974 | code: ErrorCode.CONFIG_EXTENDED_DIAGNOSTICS_IMPLIES_STRICT_TEMPLATES,
|
6975 | messageText: `
|
6976 | Angular compiler option "extendedDiagnostics" is configured, however "strictTemplates" is disabled.
|
6977 |
|
6978 | Using "extendedDiagnostics" requires that "strictTemplates" is also enabled.
|
6979 |
|
6980 | One of the following actions is required:
|
6981 | 1. Remove "strictTemplates: false" to enable it.
|
6982 | 2. Remove "extendedDiagnostics" configuration to disable them.
|
6983 | `.trim()
|
6984 | });
|
6985 | }
|
6986 | const allowedCategoryLabels = Array.from(Object.values(DiagnosticCategoryLabel));
|
6987 | const defaultCategory = (_a = options.extendedDiagnostics) == null ? void 0 : _a.defaultCategory;
|
6988 | if (defaultCategory && !allowedCategoryLabels.includes(defaultCategory)) {
|
6989 | yield makeConfigDiagnostic({
|
6990 | category: ts33.DiagnosticCategory.Error,
|
6991 | code: ErrorCode.CONFIG_EXTENDED_DIAGNOSTICS_UNKNOWN_CATEGORY_LABEL,
|
6992 | messageText: `
|
6993 | Angular compiler option "extendedDiagnostics.defaultCategory" has an unknown diagnostic category: "${defaultCategory}".
|
6994 |
|
6995 | Allowed diagnostic categories are:
|
6996 | ${allowedCategoryLabels.join("\n")}
|
6997 | `.trim()
|
6998 | });
|
6999 | }
|
7000 | const allExtendedDiagnosticNames = ALL_DIAGNOSTIC_FACTORIES.map((factory3) => factory3.name);
|
7001 | for (const [checkName, category] of Object.entries((_c = (_b = options.extendedDiagnostics) == null ? void 0 : _b.checks) != null ? _c : {})) {
|
7002 | if (!allExtendedDiagnosticNames.includes(checkName)) {
|
7003 | yield makeConfigDiagnostic({
|
7004 | category: ts33.DiagnosticCategory.Error,
|
7005 | code: ErrorCode.CONFIG_EXTENDED_DIAGNOSTICS_UNKNOWN_CHECK,
|
7006 | messageText: `
|
7007 | Angular compiler option "extendedDiagnostics.checks" has an unknown check: "${checkName}".
|
7008 |
|
7009 | Allowed check names are:
|
7010 | ${allExtendedDiagnosticNames.join("\n")}
|
7011 | `.trim()
|
7012 | });
|
7013 | }
|
7014 | if (!allowedCategoryLabels.includes(category)) {
|
7015 | yield makeConfigDiagnostic({
|
7016 | category: ts33.DiagnosticCategory.Error,
|
7017 | code: ErrorCode.CONFIG_EXTENDED_DIAGNOSTICS_UNKNOWN_CATEGORY_LABEL,
|
7018 | messageText: `
|
7019 | Angular compiler option "extendedDiagnostics.checks['${checkName}']" has an unknown diagnostic category: "${category}".
|
7020 |
|
7021 | Allowed diagnostic categories are:
|
7022 | ${allowedCategoryLabels.join("\n")}
|
7023 | `.trim()
|
7024 | });
|
7025 | }
|
7026 | }
|
7027 | }
|
7028 | function makeConfigDiagnostic({ category, code, messageText }) {
|
7029 | return {
|
7030 | category,
|
7031 | code: ngErrorCode(code),
|
7032 | file: void 0,
|
7033 | start: void 0,
|
7034 | length: void 0,
|
7035 | messageText
|
7036 | };
|
7037 | }
|
7038 | var ReferenceGraphAdapter = class {
|
7039 | constructor(graph) {
|
7040 | this.graph = graph;
|
7041 | }
|
7042 | add(source, ...references) {
|
7043 | for (const { node } of references) {
|
7044 | let sourceFile = node.getSourceFile();
|
7045 | if (sourceFile === void 0) {
|
7046 | sourceFile = ts33.getOriginalNode(node).getSourceFile();
|
7047 | }
|
7048 | if (sourceFile === void 0 || !isDtsPath(sourceFile.fileName)) {
|
7049 | this.graph.add(source, node);
|
7050 | }
|
7051 | }
|
7052 | }
|
7053 | };
|
7054 | var NotifyingProgramDriverWrapper = class {
|
7055 | constructor(delegate, notifyNewProgram) {
|
7056 | var _a;
|
7057 | this.delegate = delegate;
|
7058 | this.notifyNewProgram = notifyNewProgram;
|
7059 | this.getSourceFileVersion = (_a = this.delegate.getSourceFileVersion) == null ? void 0 : _a.bind(this);
|
7060 | }
|
7061 | get supportsInlineOperations() {
|
7062 | return this.delegate.supportsInlineOperations;
|
7063 | }
|
7064 | getProgram() {
|
7065 | return this.delegate.getProgram();
|
7066 | }
|
7067 | updateFiles(contents, updateMode) {
|
7068 | this.delegate.updateFiles(contents, updateMode);
|
7069 | this.notifyNewProgram(this.delegate.getProgram());
|
7070 | }
|
7071 | };
|
7072 | function versionMapFromProgram(program, driver) {
|
7073 | if (driver.getSourceFileVersion === void 0) {
|
7074 | return null;
|
7075 | }
|
7076 | const versions = new Map();
|
7077 | for (const possiblyRedirectedSourceFile of program.getSourceFiles()) {
|
7078 | const sf = toUnredirectedSourceFile(possiblyRedirectedSourceFile);
|
7079 | versions.set(absoluteFromSourceFile(sf), driver.getSourceFileVersion(sf));
|
7080 | }
|
7081 | return versions;
|
7082 | }
|
7083 |
|
7084 |
|
7085 | import ts34 from "typescript";
|
7086 | var DelegatingCompilerHost2 = class {
|
7087 | constructor(delegate) {
|
7088 | this.delegate = delegate;
|
7089 | this.createHash = this.delegateMethod("createHash");
|
7090 | this.directoryExists = this.delegateMethod("directoryExists");
|
7091 | this.fileNameToModuleName = this.delegateMethod("fileNameToModuleName");
|
7092 | this.getCancellationToken = this.delegateMethod("getCancellationToken");
|
7093 | this.getCanonicalFileName = this.delegateMethod("getCanonicalFileName");
|
7094 | this.getCurrentDirectory = this.delegateMethod("getCurrentDirectory");
|
7095 | this.getDefaultLibFileName = this.delegateMethod("getDefaultLibFileName");
|
7096 | this.getDefaultLibLocation = this.delegateMethod("getDefaultLibLocation");
|
7097 | this.getDirectories = this.delegateMethod("getDirectories");
|
7098 | this.getEnvironmentVariable = this.delegateMethod("getEnvironmentVariable");
|
7099 | this.getModifiedResourceFiles = this.delegateMethod("getModifiedResourceFiles");
|
7100 | this.getNewLine = this.delegateMethod("getNewLine");
|
7101 | this.getParsedCommandLine = this.delegateMethod("getParsedCommandLine");
|
7102 | this.getSourceFileByPath = this.delegateMethod("getSourceFileByPath");
|
7103 | this.readDirectory = this.delegateMethod("readDirectory");
|
7104 | this.readFile = this.delegateMethod("readFile");
|
7105 | this.readResource = this.delegateMethod("readResource");
|
7106 | this.transformResource = this.delegateMethod("transformResource");
|
7107 | this.realpath = this.delegateMethod("realpath");
|
7108 | this.resolveModuleNames = this.delegateMethod("resolveModuleNames");
|
7109 | this.resolveTypeReferenceDirectives = this.delegateMethod("resolveTypeReferenceDirectives");
|
7110 | this.resourceNameToFileName = this.delegateMethod("resourceNameToFileName");
|
7111 | this.trace = this.delegateMethod("trace");
|
7112 | this.useCaseSensitiveFileNames = this.delegateMethod("useCaseSensitiveFileNames");
|
7113 | this.writeFile = this.delegateMethod("writeFile");
|
7114 | this.getModuleResolutionCache = this.delegateMethod("getModuleResolutionCache");
|
7115 | }
|
7116 | delegateMethod(name) {
|
7117 | return this.delegate[name] !== void 0 ? this.delegate[name].bind(this.delegate) : void 0;
|
7118 | }
|
7119 | };
|
7120 | var NgCompilerHost = class extends DelegatingCompilerHost2 {
|
7121 | constructor(delegate, inputFiles, rootDirs, shimAdapter, shimTagger, entryPoint, factoryTracker, diagnostics) {
|
7122 | super(delegate);
|
7123 | this.shimAdapter = shimAdapter;
|
7124 | this.shimTagger = shimTagger;
|
7125 | this.factoryTracker = null;
|
7126 | this.entryPoint = null;
|
7127 | this.factoryTracker = factoryTracker;
|
7128 | this.entryPoint = entryPoint;
|
7129 | this.constructionDiagnostics = diagnostics;
|
7130 | this.inputFiles = [...inputFiles, ...shimAdapter.extraInputFiles];
|
7131 | this.rootDirs = rootDirs;
|
7132 | if (this.resolveModuleNames === void 0) {
|
7133 | this.resolveModuleNames = this.createCachedResolveModuleNamesFunction();
|
7134 | }
|
7135 | }
|
7136 | get ignoreForEmit() {
|
7137 | return this.shimAdapter.ignoreForEmit;
|
7138 | }
|
7139 | get shimExtensionPrefixes() {
|
7140 | return this.shimAdapter.extensionPrefixes;
|
7141 | }
|
7142 | postProgramCreationCleanup() {
|
7143 | this.shimTagger.finalize();
|
7144 | }
|
7145 | static wrap(delegate, inputFiles, options, oldProgram) {
|
7146 | const allowEmptyCodegenFiles = options.allowEmptyCodegenFiles || false;
|
7147 | const shouldGenerateFactoryShims = options.generateNgFactoryShims !== void 0 ? options.generateNgFactoryShims : allowEmptyCodegenFiles;
|
7148 | const shouldGenerateSummaryShims = options.generateNgSummaryShims !== void 0 ? options.generateNgSummaryShims : allowEmptyCodegenFiles;
|
7149 | const topLevelShimGenerators = [];
|
7150 | const perFileShimGenerators = [];
|
7151 | if (shouldGenerateSummaryShims) {
|
7152 | perFileShimGenerators.push(new SummaryGenerator());
|
7153 | }
|
7154 | let factoryTracker = null;
|
7155 | if (shouldGenerateFactoryShims) {
|
7156 | const factoryGenerator = new FactoryGenerator();
|
7157 | perFileShimGenerators.push(factoryGenerator);
|
7158 | factoryTracker = factoryGenerator;
|
7159 | }
|
7160 | const rootDirs = getRootDirs(delegate, options);
|
7161 | perFileShimGenerators.push(new TypeCheckShimGenerator());
|
7162 | let diagnostics = [];
|
7163 | const normalizedTsInputFiles = [];
|
7164 | for (const inputFile of inputFiles) {
|
7165 | if (!isNonDeclarationTsPath(inputFile)) {
|
7166 | continue;
|
7167 | }
|
7168 | normalizedTsInputFiles.push(resolve(inputFile));
|
7169 | }
|
7170 | let entryPoint = null;
|
7171 | if (options.flatModuleOutFile != null && options.flatModuleOutFile !== "") {
|
7172 | entryPoint = findFlatIndexEntryPoint(normalizedTsInputFiles);
|
7173 | if (entryPoint === null) {
|
7174 | diagnostics.push({
|
7175 | category: ts34.DiagnosticCategory.Error,
|
7176 | code: ngErrorCode(ErrorCode.CONFIG_FLAT_MODULE_NO_INDEX),
|
7177 | file: void 0,
|
7178 | start: void 0,
|
7179 | length: void 0,
|
7180 | messageText: 'Angular compiler option "flatModuleOutFile" requires one and only one .ts file in the "files" field.'
|
7181 | });
|
7182 | } else {
|
7183 | const flatModuleId = options.flatModuleId || null;
|
7184 | const flatModuleOutFile = normalizeSeparators(options.flatModuleOutFile);
|
7185 | const flatIndexGenerator = new FlatIndexGenerator(entryPoint, flatModuleOutFile, flatModuleId);
|
7186 | topLevelShimGenerators.push(flatIndexGenerator);
|
7187 | }
|
7188 | }
|
7189 | const shimAdapter = new ShimAdapter(delegate, normalizedTsInputFiles, topLevelShimGenerators, perFileShimGenerators, oldProgram);
|
7190 | const shimTagger = new ShimReferenceTagger(perFileShimGenerators.map((gen) => gen.extensionPrefix));
|
7191 | return new NgCompilerHost(delegate, inputFiles, rootDirs, shimAdapter, shimTagger, entryPoint, factoryTracker, diagnostics);
|
7192 | }
|
7193 | isShim(sf) {
|
7194 | return isShim(sf);
|
7195 | }
|
7196 | isResource(sf) {
|
7197 | return false;
|
7198 | }
|
7199 | getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
|
7200 | const shimSf = this.shimAdapter.maybeGenerate(resolve(fileName));
|
7201 | if (shimSf !== null) {
|
7202 | return shimSf;
|
7203 | }
|
7204 | const sf = this.delegate.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
|
7205 | if (sf === void 0) {
|
7206 | return void 0;
|
7207 | }
|
7208 | this.shimTagger.tag(sf);
|
7209 | return sf;
|
7210 | }
|
7211 | fileExists(fileName) {
|
7212 | return this.delegate.fileExists(fileName) || this.shimAdapter.maybeGenerate(resolve(fileName)) != null;
|
7213 | }
|
7214 | get unifiedModulesHost() {
|
7215 | return this.fileNameToModuleName !== void 0 ? this : null;
|
7216 | }
|
7217 | createCachedResolveModuleNamesFunction() {
|
7218 | const moduleResolutionCache = ts34.createModuleResolutionCache(this.getCurrentDirectory(), this.getCanonicalFileName.bind(this));
|
7219 | return (moduleNames, containingFile, reusedNames, redirectedReference, options) => {
|
7220 | return moduleNames.map((moduleName) => {
|
7221 | const module = ts34.resolveModuleName(moduleName, containingFile, options, this, moduleResolutionCache, redirectedReference);
|
7222 | return module.resolvedModule;
|
7223 | });
|
7224 | };
|
7225 | }
|
7226 | };
|
7227 |
|
7228 |
|
7229 | var NgtscProgram = class {
|
7230 | constructor(rootNames, options, delegateHost, oldProgram) {
|
7231 | this.options = options;
|
7232 | const perfRecorder = ActivePerfRecorder.zeroedToNow();
|
7233 | perfRecorder.phase(PerfPhase.Setup);
|
7234 | if (!options.disableTypeScriptVersionCheck) {
|
7235 | verifySupportedTypeScriptVersion();
|
7236 | }
|
7237 | const reuseProgram = oldProgram == null ? void 0 : oldProgram.compiler.getCurrentProgram();
|
7238 | this.host = NgCompilerHost.wrap(delegateHost, rootNames, options, reuseProgram != null ? reuseProgram : null);
|
7239 | if (reuseProgram !== void 0) {
|
7240 | retagAllTsFiles(reuseProgram);
|
7241 | }
|
7242 | this.tsProgram = perfRecorder.inPhase(PerfPhase.TypeScriptProgramCreate, () => ts35.createProgram(this.host.inputFiles, options, this.host, reuseProgram));
|
7243 | perfRecorder.phase(PerfPhase.Unaccounted);
|
7244 | perfRecorder.memory(PerfCheckpoint.TypeScriptProgramCreate);
|
7245 | this.host.postProgramCreationCleanup();
|
7246 | untagAllTsFiles(this.tsProgram);
|
7247 | const programDriver = new TsCreateProgramDriver(this.tsProgram, this.host, this.options, this.host.shimExtensionPrefixes);
|
7248 | this.incrementalStrategy = oldProgram !== void 0 ? oldProgram.incrementalStrategy.toNextBuildStrategy() : new TrackedIncrementalBuildStrategy();
|
7249 | const modifiedResourceFiles = new Set();
|
7250 | if (this.host.getModifiedResourceFiles !== void 0) {
|
7251 | const strings = this.host.getModifiedResourceFiles();
|
7252 | if (strings !== void 0) {
|
7253 | for (const fileString of strings) {
|
7254 | modifiedResourceFiles.add(absoluteFrom(fileString));
|
7255 | }
|
7256 | }
|
7257 | }
|
7258 | let ticket;
|
7259 | if (oldProgram === void 0) {
|
7260 | ticket = freshCompilationTicket(this.tsProgram, options, this.incrementalStrategy, programDriver, perfRecorder, false, false);
|
7261 | } else {
|
7262 | ticket = incrementalFromCompilerTicket(oldProgram.compiler, this.tsProgram, this.incrementalStrategy, programDriver, modifiedResourceFiles, perfRecorder);
|
7263 | }
|
7264 | this.compiler = NgCompiler.fromTicket(ticket, this.host);
|
7265 | }
|
7266 | getTsProgram() {
|
7267 | return this.tsProgram;
|
7268 | }
|
7269 | getReuseTsProgram() {
|
7270 | return this.compiler.getCurrentProgram();
|
7271 | }
|
7272 | getTsOptionDiagnostics(cancellationToken) {
|
7273 | return this.compiler.perfRecorder.inPhase(PerfPhase.TypeScriptDiagnostics, () => this.tsProgram.getOptionsDiagnostics(cancellationToken));
|
7274 | }
|
7275 | getTsSyntacticDiagnostics(sourceFile, cancellationToken) {
|
7276 | return this.compiler.perfRecorder.inPhase(PerfPhase.TypeScriptDiagnostics, () => {
|
7277 | const ignoredFiles = this.compiler.ignoreForDiagnostics;
|
7278 | let res;
|
7279 | if (sourceFile !== void 0) {
|
7280 | if (ignoredFiles.has(sourceFile)) {
|
7281 | return [];
|
7282 | }
|
7283 | res = this.tsProgram.getSyntacticDiagnostics(sourceFile, cancellationToken);
|
7284 | } else {
|
7285 | const diagnostics = [];
|
7286 | for (const sf of this.tsProgram.getSourceFiles()) {
|
7287 | if (!ignoredFiles.has(sf)) {
|
7288 | diagnostics.push(...this.tsProgram.getSyntacticDiagnostics(sf, cancellationToken));
|
7289 | }
|
7290 | }
|
7291 | res = diagnostics;
|
7292 | }
|
7293 | return res;
|
7294 | });
|
7295 | }
|
7296 | getTsSemanticDiagnostics(sourceFile, cancellationToken) {
|
7297 | return this.compiler.perfRecorder.inPhase(PerfPhase.TypeScriptDiagnostics, () => {
|
7298 | const ignoredFiles = this.compiler.ignoreForDiagnostics;
|
7299 | let res;
|
7300 | if (sourceFile !== void 0) {
|
7301 | if (ignoredFiles.has(sourceFile)) {
|
7302 | return [];
|
7303 | }
|
7304 | res = this.tsProgram.getSemanticDiagnostics(sourceFile, cancellationToken);
|
7305 | } else {
|
7306 | const diagnostics = [];
|
7307 | for (const sf of this.tsProgram.getSourceFiles()) {
|
7308 | if (!ignoredFiles.has(sf)) {
|
7309 | diagnostics.push(...this.tsProgram.getSemanticDiagnostics(sf, cancellationToken));
|
7310 | }
|
7311 | }
|
7312 | res = diagnostics;
|
7313 | }
|
7314 | return res;
|
7315 | });
|
7316 | }
|
7317 | getNgOptionDiagnostics(cancellationToken) {
|
7318 | return this.compiler.getOptionDiagnostics();
|
7319 | }
|
7320 | getNgStructuralDiagnostics(cancellationToken) {
|
7321 | return [];
|
7322 | }
|
7323 | getNgSemanticDiagnostics(fileName, cancellationToken) {
|
7324 | let sf = void 0;
|
7325 | if (fileName !== void 0) {
|
7326 | sf = this.tsProgram.getSourceFile(fileName);
|
7327 | if (sf === void 0) {
|
7328 | return [];
|
7329 | }
|
7330 | }
|
7331 | if (sf === void 0) {
|
7332 | return this.compiler.getDiagnostics();
|
7333 | } else {
|
7334 | return this.compiler.getDiagnosticsForFile(sf, OptimizeFor.WholeProgram);
|
7335 | }
|
7336 | }
|
7337 | loadNgStructureAsync() {
|
7338 | return this.compiler.analyzeAsync();
|
7339 | }
|
7340 | listLazyRoutes(entryRoute) {
|
7341 | return [];
|
7342 | }
|
7343 | emitXi18n() {
|
7344 | var _a, _b, _c;
|
7345 | const ctx = new MessageBundle(new HtmlParser(), [], {}, (_a = this.options.i18nOutLocale) != null ? _a : null);
|
7346 | this.compiler.xi18n(ctx);
|
7347 | i18nExtract((_b = this.options.i18nOutFormat) != null ? _b : null, (_c = this.options.i18nOutFile) != null ? _c : null, this.host, this.options, ctx, resolve);
|
7348 | }
|
7349 | emit(opts) {
|
7350 | if (opts !== void 0 && opts.emitFlags !== void 0 && opts.emitFlags & EmitFlags.I18nBundle) {
|
7351 | this.emitXi18n();
|
7352 | if (!(opts.emitFlags & EmitFlags.JS)) {
|
7353 | return {
|
7354 | diagnostics: [],
|
7355 | emitSkipped: true,
|
7356 | emittedFiles: []
|
7357 | };
|
7358 | }
|
7359 | }
|
7360 | this.compiler.perfRecorder.memory(PerfCheckpoint.PreEmit);
|
7361 | const res = this.compiler.perfRecorder.inPhase(PerfPhase.TypeScriptEmit, () => {
|
7362 | const { transformers } = this.compiler.prepareEmit();
|
7363 | const ignoreFiles = this.compiler.ignoreForEmit;
|
7364 | const emitCallback = opts && opts.emitCallback || defaultEmitCallback;
|
7365 | const writeFile = (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
|
7366 | if (sourceFiles !== void 0) {
|
7367 | for (const writtenSf of sourceFiles) {
|
7368 | if (writtenSf.isDeclarationFile) {
|
7369 | continue;
|
7370 | }
|
7371 | this.compiler.incrementalCompilation.recordSuccessfulEmit(writtenSf);
|
7372 | }
|
7373 | }
|
7374 | this.host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles);
|
7375 | };
|
7376 | const customTransforms = opts && opts.customTransformers;
|
7377 | const beforeTransforms = transformers.before || [];
|
7378 | const afterDeclarationsTransforms = transformers.afterDeclarations;
|
7379 | if (customTransforms !== void 0 && customTransforms.beforeTs !== void 0) {
|
7380 | beforeTransforms.push(...customTransforms.beforeTs);
|
7381 | }
|
7382 | const emitResults = [];
|
7383 | for (const targetSourceFile of this.tsProgram.getSourceFiles()) {
|
7384 | if (targetSourceFile.isDeclarationFile || ignoreFiles.has(targetSourceFile)) {
|
7385 | continue;
|
7386 | }
|
7387 | if (this.compiler.incrementalCompilation.safeToSkipEmit(targetSourceFile)) {
|
7388 | this.compiler.perfRecorder.eventCount(PerfEvent.EmitSkipSourceFile);
|
7389 | continue;
|
7390 | }
|
7391 | this.compiler.perfRecorder.eventCount(PerfEvent.EmitSourceFile);
|
7392 | emitResults.push(emitCallback({
|
7393 | targetSourceFile,
|
7394 | program: this.tsProgram,
|
7395 | host: this.host,
|
7396 | options: this.options,
|
7397 | emitOnlyDtsFiles: false,
|
7398 | writeFile,
|
7399 | customTransformers: {
|
7400 | before: beforeTransforms,
|
7401 | after: customTransforms && customTransforms.afterTs,
|
7402 | afterDeclarations: afterDeclarationsTransforms
|
7403 | }
|
7404 | }));
|
7405 | }
|
7406 | this.compiler.perfRecorder.memory(PerfCheckpoint.Emit);
|
7407 | return (opts && opts.mergeEmitResultsCallback || mergeEmitResults)(emitResults);
|
7408 | });
|
7409 | if (this.options.tracePerformance !== void 0) {
|
7410 | const perf = this.compiler.perfRecorder.finalize();
|
7411 | getFileSystem().writeFile(getFileSystem().resolve(this.options.tracePerformance), JSON.stringify(perf, null, 2));
|
7412 | }
|
7413 | return res;
|
7414 | }
|
7415 | getIndexedComponents() {
|
7416 | return this.compiler.getIndexedComponents();
|
7417 | }
|
7418 | getEmittedSourceFiles() {
|
7419 | throw new Error("Method not implemented.");
|
7420 | }
|
7421 | };
|
7422 | var defaultEmitCallback = ({ program, targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers }) => program.emit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
7423 | function mergeEmitResults(emitResults) {
|
7424 | const diagnostics = [];
|
7425 | let emitSkipped = false;
|
7426 | const emittedFiles = [];
|
7427 | for (const er of emitResults) {
|
7428 | diagnostics.push(...er.diagnostics);
|
7429 | emitSkipped = emitSkipped || er.emitSkipped;
|
7430 | emittedFiles.push(...er.emittedFiles || []);
|
7431 | }
|
7432 | return { diagnostics, emitSkipped, emittedFiles };
|
7433 | }
|
7434 |
|
7435 |
|
7436 | function createProgram({ rootNames, options, host, oldProgram }) {
|
7437 | return new NgtscProgram(rootNames, options, host, oldProgram);
|
7438 | }
|
7439 |
|
7440 |
|
7441 | import ts37 from "typescript";
|
7442 |
|
7443 |
|
7444 | import ts36 from "typescript";
|
7445 | var GENERATED_FILES = /(.*?)\.(ngfactory|shim\.ngstyle|ngstyle|ngsummary)\.(js|d\.ts|ts)$/;
|
7446 | function createMessageDiagnostic(messageText) {
|
7447 | return {
|
7448 | file: void 0,
|
7449 | start: void 0,
|
7450 | length: void 0,
|
7451 | category: ts36.DiagnosticCategory.Message,
|
7452 | messageText,
|
7453 | code: DEFAULT_ERROR_CODE,
|
7454 | source: SOURCE
|
7455 | };
|
7456 | }
|
7457 |
|
7458 |
|
7459 | var defaultFormatHost = {
|
7460 | getCurrentDirectory: () => ts37.sys.getCurrentDirectory(),
|
7461 | getCanonicalFileName: (fileName) => fileName,
|
7462 | getNewLine: () => ts37.sys.newLine
|
7463 | };
|
7464 | function formatDiagnostics(diags, host = defaultFormatHost) {
|
7465 | if (diags && diags.length) {
|
7466 | return diags.map((diagnostic) => replaceTsWithNgInErrors(ts37.formatDiagnosticsWithColorAndContext([diagnostic], host))).join("");
|
7467 | } else {
|
7468 | return "";
|
7469 | }
|
7470 | }
|
7471 | function calcProjectFileAndBasePath(project, host = getFileSystem()) {
|
7472 | const absProject = host.resolve(project);
|
7473 | const projectIsDir = host.lstat(absProject).isDirectory();
|
7474 | const projectFile = projectIsDir ? host.join(absProject, "tsconfig.json") : absProject;
|
7475 | const projectDir = projectIsDir ? absProject : host.dirname(absProject);
|
7476 | const basePath = host.resolve(projectDir);
|
7477 | return { projectFile, basePath };
|
7478 | }
|
7479 | function readConfiguration(project, existingOptions, host = getFileSystem()) {
|
7480 | var _a, _b;
|
7481 | try {
|
7482 | const fs = getFileSystem();
|
7483 | const readConfigFile = (configFile) => ts37.readConfigFile(configFile, (file) => host.readFile(host.resolve(file)));
|
7484 | const readAngularCompilerOptions = (configFile, parentOptions = {}) => {
|
7485 | const { config: config2, error: error2 } = readConfigFile(configFile);
|
7486 | if (error2) {
|
7487 | return parentOptions;
|
7488 | }
|
7489 | const existingNgCompilerOptions = __spreadValues(__spreadValues({}, config2.angularCompilerOptions), parentOptions);
|
7490 | if (config2.extends && typeof config2.extends === "string") {
|
7491 | const extendedConfigPath = getExtendedConfigPath(configFile, config2.extends, host, fs);
|
7492 | if (extendedConfigPath !== null) {
|
7493 | return readAngularCompilerOptions(extendedConfigPath, existingNgCompilerOptions);
|
7494 | }
|
7495 | }
|
7496 | return existingNgCompilerOptions;
|
7497 | };
|
7498 | const { projectFile, basePath } = calcProjectFileAndBasePath(project, host);
|
7499 | const configFileName = host.resolve(host.pwd(), projectFile);
|
7500 | const { config, error } = readConfigFile(projectFile);
|
7501 | if (error) {
|
7502 | return {
|
7503 | project,
|
7504 | errors: [error],
|
7505 | rootNames: [],
|
7506 | options: {},
|
7507 | emitFlags: EmitFlags.Default
|
7508 | };
|
7509 | }
|
7510 | const existingCompilerOptions = __spreadValues(__spreadValues({
|
7511 | genDir: basePath,
|
7512 | basePath
|
7513 | }, readAngularCompilerOptions(configFileName)), existingOptions);
|
7514 | const parseConfigHost = createParseConfigHost(host, fs);
|
7515 | const { options, errors, fileNames: rootNames, projectReferences } = ts37.parseJsonConfigFileContent(config, parseConfigHost, basePath, existingCompilerOptions, configFileName);
|
7516 | options.enableIvy = !!((_a = options.enableIvy) != null ? _a : true);
|
7517 | let emitFlags = EmitFlags.Default;
|
7518 | if (!(options.skipMetadataEmit || options.flatModuleOutFile)) {
|
7519 | emitFlags |= EmitFlags.Metadata;
|
7520 | }
|
7521 | if (options.skipTemplateCodegen) {
|
7522 | emitFlags = emitFlags & ~EmitFlags.Codegen;
|
7523 | }
|
7524 | return { project: projectFile, rootNames, projectReferences, options, errors, emitFlags };
|
7525 | } catch (e) {
|
7526 | const errors = [{
|
7527 | category: ts37.DiagnosticCategory.Error,
|
7528 | messageText: (_b = e.stack) != null ? _b : e.message,
|
7529 | file: void 0,
|
7530 | start: void 0,
|
7531 | length: void 0,
|
7532 | source: "angular",
|
7533 | code: UNKNOWN_ERROR_CODE
|
7534 | }];
|
7535 | return { project: "", errors, rootNames: [], options: {}, emitFlags: EmitFlags.Default };
|
7536 | }
|
7537 | }
|
7538 | function createParseConfigHost(host, fs = getFileSystem()) {
|
7539 | return {
|
7540 | fileExists: host.exists.bind(host),
|
7541 | readDirectory: ts37.sys.readDirectory,
|
7542 | readFile: host.readFile.bind(host),
|
7543 | useCaseSensitiveFileNames: fs.isCaseSensitive()
|
7544 | };
|
7545 | }
|
7546 | function getExtendedConfigPath(configFile, extendsValue, host, fs) {
|
7547 | const result = getExtendedConfigPathWorker(configFile, extendsValue, host, fs);
|
7548 | if (result !== null) {
|
7549 | return result;
|
7550 | }
|
7551 | return getExtendedConfigPathWorker(configFile, `${extendsValue}.json`, host, fs);
|
7552 | }
|
7553 | function getExtendedConfigPathWorker(configFile, extendsValue, host, fs) {
|
7554 | if (extendsValue.startsWith(".") || fs.isRooted(extendsValue)) {
|
7555 | const extendedConfigPath = host.resolve(host.dirname(configFile), extendsValue);
|
7556 | if (host.exists(extendedConfigPath)) {
|
7557 | return extendedConfigPath;
|
7558 | }
|
7559 | } else {
|
7560 | const parseConfigHost = createParseConfigHost(host, fs);
|
7561 | const { resolvedModule } = ts37.nodeModuleNameResolver(extendsValue, configFile, { moduleResolution: ts37.ModuleResolutionKind.NodeJs, resolveJsonModule: true }, parseConfigHost);
|
7562 | if (resolvedModule) {
|
7563 | return absoluteFrom(resolvedModule.resolvedFileName);
|
7564 | }
|
7565 | }
|
7566 | return null;
|
7567 | }
|
7568 | function exitCodeFromResult(diags) {
|
7569 | if (!diags)
|
7570 | return 0;
|
7571 | if (diags.every((diag) => diag.category !== ts37.DiagnosticCategory.Error)) {
|
7572 | return 0;
|
7573 | }
|
7574 | return diags.some((d) => d.source === "angular" && d.code === UNKNOWN_ERROR_CODE) ? 2 : 1;
|
7575 | }
|
7576 | function performCompilation({ rootNames, options, host, oldProgram, emitCallback, mergeEmitResultsCallback, gatherDiagnostics = defaultGatherDiagnostics, customTransformers, emitFlags = EmitFlags.Default, modifiedResourceFiles = null }) {
|
7577 | var _a;
|
7578 | let program;
|
7579 | let emitResult;
|
7580 | let allDiagnostics = [];
|
7581 | try {
|
7582 | if (!host) {
|
7583 | host = createCompilerHost({ options });
|
7584 | }
|
7585 | if (modifiedResourceFiles) {
|
7586 | host.getModifiedResourceFiles = () => modifiedResourceFiles;
|
7587 | }
|
7588 | program = createProgram({ rootNames, host, options, oldProgram });
|
7589 | const beforeDiags = Date.now();
|
7590 | allDiagnostics.push(...gatherDiagnostics(program));
|
7591 | if (options.diagnostics) {
|
7592 | const afterDiags = Date.now();
|
7593 | allDiagnostics.push(createMessageDiagnostic(`Time for diagnostics: ${afterDiags - beforeDiags}ms.`));
|
7594 | }
|
7595 | if (!hasErrors(allDiagnostics)) {
|
7596 | emitResult = program.emit({ emitCallback, mergeEmitResultsCallback, customTransformers, emitFlags });
|
7597 | allDiagnostics.push(...emitResult.diagnostics);
|
7598 | return { diagnostics: allDiagnostics, program, emitResult };
|
7599 | }
|
7600 | return { diagnostics: allDiagnostics, program };
|
7601 | } catch (e) {
|
7602 | program = void 0;
|
7603 | allDiagnostics.push({
|
7604 | category: ts37.DiagnosticCategory.Error,
|
7605 | messageText: (_a = e.stack) != null ? _a : e.message,
|
7606 | code: UNKNOWN_ERROR_CODE,
|
7607 | file: void 0,
|
7608 | start: void 0,
|
7609 | length: void 0
|
7610 | });
|
7611 | return { diagnostics: allDiagnostics, program };
|
7612 | }
|
7613 | }
|
7614 | function defaultGatherDiagnostics(program) {
|
7615 | const allDiagnostics = [];
|
7616 | function checkDiagnostics(diags) {
|
7617 | if (diags) {
|
7618 | allDiagnostics.push(...diags);
|
7619 | return !hasErrors(diags);
|
7620 | }
|
7621 | return true;
|
7622 | }
|
7623 | let checkOtherDiagnostics = true;
|
7624 | checkOtherDiagnostics = checkOtherDiagnostics && checkDiagnostics([...program.getTsOptionDiagnostics(), ...program.getNgOptionDiagnostics()]);
|
7625 | checkOtherDiagnostics = checkOtherDiagnostics && checkDiagnostics(program.getTsSyntacticDiagnostics());
|
7626 | checkOtherDiagnostics = checkOtherDiagnostics && checkDiagnostics([...program.getTsSemanticDiagnostics(), ...program.getNgStructuralDiagnostics()]);
|
7627 | checkOtherDiagnostics = checkOtherDiagnostics && checkDiagnostics(program.getNgSemanticDiagnostics());
|
7628 | return allDiagnostics;
|
7629 | }
|
7630 | function hasErrors(diags) {
|
7631 | return diags.some((d) => d.category === ts37.DiagnosticCategory.Error);
|
7632 | }
|
7633 |
|
7634 | export {
|
7635 | DEFAULT_ERROR_CODE,
|
7636 | UNKNOWN_ERROR_CODE,
|
7637 | SOURCE,
|
7638 | isTsDiagnostic,
|
7639 | EmitFlags,
|
7640 | createCompilerHost,
|
7641 | CycleAnalyzer,
|
7642 | ImportGraph,
|
7643 | isShim,
|
7644 | untagAllTsFiles,
|
7645 | TsCreateProgramDriver,
|
7646 | PatchedProgramIncrementalBuildStrategy,
|
7647 | MetadataDtsModuleScopeResolver,
|
7648 | LocalModuleScopeRegistry,
|
7649 | TypeCheckScopeRegistry,
|
7650 | OptimizeFor,
|
7651 | freshCompilationTicket,
|
7652 | incrementalFromStateTicket,
|
7653 | NgCompiler,
|
7654 | NgCompilerHost,
|
7655 | NgtscProgram,
|
7656 | createProgram,
|
7657 | GENERATED_FILES,
|
7658 | createMessageDiagnostic,
|
7659 | formatDiagnostics,
|
7660 | calcProjectFileAndBasePath,
|
7661 | readConfiguration,
|
7662 | exitCodeFromResult,
|
7663 | performCompilation,
|
7664 | defaultGatherDiagnostics
|
7665 | };
|
7666 |
|
7667 |
|
7668 |
|
7669 |
|
7670 |
|
7671 |
|
7672 |
|
7673 |
|
7674 |
|