blob: 0f5a4b9015545a0131509416cf01bc39f7335763 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
Tim van der Lippe8987f8f2020-01-03 15:03:1628
Blink Reformat4c46d092018-04-07 15:32:3729/**
30 * @implements {Search.SearchScope}
31 */
Paul Lewis39944952020-01-22 15:45:1832export class SourcesSearchScope {
Blink Reformat4c46d092018-04-07 15:32:3733 constructor() {
34 // FIXME: Add title once it is used by search controller.
35 this._searchId = 0;
36 /** @type {!Array<!Workspace.UISourceCode>} */
37 this._searchResultCandidates = [];
38 /** @type {?function(!Search.SearchResult)} */
39 this._searchResultCallback = null;
40 /** @type {?function(boolean)} */
41 this._searchFinishedCallback = null;
42 /** @type {?Workspace.ProjectSearchConfig} */
43 this._searchConfig = null;
44 }
45
46 /**
47 * @param {!Workspace.UISourceCode} uiSourceCode1
48 * @param {!Workspace.UISourceCode} uiSourceCode2
49 * @return {number}
50 */
51 static _filesComparator(uiSourceCode1, uiSourceCode2) {
Tim van der Lippe1d6e57a2019-09-30 11:55:3452 if (uiSourceCode1.isDirty() && !uiSourceCode2.isDirty()) {
Blink Reformat4c46d092018-04-07 15:32:3753 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:3454 }
55 if (!uiSourceCode1.isDirty() && uiSourceCode2.isDirty()) {
Blink Reformat4c46d092018-04-07 15:32:3756 return 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:3457 }
Joel Einbinderef3555d2018-12-04 02:14:4458 const isFileSystem1 = uiSourceCode1.project().type() === Workspace.projectTypes.FileSystem &&
59 !Persistence.persistence.binding(uiSourceCode1);
60 const isFileSystem2 = uiSourceCode2.project().type() === Workspace.projectTypes.FileSystem &&
61 !Persistence.persistence.binding(uiSourceCode2);
Tim van der Lippe1d6e57a2019-09-30 11:55:3462 if (isFileSystem1 !== isFileSystem2) {
Joel Einbinderef3555d2018-12-04 02:14:4463 return isFileSystem1 ? 1 : -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:3464 }
Blink Reformat4c46d092018-04-07 15:32:3765 const url1 = uiSourceCode1.url();
66 const url2 = uiSourceCode2.url();
Tim van der Lippe1d6e57a2019-09-30 11:55:3467 if (url1 && !url2) {
Blink Reformat4c46d092018-04-07 15:32:3768 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:3469 }
70 if (!url1 && url2) {
Blink Reformat4c46d092018-04-07 15:32:3771 return 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:3472 }
Blink Reformat4c46d092018-04-07 15:32:3773 return String.naturalOrderComparator(uiSourceCode1.fullDisplayName(), uiSourceCode2.fullDisplayName());
74 }
75
76 /**
77 * @override
78 * @param {!Common.Progress} progress
79 */
80 performIndexing(progress) {
81 this.stopSearch();
82
83 const projects = this._projects();
84 const compositeProgress = new Common.CompositeProgress(progress);
85 for (let i = 0; i < projects.length; ++i) {
86 const project = projects[i];
87 const projectProgress = compositeProgress.createSubProgress(project.uiSourceCodes().length);
88 project.indexContent(projectProgress);
89 }
90 }
91
92 /**
93 * @return {!Array.<!Workspace.Project>}
94 */
95 _projects() {
Paul Lewis4b64b3f2020-01-23 11:41:2096 const searchInAnonymousAndContentScripts =
97 self.Common.settings.moduleSetting('searchInAnonymousAndContentScripts').get();
Blink Reformat4c46d092018-04-07 15:32:3798
99 return Workspace.workspace.projects().filter(project => {
Tim van der Lippe1d6e57a2019-09-30 11:55:34100 if (project.type() === Workspace.projectTypes.Service) {
Blink Reformat4c46d092018-04-07 15:32:37101 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34102 }
103 if (!searchInAnonymousAndContentScripts && project.isServiceProject()) {
Blink Reformat4c46d092018-04-07 15:32:37104 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34105 }
106 if (!searchInAnonymousAndContentScripts && project.type() === Workspace.projectTypes.ContentScripts) {
Blink Reformat4c46d092018-04-07 15:32:37107 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34108 }
Blink Reformat4c46d092018-04-07 15:32:37109 return true;
110 });
111 }
112
113 /**
114 * @override
115 * @param {!Workspace.ProjectSearchConfig} searchConfig
116 * @param {!Common.Progress} progress
117 * @param {function(!Search.SearchResult)} searchResultCallback
118 * @param {function(boolean)} searchFinishedCallback
119 */
120 performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback) {
121 this.stopSearch();
122 this._searchResultCandidates = [];
123 this._searchResultCallback = searchResultCallback;
124 this._searchFinishedCallback = searchFinishedCallback;
125 this._searchConfig = searchConfig;
126
127 const promises = [];
128 const compositeProgress = new Common.CompositeProgress(progress);
129 const searchContentProgress = compositeProgress.createSubProgress();
130 const findMatchingFilesProgress = new Common.CompositeProgress(compositeProgress.createSubProgress());
131 for (const project of this._projects()) {
132 const weight = project.uiSourceCodes().length;
133 const findMatchingFilesInProjectProgress = findMatchingFilesProgress.createSubProgress(weight);
134 const filesMathingFileQuery = this._projectFilesMatchingFileQuery(project, searchConfig);
135 const promise =
136 project
137 .findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, findMatchingFilesInProjectProgress)
138 .then(this._processMatchingFilesForProject.bind(
139 this, this._searchId, project, searchConfig, filesMathingFileQuery));
140 promises.push(promise);
141 }
142
143 Promise.all(promises).then(this._processMatchingFiles.bind(
144 this, this._searchId, searchContentProgress, this._searchFinishedCallback.bind(this, true)));
145 }
146
147 /**
148 * @param {!Workspace.Project} project
149 * @param {!Workspace.ProjectSearchConfig} searchConfig
150 * @param {boolean=} dirtyOnly
151 * @return {!Array.<string>}
152 */
153 _projectFilesMatchingFileQuery(project, searchConfig, dirtyOnly) {
154 const result = [];
155 const uiSourceCodes = project.uiSourceCodes();
156 for (let i = 0; i < uiSourceCodes.length; ++i) {
157 const uiSourceCode = uiSourceCodes[i];
Tim van der Lippe1d6e57a2019-09-30 11:55:34158 if (!uiSourceCode.contentType().isTextType()) {
Blink Reformat4c46d092018-04-07 15:32:37159 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34160 }
Blink Reformat4c46d092018-04-07 15:32:37161 const binding = Persistence.persistence.binding(uiSourceCode);
Tim van der Lippe1d6e57a2019-09-30 11:55:34162 if (binding && binding.network === uiSourceCode) {
Blink Reformat4c46d092018-04-07 15:32:37163 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34164 }
165 if (dirtyOnly && !uiSourceCode.isDirty()) {
Blink Reformat4c46d092018-04-07 15:32:37166 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34167 }
168 if (searchConfig.filePathMatchesFileQuery(uiSourceCode.fullDisplayName())) {
Blink Reformat4c46d092018-04-07 15:32:37169 result.push(uiSourceCode.url());
Tim van der Lippe1d6e57a2019-09-30 11:55:34170 }
Blink Reformat4c46d092018-04-07 15:32:37171 }
172 result.sort(String.naturalOrderComparator);
173 return result;
174 }
175
176 /**
177 * @param {number} searchId
178 * @param {!Workspace.Project} project
179 * @param {!Workspace.ProjectSearchConfig} searchConfig
180 * @param {!Array<string>} filesMathingFileQuery
181 * @param {!Array<string>} files
182 */
183 _processMatchingFilesForProject(searchId, project, searchConfig, filesMathingFileQuery, files) {
184 if (searchId !== this._searchId) {
185 this._searchFinishedCallback(false);
186 return;
187 }
188
189 files.sort(String.naturalOrderComparator);
190 files = files.intersectOrdered(filesMathingFileQuery, String.naturalOrderComparator);
191 const dirtyFiles = this._projectFilesMatchingFileQuery(project, searchConfig, true);
192 files = files.mergeOrdered(dirtyFiles, String.naturalOrderComparator);
193
194 const uiSourceCodes = [];
195 for (const file of files) {
196 const uiSourceCode = project.uiSourceCodeForURL(file);
Tim van der Lippe1d6e57a2019-09-30 11:55:34197 if (!uiSourceCode) {
Blink Reformat4c46d092018-04-07 15:32:37198 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34199 }
Blink Reformat4c46d092018-04-07 15:32:37200 const script = Bindings.DefaultScriptMapping.scriptForUISourceCode(uiSourceCode);
Tim van der Lippe1d6e57a2019-09-30 11:55:34201 if (script && !script.isAnonymousScript()) {
Blink Reformat4c46d092018-04-07 15:32:37202 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34203 }
Blink Reformat4c46d092018-04-07 15:32:37204 uiSourceCodes.push(uiSourceCode);
205 }
Tim van der Lippe8987f8f2020-01-03 15:03:16206 uiSourceCodes.sort(SourcesSearchScope._filesComparator);
Blink Reformat4c46d092018-04-07 15:32:37207 this._searchResultCandidates =
Tim van der Lippe8987f8f2020-01-03 15:03:16208 this._searchResultCandidates.mergeOrdered(uiSourceCodes, SourcesSearchScope._filesComparator);
Blink Reformat4c46d092018-04-07 15:32:37209 }
210
211 /**
212 * @param {number} searchId
213 * @param {!Common.Progress} progress
214 * @param {function()} callback
215 */
216 _processMatchingFiles(searchId, progress, callback) {
217 if (searchId !== this._searchId) {
218 this._searchFinishedCallback(false);
219 return;
220 }
221
222 const files = this._searchResultCandidates;
223 if (!files.length) {
224 progress.done();
225 callback();
226 return;
227 }
228
229 progress.setTotalWork(files.length);
230
231 let fileIndex = 0;
232 const maxFileContentRequests = 20;
233 let callbacksLeft = 0;
234
Tim van der Lippe1d6e57a2019-09-30 11:55:34235 for (let i = 0; i < maxFileContentRequests && i < files.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:37236 scheduleSearchInNextFileOrFinish.call(this);
Tim van der Lippe1d6e57a2019-09-30 11:55:34237 }
Blink Reformat4c46d092018-04-07 15:32:37238
239 /**
240 * @param {!Workspace.UISourceCode} uiSourceCode
Tim van der Lippe8987f8f2020-01-03 15:03:16241 * @this {SourcesSearchScope}
Blink Reformat4c46d092018-04-07 15:32:37242 */
243 function searchInNextFile(uiSourceCode) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34244 if (uiSourceCode.isDirty()) {
Blink Reformat4c46d092018-04-07 15:32:37245 contentLoaded.call(this, uiSourceCode, uiSourceCode.workingCopy());
Tim van der Lippe1d6e57a2019-09-30 11:55:34246 } else {
Rob Paveza2eb8c142019-10-13 18:02:38247 uiSourceCode.requestContent().then(deferredContent => {
248 contentLoaded.call(this, uiSourceCode, deferredContent.content || '');
249 });
Tim van der Lippe1d6e57a2019-09-30 11:55:34250 }
Blink Reformat4c46d092018-04-07 15:32:37251 }
252
253 /**
Tim van der Lippe8987f8f2020-01-03 15:03:16254 * @this {SourcesSearchScope}
Blink Reformat4c46d092018-04-07 15:32:37255 */
256 function scheduleSearchInNextFileOrFinish() {
257 if (fileIndex >= files.length) {
258 if (!callbacksLeft) {
259 progress.done();
260 callback();
261 return;
262 }
263 return;
264 }
265
266 ++callbacksLeft;
267 const uiSourceCode = files[fileIndex++];
268 setTimeout(searchInNextFile.bind(this, uiSourceCode), 0);
269 }
270
271 /**
272 * @param {!Workspace.UISourceCode} uiSourceCode
Rob Paveza2eb8c142019-10-13 18:02:38273 * @param {string} content
Tim van der Lippe8987f8f2020-01-03 15:03:16274 * @this {SourcesSearchScope}
Blink Reformat4c46d092018-04-07 15:32:37275 */
276 function contentLoaded(uiSourceCode, content) {
277 /**
278 * @param {!Common.ContentProvider.SearchMatch} a
279 * @param {!Common.ContentProvider.SearchMatch} b
280 */
281 function matchesComparator(a, b) {
282 return a.lineNumber - b.lineNumber;
283 }
284
285 progress.worked(1);
286 let matches = [];
287 const queries = this._searchConfig.queries();
288 if (content !== null) {
289 for (let i = 0; i < queries.length; ++i) {
290 const nextMatches = Common.ContentProvider.performSearchInContent(
291 content, queries[i], !this._searchConfig.ignoreCase(), this._searchConfig.isRegex());
292 matches = matches.mergeOrdered(nextMatches, matchesComparator);
293 }
294 }
295 if (matches) {
Tim van der Lippe8987f8f2020-01-03 15:03:16296 const searchResult = new FileBasedSearchResult(uiSourceCode, matches);
Blink Reformat4c46d092018-04-07 15:32:37297 this._searchResultCallback(searchResult);
298 }
299
300 --callbacksLeft;
301 scheduleSearchInNextFileOrFinish.call(this);
302 }
303 }
304
305 /**
306 * @override
307 */
308 stopSearch() {
309 ++this._searchId;
310 }
Tim van der Lippe8987f8f2020-01-03 15:03:16311}
Blink Reformat4c46d092018-04-07 15:32:37312
313/**
314 * @implements {Search.SearchResult}
315 */
Tim van der Lippe8987f8f2020-01-03 15:03:16316export class FileBasedSearchResult {
Blink Reformat4c46d092018-04-07 15:32:37317 /**
318 * @param {!Workspace.UISourceCode} uiSourceCode
319 * @param {!Array.<!Common.ContentProvider.SearchMatch>} searchMatches
320 */
321 constructor(uiSourceCode, searchMatches) {
322 this._uiSourceCode = uiSourceCode;
323 this._searchMatches = searchMatches;
324 }
325
326 /**
327 * @override
328 * @return {string}
329 */
330 label() {
331 return this._uiSourceCode.displayName();
332 }
333
334 /**
335 * @override
336 * @return {string}
337 */
338 description() {
339 return this._uiSourceCode.fullDisplayName();
340 }
341
342 /**
343 * @override
344 * @return {number}
345 */
346 matchesCount() {
347 return this._searchMatches.length;
348 }
349
350 /**
351 * @override
352 * @param {number} index
353 * @return {string}
354 */
355 matchLineContent(index) {
356 return this._searchMatches[index].lineContent;
357 }
358
359 /**
360 * @override
361 * @param {number} index
362 * @return {!Object}
363 */
364 matchRevealable(index) {
365 const match = this._searchMatches[index];
Tim van der Lippeffa78622019-09-16 12:07:12366 return this._uiSourceCode.uiLocation(match.lineNumber, undefined);
Blink Reformat4c46d092018-04-07 15:32:37367 }
368
369 /**
370 * @override
371 * @param {number} index
372 * @return {?}
373 */
374 matchLabel(index) {
375 return this._searchMatches[index].lineNumber + 1;
376 }
Tim van der Lippe8987f8f2020-01-03 15:03:16377}