Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9426919

Browse files
Merge pull request #2109 from Haehnchen/feature/duplicate-key-visit
duplicate key inspections for xml should only visits the working context
2 parents 3eb172c + 213fe9f commit 9426919

File tree

4 files changed

+78
-54
lines changed

4 files changed

+78
-54
lines changed

‎src/main/java/fr/adrienbrault/idea/symfony2plugin/config/xml/inspection/XmlDuplicateParameterKeyInspection.java‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package fr.adrienbrault.idea.symfony2plugin.config.xml.inspection;
22

33
import com.intellij.codeInspection.ProblemsHolder;
4+
import com.intellij.psi.PsiElement;
45
import com.intellij.psi.PsiElementVisitor;
5-
import com.intellij.psi.PsiFile;
6+
import com.intellij.psi.xml.XmlAttributeValue;
67
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
78
import org.jetbrains.annotations.NotNull;
89

@@ -20,8 +21,12 @@ public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, bool
2021

2122
return new PsiElementVisitor() {
2223
@Override
23-
public void visitFile(PsiFile file) {
24-
visitRoot(file, holder, "parameters", "parameter", "key");
24+
public void visitElement(@NotNull PsiElement element) {
25+
if (element instanceof XmlAttributeValue xmlAttributeValue) {
26+
visitRoot(xmlAttributeValue, holder, "parameters", "parameter", "key");
27+
}
28+
29+
super.visitElement(element);
2530
}
2631
};
2732
}

‎src/main/java/fr/adrienbrault/idea/symfony2plugin/config/xml/inspection/XmlDuplicateServiceKeyInspection.java‎

Lines changed: 24 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,12 @@
55
import com.intellij.codeInspection.ProblemsHolder;
66
import com.intellij.psi.PsiElement;
77
import com.intellij.psi.PsiElementVisitor;
8-
import com.intellij.psi.PsiFile;
9-
import com.intellij.psi.util.PsiTreeUtil;
108
import com.intellij.psi.xml.XmlAttribute;
119
import com.intellij.psi.xml.XmlAttributeValue;
12-
import com.intellij.psi.xml.XmlDocument;
1310
import com.intellij.psi.xml.XmlTag;
1411
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
15-
import org.apache.commons.lang.StringUtils;
1612
import org.jetbrains.annotations.NotNull;
1713

18-
import java.util.HashMap;
19-
import java.util.HashSet;
20-
import java.util.Map;
21-
import java.util.Set;
22-
2314
/**
2415
* @author Daniel Espendiller <daniel@espendiller.net>
2516
*/
@@ -34,59 +25,41 @@ public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, bool
3425

3526
return new PsiElementVisitor() {
3627
@Override
37-
public void visitFile(PsiFile file) {
38-
visitRoot(file, holder, "services", "service", "id");
39-
super.visitFile(file);
28+
public void visitElement(@NotNull PsiElement element) {
29+
if (element instanceof XmlAttributeValue xmlAttributeValue) {
30+
visitRoot(xmlAttributeValue, holder, "services", "service", "id");
31+
}
32+
33+
super.visitElement(element);
4034
}
4135
};
4236
}
4337

