Skip to content
This repository was archived by the owner on Mar 12, 2022. It is now read-only.

Commit 06e77c2

Browse files
committed
fix performance issue for Blade linemarkers: targets must be attached to leaf elements #161
1 parent 7126f98 commit 06e77c2

File tree

1 file changed

+111
-80
lines changed

1 file changed

+111
-80
lines changed

src/de/espend/idea/laravel/blade/TemplateLineMarker.java

Lines changed: 111 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.intellij.psi.PsiElement;
1313
import com.intellij.psi.PsiFile;
1414
import com.intellij.psi.PsiManager;
15+
import com.intellij.psi.impl.source.tree.LeafPsiElement;
1516
import com.intellij.psi.search.GlobalSearchScope;
1617
import com.intellij.util.ConstantFunction;
1718
import com.intellij.util.indexing.FileBasedIndex;
@@ -47,7 +48,7 @@ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) {
4748
}
4849

4950
@Override
50-
public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements, @NotNull Collection<LineMarkerInfo> collection) {
51+
public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements, @NotNull Collection<LineMarkerInfo> lineMarkers) {
5152
// we need project element; so get it from first item
5253
if(psiElements.size() == 0) {
5354
return;
@@ -62,56 +63,71 @@ public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements, @NotNu
6263

6364
for(PsiElement psiElement: psiElements) {
6465
if(psiElement instanceof PsiFile) {
65-
// template file like rendering:
66-
67-
if(resolver == null) resolver = new LazyVirtualFileTemplateResolver();
68-
collectTemplateFileRelatedFiles((PsiFile) psiElement, collection, resolver);
69-
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.SECTION_DIRECTIVE) {
70-
Pair<PsiElement, String> section = extractSectionParameter(psiElement);
71-
if(section != null) {
72-
if(resolver == null) {
73-
resolver = new LazyVirtualFileTemplateResolver();
74-
}
66+
// template file like rendering: like "extends" path
7567

76-
collectOverwrittenSection(section.getFirst(), collection, section.getSecond(), resolver);
77-
collectImplementsSection(section.getFirst(), collection, section.getSecond(), resolver);
68+
if (resolver == null) {
69+
resolver = new LazyVirtualFileTemplateResolver();
7870
}
79-
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.YIELD_DIRECTIVE) {
80-
Pair<PsiElement, String> section = extractSectionParameter(psiElement);
81-
if(section != null) {
82-
if(resolver == null) {
83-
resolver = new LazyVirtualFileTemplateResolver();
71+
72+
lineMarkers.addAll(collectTemplateFileRelatedFiles((PsiFile) psiElement, resolver));
73+
} else if(psiElement instanceof LeafPsiElement) {
74+
75+
if (psiElement.getNode().getElementType() == BladeTokenTypes.SECTION_DIRECTIVE) {
76+
// @section()
77+
78+
Pair<BladePsiDirectiveParameter, String> section = extractSectionParameter(psiElement);
79+
if(section != null) {
80+
if(resolver == null) {
81+
resolver = new LazyVirtualFileTemplateResolver();
82+
}
83+
84+
lineMarkers.addAll(collectOverwrittenSection((LeafPsiElement) psiElement, section.getSecond(), resolver));
85+
lineMarkers.addAll(collectImplementsSection((LeafPsiElement) psiElement, section.getSecond(), resolver));
8486
}
87+
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.YIELD_DIRECTIVE) {
88+
// @yield()
8589

86-
collectImplementsSection(section.getFirst(), collection, section.getSecond(), resolver);
87-
}
88-
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.STACK_DIRECTIVE) {
89-
Pair<PsiElement, String> section = extractSectionParameter(psiElement);
90-
if(section != null) {
91-
if(resolver == null) {
92-
resolver = new LazyVirtualFileTemplateResolver();
90+
Pair<BladePsiDirectiveParameter, String> section = extractSectionParameter(psiElement);
91+
if(section != null) {
92+
if(resolver == null) {
93+
resolver = new LazyVirtualFileTemplateResolver();
94+
}
95+
96+
lineMarkers.addAll(collectImplementsSection((LeafPsiElement) psiElement, section.getSecond(), resolver));
9397
}
98+
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.STACK_DIRECTIVE) {
99+
// @stack()
94100

95-
collectStackImplements(section.getFirst(), collection, section.getSecond(), resolver);
96-
}
97-
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.PUSH_DIRECTIVE) {
98-
Pair<PsiElement, String> section = extractSectionParameter(psiElement);
99-
if(section != null) {
100-
if(resolver == null) {
101-
resolver = new LazyVirtualFileTemplateResolver();
101+
Pair<BladePsiDirectiveParameter, String> section = extractSectionParameter(psiElement);
102+
if(section != null) {
103+
if(resolver == null) {
104+
resolver = new LazyVirtualFileTemplateResolver();
105+
}
106+
107+
lineMarkers.addAll(collectStackImplements((LeafPsiElement) psiElement, section.getSecond(), resolver));
102108
}
109+
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.PUSH_DIRECTIVE) {
110+
// @push('scripts')
103111

104-
collectPushOverwrites(section.getFirst(), collection, section.getSecond());
105-
}
106-
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.SLOT_DIRECTIVE) {
107-
// @slot('foobar')
108-
Pair<PsiElement, String> section = extractSectionParameter(psiElement);
109-
if(section != null) {
110-
if(resolver == null) {
111-
resolver = new LazyVirtualFileTemplateResolver();
112+
Pair<BladePsiDirectiveParameter, String> section = extractSectionParameter(psiElement);
113+
if(section != null) {
114+
if(resolver == null) {
115+
resolver = new LazyVirtualFileTemplateResolver();
116+
}
117+
118+
lineMarkers.addAll(collectPushOverwrites((LeafPsiElement) psiElement, section.getSecond()));
112119
}
120+
} else if(psiElement.getNode().getElementType() == BladeTokenTypes.SLOT_DIRECTIVE) {
121+
// @slot('foobar')
113122

114-
collectSlotOverwrites(section.getFirst(), collection, section.getSecond(), resolver);
123+
Pair<BladePsiDirectiveParameter, String> section = extractSectionParameter(psiElement);
124+
if (section != null) {
125+
if (resolver == null) {
126+
resolver = new LazyVirtualFileTemplateResolver();
127+
}
128+
129+
lineMarkers.addAll(collectSlotOverwrites((LeafPsiElement) psiElement, section.getFirst(), section.getSecond(), resolver));
130+
}
115131
}
116132
}
117133
}
@@ -121,25 +137,25 @@ public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements, @NotNu
121137
* Extract parameter: @foobar('my_value')
122138
*/
123139
@Nullable
124-
private Pair<PsiElement, String> extractSectionParameter(@NotNull PsiElement psiElement) {
140+
private Pair<BladePsiDirectiveParameter, String> extractSectionParameter(@NotNull PsiElement psiElement) {
125141
PsiElement nextSibling = psiElement.getNextSibling();
126142

127143
if(nextSibling instanceof BladePsiDirectiveParameter) {
128144
String sectionName = BladePsiUtil.getSection(nextSibling);
129145
if (sectionName != null && StringUtils.isNotBlank(sectionName)) {
130-
return Pair.create(nextSibling, sectionName);
146+
return Pair.create((BladePsiDirectiveParameter) nextSibling, sectionName);
131147
}
132148
}
133149

134150
return null;
135151
}
136152

137153
/**
138-
* like this @section('sidebar')
154+
* Like this @section('sidebar')
139155
*/
140-
private void collectOverwrittenSection(final PsiElement psiElement, @NotNull Collection<LineMarkerInfo> collection, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
141-
142-
final List<GotoRelatedItem> gotoRelatedItems = new ArrayList<>();
156+
@NotNull
157+
private Collection<LineMarkerInfo> collectOverwrittenSection(@NotNull LeafPsiElement psiElement, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
158+
List<GotoRelatedItem> gotoRelatedItems = new ArrayList<>();
143159

144160
for(PsiElement psiElement1 : psiElement.getContainingFile().getChildren()) {
145161
PsiElement extendDirective = psiElement1.getFirstChild();
@@ -160,16 +176,19 @@ private void collectOverwrittenSection(final PsiElement psiElement, @NotNull Col
160176
}
161177

162178
if(gotoRelatedItems.size() == 0) {
163-
return;
179+
return Collections.emptyList();
164180
}
165181

166-
collection.add(getRelatedPopover("Parent Section", "Blade Section", psiElement, gotoRelatedItems, PhpIcons.OVERRIDES));
182+
return Collections.singletonList(
183+
getRelatedPopover("Parent Section", "Blade Section", psiElement, gotoRelatedItems, PhpIcons.OVERRIDES)
184+
);
167185
}
168186

169-
private void collectTemplateFileRelatedFiles(@NotNull PsiFile psiFile, @NotNull Collection<LineMarkerInfo> collection, @NotNull LazyVirtualFileTemplateResolver resolver) {
187+
@NotNull
188+
private Collection<LineMarkerInfo> collectTemplateFileRelatedFiles(@NotNull PsiFile psiFile, @NotNull LazyVirtualFileTemplateResolver resolver) {
170189
Collection<String> collectedTemplates = resolver.resolveTemplateName(psiFile);
171190
if(collectedTemplates.size() == 0) {
172-
return;
191+
return Collections.emptyList();
173192
}
174193

175194
// lowercase for index
@@ -202,13 +221,15 @@ private void collectTemplateFileRelatedFiles(@NotNull PsiFile psiFile, @NotNull
202221
}
203222
}
204223

224+
Collection<LineMarkerInfo> lineMarkers = new ArrayList<>();
225+
205226
if(includeLineMarker.get()) {
206227
NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder
207228
.create(PhpIcons.IMPLEMENTED)
208229
.setTargets(new TemplateIncludeCollectionNotNullLazyValue(psiFile.getProject(), templateNames))
209230
.setTooltipText("Navigate to Blade file");
210231

211-
collection.add(builder.createLineMarkerInfo(psiFile));
232+
lineMarkers.add(builder.createLineMarkerInfo(psiFile));
212233
}
213234

214235
// try to find at least von controller target; lazyly load target later via click
@@ -227,12 +248,14 @@ private void collectTemplateFileRelatedFiles(@NotNull PsiFile psiFile, @NotNull
227248
.setTargets(new ControllerRenderViewCollectionNotNullLazyValue(psiFile.getProject(), templateNames))
228249
.setTooltipText("Navigate to controller");
229250

230-
collection.add(builder.createLineMarkerInfo(psiFile));
251+
lineMarkers.add(builder.createLineMarkerInfo(psiFile));
231252
}
232-
}
233253

234-
private LineMarkerInfo getRelatedPopover(String singleItemTitle, String singleItemTooltipPrefix, PsiElement lineMarkerTarget, Collection<GotoRelatedItem> gotoRelatedItems, Icon icon) {
254+
return lineMarkers;
255+
}
235256

257+
@NotNull
258+
private LineMarkerInfo getRelatedPopover(@NotNull String singleItemTitle, @NotNull String singleItemTooltipPrefix, @NotNull PsiElement lineMarkerTarget, @NotNull Collection<GotoRelatedItem> gotoRelatedItems, @NotNull Icon icon) {
236259
// single item has no popup
237260
String title = singleItemTitle;
238261
if(gotoRelatedItems.size() == 1) {
@@ -253,11 +276,11 @@ private LineMarkerInfo getRelatedPopover(String singleItemTitle, String singleIt
253276
);
254277
}
255278

256-
private void visitOverwrittenTemplateFile(final PsiFile psiFile, final List<GotoRelatedItem> gotoRelatedItems, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
279+
private void visitOverwrittenTemplateFile(@NotNull PsiFile psiFile, @NotNull List<GotoRelatedItem> gotoRelatedItems, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
257280
visitOverwrittenTemplateFile(psiFile, gotoRelatedItems, sectionName, 10, resolver);
258281
}
259282

260-
private void visitOverwrittenTemplateFile(final PsiFile psiFile, final List<GotoRelatedItem> gotoRelatedItems, @NotNull String sectionName, int depth, @NotNull LazyVirtualFileTemplateResolver resolver) {
283+
private void visitOverwrittenTemplateFile(@NotNull PsiFile psiFile, @NotNull List<GotoRelatedItem> gotoRelatedItems, @NotNull String sectionName, int depth, @NotNull LazyVirtualFileTemplateResolver resolver) {
261284
// simple secure recursive calls
262285
if(depth-- <= 0) {
263286
return;
@@ -288,17 +311,18 @@ private void visitOverwrittenTemplateFile(final PsiFile psiFile, final List<Goto
288311
* Find all sub implementations of a section that are overwritten by an extends tag
289312
* Possible targets are: @section('sidebar')
290313
*/
291-
private void collectImplementsSection(@NotNull PsiElement psiElement, @NotNull Collection<LineMarkerInfo> collection, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
314+
@NotNull
315+
private Collection<LineMarkerInfo> collectImplementsSection(@NotNull LeafPsiElement psiElement, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
292316
Collection<String> templateNames = resolver.resolveTemplateName(psiElement.getContainingFile());
293317
if(templateNames.size() == 0) {
294-
return;
318+
return Collections.emptyList();
295319
}
296320

297321
Collection<GotoRelatedItem> gotoRelatedItems = new ArrayList<>();
298322

299323
Set<VirtualFile> virtualFiles = BladeTemplateUtil.getExtendsImplementations(psiElement.getProject(), templateNames);
300324
if(virtualFiles.size() == 0) {
301-
return;
325+
return Collections.emptyList();
302326
}
303327

304328
for(VirtualFile virtualFile: virtualFiles) {
@@ -313,26 +337,29 @@ private void collectImplementsSection(@NotNull PsiElement psiElement, @NotNull C
313337
}
314338

315339
if(gotoRelatedItems.size() == 0) {
316-
return;
340+
return Collections.emptyList();
317341
}
318342

319-
collection.add(getRelatedPopover("Template", "Blade File", psiElement, gotoRelatedItems, PhpIcons.IMPLEMENTED));
343+
return Collections.singletonList(
344+
getRelatedPopover("Template", "Blade File", psiElement, gotoRelatedItems, PhpIcons.IMPLEMENTED)
345+
);
320346
}
321347

322348
/**
323349
* Support: @stack('foobar')
324350
*/
325-
private void collectStackImplements(@NotNull PsiElement psiElement, @NotNull Collection<LineMarkerInfo> collection, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
351+
@NotNull
352+
private Collection<LineMarkerInfo> collectStackImplements(@NotNull LeafPsiElement psiElement, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
326353
Collection<String> templateNames = resolver.resolveTemplateName(psiElement.getContainingFile());
327354
if(templateNames.size() == 0) {
328-
return;
355+
return Collections.emptyList();
329356
}
330357

331-
final List<GotoRelatedItem> gotoRelatedItems = new ArrayList<>();
358+
List<GotoRelatedItem> gotoRelatedItems = new ArrayList<>();
332359

333360
Set<VirtualFile> virtualFiles = BladeTemplateUtil.getExtendsImplementations(psiElement.getProject(), templateNames);
334361
if(virtualFiles.size() == 0) {
335-
return;
362+
return Collections.emptyList();
336363
}
337364

338365
for(VirtualFile virtualFile: virtualFiles) {
@@ -347,16 +374,19 @@ private void collectStackImplements(@NotNull PsiElement psiElement, @NotNull Col
347374
}
348375

349376
if(gotoRelatedItems.size() == 0) {
350-
return;
377+
return Collections.emptyList();
351378
}
352379

353-
collection.add(getRelatedPopover("Push Implementation", "Push Implementation", psiElement, gotoRelatedItems, PhpIcons.IMPLEMENTED));
380+
return Collections.singletonList(
381+
getRelatedPopover("Push Implementation", "Push Implementation", psiElement, gotoRelatedItems, PhpIcons.IMPLEMENTED)
382+
);
354383
}
355384

356385
/**
357386
* Support: @push('foobar')
358387
*/
359-
private void collectPushOverwrites(@NotNull PsiElement psiElement, @NotNull Collection<LineMarkerInfo> collection, @NotNull String sectionName) {
388+
@NotNull
389+
private Collection<LineMarkerInfo> collectPushOverwrites(@NotNull LeafPsiElement psiElement, @NotNull String sectionName) {
360390
final List<GotoRelatedItem> gotoRelatedItems = new ArrayList<>();
361391

362392
BladeTemplateUtil.visitUpPath(psiElement.getContainingFile(), 10, parameter -> {
@@ -366,23 +396,22 @@ private void collectPushOverwrites(@NotNull PsiElement psiElement, @NotNull Coll
366396
}, BladeTokenTypes.STACK_DIRECTIVE);
367397

368398
if(gotoRelatedItems.size() == 0) {
369-
return;
399+
return Collections.emptyList();
370400
}
371401

372-
collection.add(getRelatedPopover("Stack Section", "Stack Overwrites", psiElement, gotoRelatedItems, PhpIcons.OVERRIDES));
402+
return Collections.singletonList(
403+
getRelatedPopover("Stack Section", "Stack Overwrites", psiElement, gotoRelatedItems, PhpIcons.OVERRIDES)
404+
);
373405
}
374406

375407
/**
376408
* Support: @slot('foobar')
377409
*/
378-
private void collectSlotOverwrites(@NotNull PsiElement psiElement, @NotNull Collection<LineMarkerInfo> collection, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
379-
if(!(psiElement instanceof BladePsiDirectiveParameter)) {
380-
return;
381-
}
382-
383-
String component = BladePsiUtil.findComponentForSlotScope((BladePsiDirectiveParameter) psiElement);
410+
@NotNull
411+
private Collection<LineMarkerInfo> collectSlotOverwrites(@NotNull LeafPsiElement psiElement, @NotNull BladePsiDirectiveParameter parameter, @NotNull String sectionName, @NotNull LazyVirtualFileTemplateResolver resolver) {
412+
String component = BladePsiUtil.findComponentForSlotScope(parameter);
384413
if(component == null) {
385-
return;
414+
return Collections.emptyList();
386415
}
387416

388417
List<GotoRelatedItem> gotoRelatedItems = new ArrayList<>();
@@ -401,10 +430,12 @@ private void collectSlotOverwrites(@NotNull PsiElement psiElement, @NotNull Coll
401430
}
402431

403432
if(gotoRelatedItems.size() == 0) {
404-
return;
433+
return Collections.emptyList();
405434
}
406435

407-
collection.add(getRelatedPopover("Slot Overwrites", "Slot Overwrites", psiElement, gotoRelatedItems, PhpIcons.OVERRIDES));
436+
return Collections.singletonList(
437+
getRelatedPopover("Slot Overwrites", "Slot Overwrites", psiElement, gotoRelatedItems, PhpIcons.OVERRIDES)
438+
);
408439
}
409440

410441
/**

0 commit comments

Comments
 (0)