Skip to content

Commit 126c2cf

Browse files
authored
Merge pull request #1672 from Haehnchen/feature/fixes
smarter public asset folder, fix twig form linemarker psi pattern, remove symfony check from notication window
2 parents a8623ee + 325f7ad commit 126c2cf

File tree

9 files changed

+115
-63
lines changed

9 files changed

+115
-63
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/asset/AssetDirectoryReader.java

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@
1111
import fr.adrienbrault.idea.symfony2plugin.util.dict.SymfonyBundle;
1212
import org.apache.commons.lang.StringUtils;
1313
import org.jetbrains.annotations.NotNull;
14-
import org.jetbrains.annotations.Nullable;
1514

16-
import java.util.ArrayList;
17-
import java.util.Arrays;
18-
import java.util.Collection;
19-
import java.util.HashSet;
15+
import java.util.*;
2016
import java.util.regex.Matcher;
2117
import java.util.regex.Pattern;
18+
import java.util.stream.Collectors;
2219

2320
/**
2421
* @author Daniel Espendiller <daniel@espendiller.net>
@@ -41,30 +38,40 @@ public AssetDirectoryReader(@NotNull String[] filterExtension, boolean includeBu
4138
this.filterExtension.addAll(Arrays.asList(filterExtension));
4239
}
4340

44-
@Nullable
45-
private static VirtualFile getProjectAssetRoot(@NotNull Project project) {
46-
String webDirectoryName = Settings.getInstance(project).directoryToWeb;
47-
return VfsUtil.findRelativeFile(ProjectUtil.getProjectDir(project), webDirectoryName.split("/"));
41+
@NotNull
42+
private static Collection<VirtualFile> getProjectAssetRoot(@NotNull Project project) {
43+
Set<String> paths = new HashSet<>();
44+
45+
// custom config
46+
String directoryToWeb = Settings.getInstance(project).directoryToWeb;
47+
if (StringUtils.isNotBlank(directoryToWeb)) {
48+
paths.add(directoryToWeb);
49+
}
50+
51+
paths.add("public"); // latest Symfony structure
52+
paths.add("web"); // old Symfony structure
53+
54+
return paths.stream()
55+
.map(path -> VfsUtil.findRelativeFile(ProjectUtil.getProjectDir(project), path.split("/")))
56+
.filter(Objects::nonNull)
57+
.collect(Collectors.toSet());
4858
}
4959

5060
@NotNull
5161
public Collection<AssetFile> getAssetFiles(@NotNull Project project) {
5262
Collection<AssetFile> files = new ArrayList<>();
5363

54-
VirtualFile webDirectory = getProjectAssetRoot(project);
55-
if (null == webDirectory) {
56-
return files;
57-
}
58-
59-
VfsUtil.visitChildrenRecursively(webDirectory, new VirtualFileVisitor() {
60-
@Override
61-
public boolean visitFile(@NotNull VirtualFile virtualFile) {
62-
if(isValidFile(virtualFile)) {
63-
files.add(new AssetFile(virtualFile, AssetEnum.Position.Web, webDirectory));
64+
for (VirtualFile webDirectory : getProjectAssetRoot(project)) {
65+
VfsUtil.visitChildrenRecursively(webDirectory, new VirtualFileVisitor<VirtualFile>() {
66+
@Override
67+
public boolean visitFile(@NotNull VirtualFile virtualFile) {
68+
if(isValidFile(virtualFile)) {
69+
files.add(new AssetFile(virtualFile, AssetEnum.Position.Web, webDirectory));
70+
}
71+
return super.visitFile(virtualFile);
6472
}
65-
return super.visitFile(virtualFile);
66-
}
67-
});
73+
});
74+
}
6875

6976
if(!this.includeBundleDir) {
7077
return files;
@@ -81,7 +88,7 @@ public boolean visitFile(@NotNull VirtualFile virtualFile) {
8188
VirtualFile resourceDirectory = VfsUtil.findRelativeFile(bundleDirectoryVirtual, "Resources");
8289

8390
if (null != resourceDirectory) {
84-
VfsUtil.visitChildrenRecursively(resourceDirectory, new VirtualFileVisitor() {
91+
VfsUtil.visitChildrenRecursively(resourceDirectory, new VirtualFileVisitor<VirtualFile>() {
8592
@Override
8693
public boolean visitFile(@NotNull VirtualFile virtualFile) {
8794
if(isValidFile(virtualFile)) {
@@ -139,21 +146,18 @@ public Collection<VirtualFile> resolveAssetFile(@NotNull Project project, @NotNu
139146

140147
Collection<VirtualFile> files = new ArrayList<>();
141148

142-
VirtualFile webDirectory = getProjectAssetRoot(project);
143-
if (null == webDirectory) {
144-
return files;
145-
}
146-
147-
Matcher matcher = Pattern.compile("^(.*[/\\\\])\\*([.\\w+]*)$").matcher(assetName);
148-
if (!matcher.find()) {
149-
VirtualFile assetFile = VfsUtil.findRelativeFile(webDirectory, assetName.split("/"));
150-
if(assetFile != null) {
151-
files.add(assetFile);
149+
for (VirtualFile webDirectory : getProjectAssetRoot(project)) {
150+
Matcher matcher = Pattern.compile("^(.*[/\\\\])\\*([.\\w+]*)$").matcher(assetName);
151+
if (!matcher.find()) {
152+
VirtualFile assetFile = VfsUtil.findRelativeFile(webDirectory, assetName.split("/"));
153+
if(assetFile != null) {
154+
files.add(assetFile);
155+
}
156+
} else {
157+
// "/*"
158+
// "/*.js"
159+
files.addAll(collectWildcardDirectories(matcher, webDirectory));
152160
}
153-
} else {
154-
// "/*"
155-
// "/*.js"
156-
files.addAll(collectWildcardDirectories(matcher, webDirectory));
157161
}
158162

159163
return files;

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigLineMarkerProvider.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.intellij.psi.PsiManager;
1818
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
1919
import com.intellij.psi.search.GlobalSearchScope;
20+
import com.intellij.psi.util.PsiTreeUtil;
2021
import com.intellij.util.ConstantFunction;
2122
import com.intellij.util.indexing.FileBasedIndex;
2223
import com.jetbrains.php.PhpIcons;
@@ -26,6 +27,9 @@
2627
import com.jetbrains.twig.TwigFileType;
2728
import com.jetbrains.twig.TwigTokenTypes;
2829
import com.jetbrains.twig.elements.TwigElementTypes;
30+
import com.jetbrains.twig.elements.TwigFieldReference;
31+
import com.jetbrains.twig.elements.TwigPsiReference;
32+
import com.jetbrains.twig.elements.TwigVariableReference;
2933
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
3034
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
3135
import fr.adrienbrault.idea.symfony2plugin.dic.RelatedPopupGotoLineMarker;
@@ -105,7 +109,7 @@ public void collectSlowLineMarkers(@NotNull List<? extends PsiElement> psiElemen
105109
if(lineOverwrites != null) {
106110
results.add(lineOverwrites);
107111
}
108-
} else if(TwigPattern.getFunctionPattern("form_start", "form").accepts(psiElement)) {
112+
} else if(TwigPattern.getFunctionPattern("form_start", "form", "form_end", "form_rest").accepts(psiElement)) {
109113
LineMarkerInfo<?> lineOverwrites = attachFormType(psiElement);
110114
if(lineOverwrites != null) {
111115
results.add(lineOverwrites);
@@ -307,17 +311,13 @@ private LineMarkerInfo<?> attachBlockOverwrites(@NotNull PsiElement psiElement,
307311

308312
@Nullable
309313
private LineMarkerInfo<?> attachFormType(@NotNull PsiElement psiElement) {
310-
PsiElement firstChild = psiElement.getFirstChild();
311-
if (firstChild == null) {
314+
// form(theform);
315+
PsiElement twigFunctionParameterIdentifierPsi = TwigUtil.getTwigFunctionParameterIdentifierPsi(psiElement);
316+
if (twigFunctionParameterIdentifierPsi == null) {
312317
return null;
313318
}
314319

315-
PsiElement nextSiblingOfType = PsiElementUtils.getNextSiblingOfType(firstChild, PlatformPatterns.psiElement().withElementType(TwigTokenTypes.IDENTIFIER).afterLeaf(PlatformPatterns.psiElement(TwigTokenTypes.LBRACE)));
316-
if (nextSiblingOfType == null) {
317-
return null;
318-
}
319-
320-
Collection<TwigTypeContainer> twigTypeContainers = TwigTypeResolveUtil.resolveTwigMethodName(nextSiblingOfType, TwigTypeResolveUtil.formatPsiTypeNameWithCurrent(nextSiblingOfType));
320+
Collection<TwigTypeContainer> twigTypeContainers = TwigTypeResolveUtil.resolveTwigMethodName(twigFunctionParameterIdentifierPsi, TwigTypeResolveUtil.formatPsiTypeNameWithCurrent(twigFunctionParameterIdentifierPsi));
321321

322322
Collection<PhpClass> phpClasses = new HashSet<>();
323323

@@ -337,7 +337,7 @@ private LineMarkerInfo<?> attachFormType(@NotNull PsiElement psiElement) {
337337
.setTooltipText("Navigate to Form")
338338
.setCellRenderer(new MyBlockListCellRenderer());
339339

340-
return builder.createLineMarkerInfo(firstChild);
340+
return builder.createLineMarkerInfo(psiElement.getFirstChild());
341341
}
342342

343343
@Nullable

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigUtil.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,29 @@ public void visitElement(PsiElement element) {
310310
return null;
311311
}
312312

313+
/**
314+
* "form(form.name)" => "form"
315+
*/
316+
@Nullable
317+
public static PsiElement getTwigFunctionParameterIdentifierPsi(@NotNull PsiElement psiElement) {
318+
// "form(form.name)" => "form"
319+
TwigFieldReference childOfType = PsiTreeUtil.findChildOfType(psiElement, TwigFieldReference.class);
320+
if (childOfType != null) {
321+
TwigPsiReference owner = childOfType.getOwner();
322+
if (owner != null) {
323+
return owner.getFirstChild();
324+
}
325+
}
326+
327+
// "form(form)" => "form"
328+
TwigVariableReference childOfType1 = PsiTreeUtil.findChildOfType(psiElement, TwigVariableReference.class);
329+
if (childOfType1 != null) {
330+
return childOfType1.getFirstChild();
331+
}
332+
333+
return null;
334+
}
335+
313336
/**
314337
* Search Twig element to find use trans_default_domain and returns given string parameter
315338
*/

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/webpack/SymfonyWebpackUtil.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import com.intellij.openapi.project.Project;
44
import com.intellij.openapi.util.Pair;
55
import com.intellij.openapi.util.io.StreamUtil;
6+
import com.intellij.openapi.vfs.VfsUtil;
67
import com.intellij.openapi.vfs.VirtualFile;
78
import com.intellij.psi.search.FilenameIndex;
89
import com.intellij.psi.search.GlobalSearchScope;
10+
import fr.adrienbrault.idea.symfony2plugin.util.ProjectUtil;
911
import org.jetbrains.annotations.NotNull;
1012
import org.json.simple.JSONObject;
1113
import org.json.simple.parser.JSONParser;
@@ -27,11 +29,15 @@ public class SymfonyWebpackUtil {
2729
*/
2830
public static void visitAllEntryFileTypes(@NotNull Project project, @NotNull Consumer<Pair<VirtualFile, String>> consumer) {
2931
for (VirtualFile virtualFile : FilenameIndex.getVirtualFilesByName(project, "webpack.config.js", GlobalSearchScope.allScope(project))) {
30-
visitWebpackConfiguration(virtualFile, consumer);
32+
if (!isTestFile(project, virtualFile)) {
33+
visitWebpackConfiguration(virtualFile, consumer);
34+
}
3135
}
3236

3337
for (VirtualFile virtualFile : FilenameIndex.getVirtualFilesByName(project, "entrypoints.json", GlobalSearchScope.allScope(project))) {
34-
visitEntryPointJson(virtualFile, consumer);
38+
if (!isTestFile(project, virtualFile)) {
39+
visitEntryPointJson(virtualFile, consumer);
40+
}
3541
}
3642
}
3743

@@ -94,9 +100,20 @@ private static void visitWebpackConfiguration(@NotNull VirtualFile virtualFile,
94100
}
95101

96102
// if adding "javascript" plugin; would resolve better but not for now
97-
Matcher matcher = Pattern.compile("addEntry\\s*\\(\\s*['\"]([^'\"]+)['\"]").matcher(s);
103+
Matcher matcher = Pattern.compile("(addEntry|addStyleEntry)\\s*\\(\\s*['\"]([^'\"]+)['\"]").matcher(s);
98104
while(matcher.find()){
99-
consumer.accept(Pair.create(virtualFile, matcher.group(1)));
105+
consumer.accept(Pair.create(virtualFile, matcher.group(2)));
106+
}
107+
}
108+
109+
private static boolean isTestFile(@NotNull Project project, @NotNull VirtualFile virtualFile) {
110+
// ignore: "vendor/symonfy/.../tests/fixtures/build/entrypoints.json"
111+
String path = VfsUtil.getRelativePath(virtualFile, ProjectUtil.getProjectDir(project), '/');
112+
if (path != null) {
113+
String lowerCase = path.toLowerCase();
114+
return lowerCase.contains("/test/") || lowerCase.contains("/tests/");
100115
}
116+
117+
return false;
101118
}
102119
}

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/webpack/WebpackEncoreGotoCompletionRegistrar.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,6 @@ public Collection<PsiElement> getPsiTargets(PsiElement element) {
6565
public void getLookupElements(@NotNull GotoCompletionProviderLookupArguments arguments) {
6666
SymfonyWebpackUtil.visitAllEntryFileTypes(getProject(), pair ->
6767
{
68-
// ignore: "vendor/symonfy/.../tests/fixtures/build/entrypoints.json"
69-
String path = VfsUtil.getRelativePath(pair.first, ProjectUtil.getProjectDir(getElement()), '/');
70-
if (path != null) {
71-
String lowerCase = path.toLowerCase();
72-
73-
if (lowerCase.contains("/test/") || lowerCase.contains("/tests/")) {
74-
return;
75-
}
76-
}
77-
7868
LookupElementBuilder lookupElement = LookupElementBuilder.create(pair.getSecond())
7969
.withIcon(Symfony2Icons.SYMFONY)
8070
.withTypeText(pair.first.getName());

src/main/java/fr/adrienbrault/idea/symfony2plugin/util/IdeHelper.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import java.net.URISyntaxException;
2727
import java.util.*;
2828
import java.util.List;
29-
import java.util.function.Function;
3029
import java.util.stream.Collectors;
3130

3231
/**
@@ -161,10 +160,12 @@ public static Collection<String> enablePluginAndConfigure(@NotNull Project proje
161160

162161
Collection<String> messages = new ArrayList<>();
163162

163+
/* Remove version info; prevent index issues
164164
Set<String> versions = SymfonyUtil.getVersions(project);
165165
if (!versions.isEmpty()) {
166166
messages.add("Symfony Version: " + versions.iterator().next());
167167
}
168+
*/
168169

169170
// Symfony 3.0 structure
170171
if (VfsUtil.findRelativeFile(ProjectUtil.getProjectDir(project), "var", "cache") != null) {
@@ -180,10 +181,12 @@ public static Collection<String> enablePluginAndConfigure(@NotNull Project proje
180181

181182
// There no clean version when "FooBar:Foo:foo.html.twig" was dropped or deprecated
182183
// So we disable it in the 4 branch by default; following with a default switch to "false" soon
184+
/* Remove version info; prevent index issues
183185
if (SymfonyUtil.isVersionGreaterThenEquals(project, "4.0")) {
184186
Settings.getInstance(project).twigBundleNamespaceSupport = false;
185187
messages.add("Twig: Bundle names disabled");
186188
}
189+
*/
187190

188191
return messages;
189192
}

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigUtilTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,20 @@ public void testGetBlocksForFile() {
875875
assertDoesntContain(blocks, "foobar_2");
876876
}
877877

878+
public void testGetTwigFunctionParameterIdentifierPsi() {
879+
PsiElement psiElement = TwigElementFactory.createPsiElement(getProject(), "{{ form(form.name) }}", TwigElementTypes.FUNCTION_CALL);
880+
PsiElement twigFunctionParameter = TwigUtil.getTwigFunctionParameterIdentifierPsi(psiElement);
881+
882+
assertEquals("form", twigFunctionParameter.getText());
883+
assertEquals(TwigTokenTypes.IDENTIFIER, twigFunctionParameter.getNode().getElementType());
884+
885+
psiElement = TwigElementFactory.createPsiElement(getProject(), "{{ form_start(\n form, {attr: {'novalidate': 'novalidate'}}) }}", TwigElementTypes.FUNCTION_CALL);
886+
twigFunctionParameter = TwigUtil.getTwigFunctionParameterIdentifierPsi(psiElement);
887+
888+
assertEquals("form", twigFunctionParameter.getText());
889+
assertEquals(TwigTokenTypes.IDENTIFIER, twigFunctionParameter.getNode().getElementType());
890+
}
891+
878892
public void testGetBlockLookupElements() {
879893
PsiFile psiFile = myFixture.configureByText("foo.html.twig", "{% block name %}{% endblock %}");
880894
PsiFile psiFile2 = myFixture.configureByText("foo_2.html.twig", "{% block foobar %}{% endblock %}");

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/templating/webpack/SymfonyWebpackUtilTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ public void testVisitEntries() {
2525
Set<String> entries = new HashSet<>();
2626

2727
SymfonyWebpackUtil.visitAllEntryFileTypes(myFixture.getProject(), pair -> entries.add(pair.second));
28-
assertContainsElements(entries, "foo", "foobar", "entry_foobar_2");
28+
assertContainsElements(entries, "foo", "foobar", "entry_foobar_2", "addStyleEntryFoobar");
2929
}
3030
}

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/templating/webpack/fixtures/webpack.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Encore
2222
*/
2323
.addEntry('foobar', './assets/app.js')
2424
.addEntry("foo")
25+
.addStyleEntry('addStyleEntryFoobar')
2526

2627
.enableVueLoader(() => {}, { runtimeCompilerBuild: false })
2728

0 commit comments

Comments
 (0)