1 | ;
|
2 | /**
|
3 | * @license
|
4 | * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
5 | * This code may only be used under the BSD style license found at
|
6 | * http://polymer.github.io/LICENSE.txt
|
7 | * The complete set of authors may be found at
|
8 | * http://polymer.github.io/AUTHORS.txt
|
9 | * The complete set of contributors may be found at
|
10 | * http://polymer.github.io/CONTRIBUTORS.txt
|
11 | * Code distributed by Google as part of the polymer project is also
|
12 | * subject to an additional IP rights grant found at
|
13 | * http://polymer.github.io/PATENTS.txt
|
14 | */
|
15 | Object.defineProperty(exports, "__esModule", { value: true });
|
16 | const async_work_cache_1 = require("./async-work-cache");
|
17 | const dependency_graph_1 = require("./dependency-graph");
|
18 | class AnalysisCache {
|
19 | /**
|
20 | * @param from Another AnalysisCache to copy the caches from. The new
|
21 | * AnalysisCache will have an independent copy of everything but from's
|
22 | * dependency graph, which is passed in separately.
|
23 | * @param newDependencyGraph If given, use this dependency graph. We pass
|
24 | * this in like this purely as an optimization. See `invalidatePaths`.
|
25 | */
|
26 | constructor(from, newDependencyGraph) {
|
27 | const f = from || {};
|
28 | this.parsedDocumentPromises = new async_work_cache_1.AsyncWorkCache(f.parsedDocumentPromises);
|
29 | this.scannedDocumentPromises =
|
30 | new async_work_cache_1.AsyncWorkCache(f.scannedDocumentPromises);
|
31 | this.analyzedDocumentPromises =
|
32 | new async_work_cache_1.AsyncWorkCache(f.analyzedDocumentPromises);
|
33 | this.dependenciesScannedPromises =
|
34 | new async_work_cache_1.AsyncWorkCache(f.dependenciesScannedPromises);
|
35 | this.failedDocuments = new Map(f.failedDocuments);
|
36 | this.scannedDocuments = new Map(f.scannedDocuments);
|
37 | this.analyzedDocuments = new Map(f.analyzedDocuments);
|
38 | this.dependencyGraph = newDependencyGraph || new dependency_graph_1.DependencyGraph();
|
39 | }
|
40 | /**
|
41 | * Returns a copy of this cache, with the given document and all of its
|
42 | * transitive dependants invalidated.
|
43 | *
|
44 | * Must be called whenever a document changes.
|
45 | */
|
46 | invalidate(documentPaths) {
|
47 | // TODO(rictic): how much of this work can we short circuit in the case
|
48 | // none of these paths are in any of the caches? e.g. when someone calls
|
49 | // filesChanged() for the same files twice without ever calling analyze?
|
50 | // Could end up saving some work in the editor case.
|
51 | // On the other hand, copying a half dozen maps with maybe 200 entries
|
52 | // each should be pretty cheap, maybe not worth the effort.
|
53 | const newCache = new AnalysisCache(this, this.dependencyGraph.invalidatePaths(documentPaths));
|
54 | for (const path of documentPaths) {
|
55 | // Note that we must calculate the dependency graph based on the parent,
|
56 | // not the forked newCache.
|
57 | const dependants = this.dependencyGraph.getAllDependantsOf(path);
|
58 | newCache.parsedDocumentPromises.delete(path);
|
59 | newCache.scannedDocumentPromises.delete(path);
|
60 | newCache.dependenciesScannedPromises.delete(path);
|
61 | newCache.scannedDocuments.delete(path);
|
62 | newCache.analyzedDocuments.delete(path);
|
63 | newCache.failedDocuments.delete(path);
|
64 | // Analyzed documents need to be treated more carefully, because they have
|
65 | // relationships with other documents. So first we remove all documents
|
66 | // which transitively import the changed document. We also need to mark
|
67 | // all of those docs as needing to rescan their dependencies.
|
68 | for (const partiallyInvalidatedPath of dependants) {
|
69 | newCache.dependenciesScannedPromises.delete(partiallyInvalidatedPath);
|
70 | newCache.analyzedDocuments.delete(partiallyInvalidatedPath);
|
71 | }
|
72 | // Then we clear out the analyzed document promises, which could have
|
73 | // in-progress results that don't cohere with the state of the new cache.
|
74 | // Only populate the new analyzed promise cache with results that are
|
75 | // definite, and not invalidated.
|
76 | newCache.analyzedDocumentPromises.clear();
|
77 | for (const keyValue of newCache.analyzedDocuments) {
|
78 | newCache.analyzedDocumentPromises.set(keyValue[0], keyValue[1]);
|
79 | }
|
80 | }
|
81 | return newCache;
|
82 | }
|
83 | toString() {
|
84 | let result = `<AnalysisCache`;
|
85 | if (this.scannedDocuments.size > 0) {
|
86 | result += `
|
87 | scannedDocuments:
|
88 | ${Array.from(this.scannedDocuments.keys()).join('\n ')}`;
|
89 | }
|
90 | if (this.analyzedDocuments.size > 0) {
|
91 | result += `
|
92 | analyzedDocuments:
|
93 | ${Array.from(this.analyzedDocuments.keys()).join('\n ')}`;
|
94 | }
|
95 | if (this.failedDocuments.size > 0) {
|
96 | result += `
|
97 | failedDocuments:
|
98 | ${Array.from(this.failedDocuments.keys()).join('\n ')}`;
|
99 | }
|
100 | result += '>';
|
101 | return result;
|
102 | }
|
103 | }
|
104 | exports.AnalysisCache = AnalysisCache;
|
105 | //# sourceMappingURL=analysis-cache.js.map |
\ | No newline at end of file |