44-
protected void visitRoot(PsiFile psiFile, @NotNull ProblemsHolder holder, String root, String child, String tagName) {
38+
protected void visitRoot(@NotNull XmlAttributeValue xmlAttributeValue, @NotNull ProblemsHolder holder, String root, String child, String tagName) {
39+
String value = null;
4540

46-
XmlDocument xmlDocument = PsiTreeUtil.getChildOfType(psiFile, XmlDocument.class);
47-
if(xmlDocument == null) {
48-
return;
49-
}
41+
if (xmlAttributeValue.getParent() instanceof XmlAttribute xmlAttribute && tagName.equals(xmlAttribute.getName())) {
42+
XmlTag xmlTag = xmlAttribute.getParent();
43+
if (xmlTag != null && child.equals(xmlTag.getName()) && xmlTag.getParent() instanceof XmlTag rootContextXmlTag && root.equals(rootContextXmlTag.getName())) {
44+
int found = 0;
45+
for (XmlTag parameters : rootContextXmlTag.findSubTags(child)) {
46+
String key = parameters.getAttributeValue(tagName);
5047

51-
Map<String, XmlAttribute> psiElementMap = new HashMap<>();
52-
Set<XmlAttribute> yamlKeyValues = new HashSet<>();
53-
54-
for(XmlTag xmlTag: PsiTreeUtil.getChildrenOfTypeAsList(psiFile.getFirstChild(), XmlTag.class)) {
55-
if(xmlTag.getName().equals("container")) {
56-
for(XmlTag servicesTag: xmlTag.getSubTags()) {
57-
if(servicesTag.getName().equals(root)) {
58-
for(XmlTag parameterTag: servicesTag.getSubTags()) {
59-
if(parameterTag.getName().equals(child)) {
60-
XmlAttribute keyAttr = parameterTag.getAttribute(tagName);
61-
if(keyAttr != null) {
62-
String parameterName = keyAttr.getValue();
63-
if(parameterName != null && StringUtils.isNotBlank(parameterName)) {
64-
if(psiElementMap.containsKey(parameterName)) {
65-
yamlKeyValues.add(psiElementMap.get(parameterName));
66-
yamlKeyValues.add(keyAttr);
67-
} else {
68-
psiElementMap.put(parameterName, keyAttr);
69-
}
70-
}
48+
// lazy value resolve
49+
if (value == null) {
50+
value = xmlAttributeValue.getValue();
51+
}
7152

72-
}
73-
}
74-
}
53+
if (value.equals(key)) {
54+
found++;
7555
}
76-
}
77-
}
78-
}
7956

80-
if(yamlKeyValues.size() > 0) {
81-
for(PsiElement psiElement: yamlKeyValues) {
82-
XmlAttributeValue valueElement = ((XmlAttribute) psiElement).getValueElement();
83-
if(valueElement != null) {
84-
holder.registerProblem(valueElement, "Duplicate Key", ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
57+
if (found == 2) {
58+
holder.registerProblem(xmlAttributeValue, "Symfony: Duplicate Key", ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
59+
break;
60+
}
8561
}
8662
}
8763
}
88-
8964
}
90-
91-
9265
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package fr.adrienbrault.idea.symfony2plugin.tests.config.xml;
2+
3+
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
4+
5+
/**
6+
* @author Daniel Espendiller <daniel@espendiller.net>
7+
* @see fr.adrienbrault.idea.symfony2plugin.config.xml.inspection.XmlDuplicateParameterKeyInspection
8+
*/
9+
public class XmlDuplicateParameterKeyInspectionTest extends SymfonyLightCodeInsightFixtureTestCase {
10+
public void testDuplicateParameterKey() {
11+
assertLocalInspectionContains("service.xml",
12+
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
13+
"<container>\n" +
14+
"\n" +
15+
" <parameters>\n" +
16+
" <parameter key=\"mailer.transport\">foo</parameter>\n" +
17+
" <parameter key=\"maile<caret>r.transport\">foo1</parameter>\n" +
18+
" </parameters>\n" +
19+
"\n" +
20+
"</container>",
21+
"Symfony: Duplicate Key"
22+
);
23+
}
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package fr.adrienbrault.idea.symfony2plugin.tests.config.xml.inspection;
2+
3+
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
4+
5+
/**
6+
* @author Daniel Espendiller <daniel@espendiller.net>
7+
* @see fr.adrienbrault.idea.symfony2plugin.config.xml.inspection.XmlDuplicateServiceKeyInspection
8+
*/
9+
public class XmlDuplicateServiceKeyInspectionTest extends SymfonyLightCodeInsightFixtureTestCase {
10+
public void testDuplicateParameterKey() {
11+
assertLocalInspectionContains("service.xml","" +
12+
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
13+
"<container>\n" +
14+
" <services>\n" +
15+
" <service id=\"foo<caret>bar\"/>\n" +
16+
" <service id=\"foobar\"/>\n" +
17+
" </services>\n" +
18+
"</container>",
19+
"Symfony: Duplicate Key"
20+
);
21+
}
22+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /