Skip to content

Commit 39f49bd

Browse files
authored
Merge pull request #84 from cedricziel/multi-build
Use ScalarIndexExtension instead of DirectoryScanner
2 parents 018c5dc + 646a34f commit 39f49bd

File tree

10 files changed

+155
-144
lines changed

10 files changed

+155
-144
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@ jdk:
55
before_cache:
66
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
77
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
8+
- rm -fr $HOME/.gradle/caches/*/fileHashes/fileHashes.bin
9+
- rm -fr $HOME/.gradle/caches/*/fileHashes/fileHashes.lock
810
cache:
911
directories:
1012
- $HOME/.gradle/caches/
1113
- $HOME/.gradle/wrapper/
1214
script:
15+
- "./gradlew check"
1316
- "./gradlew buildPlugin"
1417
deploy:
1518
provider: releases

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ apply plugin: 'java'
1818

1919
intellij {
2020
version 'IU-2017.2.5'
21-
plugins = ['com.jetbrains.php:172.4155.41']
21+
plugins = ['com.jetbrains.php:172.4155.41', 'CSS', 'java-i18n', 'properties']
2222
pluginName 'TYPO3 CMS Plugin'
2323

2424
publishPlugin {

src/main/java/com/cedricziel/idea/typo3/annotation/PathResourceAnnotator.java

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
package com.cedricziel.idea.typo3.annotation;
22

3+
import com.cedricziel.idea.typo3.index.ResourcePathIndex;
34
import com.intellij.lang.annotation.AnnotationHolder;
45
import com.intellij.lang.annotation.Annotator;
5-
import com.intellij.openapi.vfs.VirtualFile;
66
import com.intellij.psi.PsiElement;
7-
import com.intellij.psi.PsiFile;
8-
import com.intellij.psi.search.FilenameIndex;
9-
import com.intellij.psi.search.GlobalSearchScope;
107
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
11-
import org.codehaus.plexus.util.DirectoryScanner;
128
import org.jetbrains.annotations.NotNull;
139

14-
import java.util.Arrays;
15-
import java.util.List;
16-
1710
/**
1811
* Matches {@link StringLiteralExpression} elements and annotates them if a resource does not exist.
1912
* <p>
@@ -38,42 +31,15 @@ public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder hold
3831
return;
3932
}
4033

41-
String[] split = resourceName.split("/");
42-
String fileName = split[split.length - 1];
43-
DirectoryScanner scanner = new DirectoryScanner();
44-
45-
scanner.setBasedir(element.getProject().getBasePath());
46-
scanner.addDefaultExcludes();
47-
scanner.setIncludes(new String[]{"**/" + resourceName + "/"});
48-
scanner.scan();
49-
50-
String[] paths = scanner.getIncludedFiles();
51-
if (paths.length != 0) {
52-
// the resource is a directory
34+
if (ResourcePathIndex.projectContainsResourceFile(element.getProject(), content)) {
35+
// exact match found
5336
return;
5437
}
5538

56-
List<PsiFile> filesByName = Arrays.asList(FilenameIndex.getFilesByName(element.getProject(), fileName, GlobalSearchScope.allScope(element.getProject())));
57-
if (filesByName.size() == 0) {
58-
createErrorMessage(element, holder, resourceName);
59-
39+
if (ResourcePathIndex.projectContainsResourceDirectory(element.getProject(), content)) {
6040
return;
6141
}
6242

63-
for (PsiFile file : filesByName) {
64-
VirtualFile virtualFile = file.getVirtualFile();
65-
66-
67-
if (virtualFile.getPath().contains("typo3conf/ext/" + resourceName) || virtualFile.getPath().contains("sysext/" + resourceName)) {
68-
// all good
69-
return;
70-
}
71-
72-
if (virtualFile.isDirectory() && virtualFile.getPath().endsWith(resourceName)) {
73-
return;
74-
}
75-
}
76-
7743
createErrorMessage(element, holder, resourceName);
7844
}
7945

src/main/java/com/cedricziel/idea/typo3/codeInsight/PathResourceCompletionContributor.java

Lines changed: 4 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
package com.cedricziel.idea.typo3.codeInsight;
22

3+
import com.cedricziel.idea.typo3.index.ResourcePathIndex;
34
import com.intellij.codeInsight.completion.*;
4-
import com.intellij.codeInsight.lookup.LookupElement;
5-
import com.intellij.codeInsight.lookup.LookupElementPresentation;
6-
import com.intellij.icons.AllIcons;
5+
import com.intellij.codeInsight.lookup.LookupElementBuilder;
76
import com.intellij.openapi.project.Project;
87
import com.intellij.patterns.PlatformPatterns;
98
import com.intellij.psi.PsiElement;
109
import com.intellij.util.ProcessingContext;
1110
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
12-
import org.codehaus.plexus.util.DirectoryScanner;
1311
import org.jetbrains.annotations.NotNull;
1412

15-
import java.util.Arrays;
16-
1713
public class PathResourceCompletionContributor extends CompletionContributor {
1814
public PathResourceCompletionContributor() {
1915
extend(
@@ -31,79 +27,8 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
3127
return;
3228
}
3329

34-
String[] includes;
35-
if (currentText.contains("/")) {
36-
String current = currentText
37-
.split("/", 1)[0]
38-
.replace("EXT:", "")
39-
.replace("IntellijIdeaRulezzz", "")
40-
.replace("'", "")
41-
.trim();
42-
43-
includes = new String[]{
44-
"**/sysext/" + current + "**",
45-
"**/typo3conf/ext/" + current + "**",
46-
};
47-
} else {
48-
includes = new String[]{
49-
"**/sysext/*/",
50-
"**/typo3conf/ext/*/",
51-
};
52-
}
53-
54-
DirectoryScanner scanner = new DirectoryScanner();
55-
56-
scanner.setBasedir(project.getBasePath());
57-
scanner.addDefaultExcludes();
58-
scanner.setIncludes(includes);
59-
scanner.scan();
60-
61-
Arrays.stream(scanner.getIncludedFiles()).forEach(f -> {
62-
result.addElement(new LookupElement() {
63-
@NotNull
64-
@Override
65-
public String getLookupString() {
66-
String[] splitted = f.split("sysext/");
67-
if (splitted.length > 1) {
68-
return "EXT:" + splitted[1];
69-
}
70-
71-
splitted = f.split("typo3conf/ext/");
72-
if (splitted.length > 1) {
73-
return "EXT:" + splitted[1];
74-
}
75-
76-
return "EXT:" + f;
77-
}
78-
});
79-
});
80-
81-
Arrays.stream(scanner.getIncludedDirectories()).forEach(f -> {
82-
result.addElement(new LookupElement() {
83-
84-
@Override
85-
public void renderElement(LookupElementPresentation presentation) {
86-
presentation.setIcon(AllIcons.Modules.SourceFolder);
87-
88-
super.renderElement(presentation);
89-
}
90-
91-
@NotNull
92-
@Override
93-
public String getLookupString() {
94-
String[] splitted = f.split("sysext/");
95-
if (splitted.length > 1) {
96-
return "EXT:" + splitted[1];
97-
}
98-
99-
splitted = f.split("typo3conf/ext/");
100-
if (splitted.length > 1) {
101-
return "EXT:" + splitted[1];
102-
}
103-
104-
return "EXT:" + f;
105-
}
106-
});
30+
ResourcePathIndex.getAvailableExtensionResourceFiles(project).forEach(identifier -> {
31+
result.addElement(LookupElementBuilder.create(identifier));
10732
});
10833
}
10934
}

src/main/java/com/cedricziel/idea/typo3/codeInsight/navigation/PathResourceGotoDeclarationHandler.java

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
package com.cedricziel.idea.typo3.codeInsight.navigation;
22

3+
import com.cedricziel.idea.typo3.index.ResourcePathIndex;
34
import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler;
45
import com.intellij.openapi.actionSystem.DataContext;
56
import com.intellij.openapi.editor.Editor;
67
import com.intellij.psi.PsiElement;
7-
import com.intellij.psi.PsiFile;
8-
import com.intellij.psi.search.FilenameIndex;
9-
import com.intellij.psi.search.GlobalSearchScope;
108
import org.jetbrains.annotations.NotNull;
119
import org.jetbrains.annotations.Nullable;
1210

13-
import java.util.Arrays;
14-
import java.util.List;
15-
1611
import static com.cedricziel.idea.typo3.util.ResourceUtil.isExtResourcePath;
1712

1813
public class PathResourceGotoDeclarationHandler implements GotoDeclarationHandler {
@@ -24,26 +19,8 @@ public PsiElement[] getGotoDeclarationTargets(@Nullable PsiElement sourceElement
2419
}
2520

2621
if (sourceElement != null) {
27-
String text = sourceElement.getText();
28-
String[] strings = text.split("/");
29-
if (strings.length == 0) {
30-
return emptyPsiElementArray();
31-
}
32-
33-
String fileName = strings[strings.length - 1];
34-
String relativePath = text.replaceFirst("EXT:", "");
35-
36-
List<PsiFile> psiFiles = Arrays.asList(
37-
FilenameIndex.getFilesByName(
38-
sourceElement.getProject(),
39-
fileName,
40-
GlobalSearchScope.allScope(sourceElement.getProject())
41-
));
42-
43-
return psiFiles
44-
.stream()
45-
.filter(x -> x.getVirtualFile().getPath().contains(relativePath))
46-
.toArray(PsiElement[]::new);
22+
String identifier = sourceElement.getText();
23+
return ResourcePathIndex.findElementsForKey(sourceElement.getProject(), identifier);
4724
}
4825

4926
return emptyPsiElementArray();
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package com.cedricziel.idea.typo3.index;
2+
3+
import com.intellij.openapi.project.Project;
4+
import com.intellij.psi.PsiElement;
5+
import com.intellij.psi.PsiManager;
6+
import com.intellij.psi.search.GlobalSearchScope;
7+
import com.intellij.util.indexing.*;
8+
import com.intellij.util.io.EnumeratorStringDescriptor;
9+
import com.intellij.util.io.KeyDescriptor;
10+
import gnu.trove.THashMap;
11+
import org.jetbrains.annotations.NotNull;
12+
13+
import java.util.*;
14+
15+
public class ResourcePathIndex extends ScalarIndexExtension<String> {
16+
17+
public static final ID<String, Void> KEY = ID.create("com.cedricziel.idea.typo3.index.resource_path");
18+
19+
public static Collection<String> getAvailableExtensionResourceFiles(@NotNull Project project) {
20+
return FileBasedIndex.getInstance().getAllKeys(ResourcePathIndex.KEY, project);
21+
}
22+
23+
public static boolean projectContainsResourceFile(@NotNull Project project, @NotNull String resourceId) {
24+
return FileBasedIndex.getInstance().getAllKeys(ResourcePathIndex.KEY, project).contains(resourceId);
25+
}
26+
27+
public static boolean projectContainsResourceDirectory(@NotNull Project project, @NotNull String resourceId) {
28+
return false;
29+
}
30+
31+
public static PsiElement[] findElementsForKey(@NotNull Project project, @NotNull String identifier) {
32+
Set<String> keys = new HashSet<>();
33+
keys.add(identifier);
34+
Set<PsiElement> elements = new HashSet<>();
35+
36+
FileBasedIndex.getInstance().getFilesWithKey(ResourcePathIndex.KEY, keys, virtualFile -> {
37+
elements.add(PsiManager.getInstance(project).findFile(virtualFile));
38+
39+
return true;
40+
}, GlobalSearchScope.allScope(project));
41+
42+
return elements
43+
.stream()
44+
.filter(Objects::nonNull)
45+
.toArray(PsiElement[]::new);
46+
}
47+
48+
@NotNull
49+
@Override
50+
public ID<String, Void> getName() {
51+
return KEY;
52+
}
53+
54+
@NotNull
55+
@Override
56+
public DataIndexer<String, Void, FileContent> getIndexer() {
57+
return inputData -> {
58+
Map<String, Void> map = new THashMap<>();
59+
60+
map.put(compileId(inputData), null);
61+
62+
return map;
63+
};
64+
}
65+
66+
private String compileId(FileContent inputData) {
67+
String path = inputData.getFile().getPath();
68+
String filePosition = "";
69+
if (path.contains("typo3conf/ext/")) {
70+
filePosition = path.split("typo3conf/ext/")[1];
71+
}
72+
if (path.contains("sysext/")) {
73+
filePosition = path.split("sysext/")[1];
74+
}
75+
76+
return "EXT:" + filePosition;
77+
}
78+
79+
@NotNull
80+
@Override
81+
public KeyDescriptor<String> getKeyDescriptor() {
82+
return EnumeratorStringDescriptor.INSTANCE;
83+
}
84+
85+
@Override
86+
public int getVersion() {
87+
return 0;
88+
}
89+
90+
@NotNull
91+
@Override
92+
public FileBasedIndex.InputFilter getInputFilter() {
93+
return file -> file.isInLocalFileSystem() && (file.getPath().contains("sysext") || file.getPath().contains("typo3conf/ext"));
94+
}
95+
96+
@Override
97+
public boolean dependsOnFileContent() {
98+
return false;
99+
}
100+
}

src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ It is a great inspiration for possible solutions and parts of the code.</p>
268268
<fileBasedIndex implementation="com.cedricziel.idea.typo3.index.CoreServiceMapStubIndex"/>
269269
<fileBasedIndex implementation="com.cedricziel.idea.typo3.index.ExtensionNameStubIndex"/>
270270
<fileBasedIndex implementation="com.cedricziel.idea.typo3.index.IconIndex"/>
271+
<fileBasedIndex implementation="com.cedricziel.idea.typo3.index.ResourcePathIndex"/>
271272
<fileBasedIndex implementation="com.cedricziel.idea.typo3.index.TablenameFileIndex"/>
272273

273274
<!-- completion -->
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.cedricziel.idea.typo3.codeInsight;
2+
3+
import com.cedricziel.idea.typo3.index.ResourcePathIndex;
4+
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
5+
6+
public class PathResourceCompletionContributorTest extends LightCodeInsightFixtureTestCase {
7+
public void testResourcesAreIndexed() {
8+
myFixture.addFileToProject("typo3conf/ext/foo/bar.php", "");
9+
myFixture.addFileToProject("typo3/sysext/baz/bar.png", "");
10+
11+
assertTrue(ResourcePathIndex.projectContainsResourceFile(myFixture.getProject(), "EXT:foo/bar.php"));
12+
assertTrue(ResourcePathIndex.projectContainsResourceFile(myFixture.getProject(), "EXT:baz/bar.png"));
13+
}
14+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.cedricziel.idea.typo3.index;
2+
3+
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
4+
import com.jetbrains.php.lang.PhpFileType;
5+
6+
import java.util.List;
7+
8+
public class ResourcePathIndexTest extends LightCodeInsightFixtureTestCase {
9+
public void testResourcesAreIndexed() {
10+
myFixture.addFileToProject("typo3conf/ext/foo/bar.php", "");
11+
myFixture.addFileToProject("typo3/sysext/baz/bar.png", "");
12+
myFixture.configureByText(PhpFileType.INSTANCE, "<?php \n" +
13+
"echo 'EXT:<caret>';");
14+
myFixture.completeBasic();
15+
16+
List<String> lookupElementStrings = myFixture.getLookupElementStrings();
17+
18+
if (lookupElementStrings == null) {
19+
fail("Could not complete");
20+
}
21+
22+
assertContainsElements(lookupElementStrings, "EXT:foo/bar.php");
23+
assertContainsElements(lookupElementStrings, "EXT:baz/bar.png");
24+
}
25+
}

tests/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)