Skip to content

Commit 35f0cfe

Browse files
authored
Merge pull request #2095 from Haehnchen/feature/tag-extends-inspection-recursive
replace recursive visiting for service tag "extends" inspection
2 parents 816cae3 + 8fb2e74 commit 35f0cfe

File tree

1 file changed

+68
-82
lines changed

1 file changed

+68
-82
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/codeInspection/service/TaggedExtendsInterfaceClassInspection.java

Lines changed: 68 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import com.intellij.codeInspection.LocalInspectionTool;
44
import com.intellij.codeInspection.ProblemHighlightType;
55
import com.intellij.codeInspection.ProblemsHolder;
6+
import com.intellij.lang.Language;
7+
import com.intellij.lang.xml.XMLLanguage;
8+
import com.intellij.openapi.util.NotNullLazyValue;
69
import com.intellij.psi.PsiElement;
710
import com.intellij.psi.PsiElementVisitor;
8-
import com.intellij.psi.PsiFile;
9-
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
1011
import com.intellij.psi.util.PsiTreeUtil;
11-
import com.intellij.psi.xml.XmlFile;
1212
import com.intellij.psi.xml.XmlTag;
1313
import com.jetbrains.php.lang.psi.elements.PhpClass;
1414
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
@@ -23,9 +23,9 @@
2323
import org.apache.commons.lang.StringUtils;
2424
import org.jetbrains.annotations.NotNull;
2525
import org.jetbrains.annotations.Nullable;
26+
import org.jetbrains.yaml.YAMLLanguage;
2627
import org.jetbrains.yaml.YAMLTokenTypes;
2728
import org.jetbrains.yaml.psi.YAMLCompoundValue;
28-
import org.jetbrains.yaml.psi.YAMLFile;
2929
import org.jetbrains.yaml.psi.YAMLKeyValue;
3030
import org.jetbrains.yaml.psi.YAMLScalar;
3131

@@ -39,107 +39,93 @@ public class TaggedExtendsInterfaceClassInspection extends LocalInspectionTool {
3939
@NotNull
4040
@Override
4141
public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, boolean isOnTheFly) {
42-
if(!Symfony2ProjectComponent.isEnabled(holder.getProject())) {
42+
if (!Symfony2ProjectComponent.isEnabled(holder.getProject())) {
4343
return super.buildVisitor(holder, isOnTheFly);
4444
}
4545

4646
return new PsiElementVisitor() {
47+
private NotNullLazyValue<ContainerCollectionResolver.LazyServiceCollector> serviceCollector;
48+
4749
@Override
48-
public void visitFile(@NotNull PsiFile psiFile) {
49-
if(psiFile instanceof YAMLFile) {
50-
psiFile.acceptChildren(new YmlClassElementWalkingVisitor(holder, new ContainerCollectionResolver.LazyServiceCollector(holder.getProject())));
51-
} else if(psiFile instanceof XmlFile) {
52-
psiFile.acceptChildren(new XmlClassElementWalkingVisitor(holder, new ContainerCollectionResolver.LazyServiceCollector(holder.getProject())));
50+
public void visitElement(@NotNull PsiElement element) {
51+
Language language = element.getLanguage();
52+
53+
if (language == YAMLLanguage.INSTANCE) {
54+
visitYamlElement(element, holder, this.createLazyServiceCollector());
55+
} else if (language == XMLLanguage.INSTANCE) {
56+
visitXmlElement(element, holder, this.createLazyServiceCollector());
5357
}
58+
59+
super.visitElement(element);
5460
}
55-
};
56-
}
5761

58-
private class XmlClassElementWalkingVisitor extends PsiRecursiveElementWalkingVisitor {
59-
private final ProblemsHolder holder;
60-
private final ContainerCollectionResolver.LazyServiceCollector lazyServiceCollector;
62+
private NotNullLazyValue<ContainerCollectionResolver.LazyServiceCollector> createLazyServiceCollector() {
63+
if (this.serviceCollector == null) {
64+
this.serviceCollector = NotNullLazyValue.lazy(() -> new ContainerCollectionResolver.LazyServiceCollector(holder.getProject()));
65+
}
6166

62-
public XmlClassElementWalkingVisitor(ProblemsHolder holder, ContainerCollectionResolver.LazyServiceCollector lazyServiceCollector) {
63-
this.holder = holder;
64-
this.lazyServiceCollector = lazyServiceCollector;
65-
}
67+
return this.serviceCollector;
68+
}
69+
};
70+
}
6671

67-
@Override
68-
public void visitElement(@NotNull PsiElement element) {
69-
String className = getClassNameFromServiceDefinition(element);
70-
if (className != null) {
71-
XmlTag parentOfType = PsiTreeUtil.getParentOfType(element, XmlTag.class);
72-
if(parentOfType != null) {
73-
// attach problems to string value only
74-
PsiElement[] psiElements = element.getChildren();
75-
if (psiElements.length > 2) {
76-
registerTaggedProblems(psiElements[1], FormUtil.getTags(parentOfType), className, holder, this.lazyServiceCollector);
77-
}
72+
private void visitXmlElement(@NotNull PsiElement element, @NotNull ProblemsHolder holder, @NotNull NotNullLazyValue<ContainerCollectionResolver.LazyServiceCollector> lazyServiceCollector) {
73+
String className = getClassNameFromServiceDefinition(element);
74+
if (className != null) {
75+
XmlTag parentOfType = PsiTreeUtil.getParentOfType(element, XmlTag.class);
76+
if (parentOfType != null) {
77+
// attach problems to string value only
78+
PsiElement[] psiElements = element.getChildren();
79+
if (psiElements.length > 2) {
80+
registerTaggedProblems(psiElements[1], FormUtil.getTags(parentOfType), className, holder, lazyServiceCollector);
7881
}
7982
}
80-
81-
super.visitElement(element);
8283
}
8384
}
8485

85-
private class YmlClassElementWalkingVisitor extends PsiRecursiveElementWalkingVisitor {
86-
private final ProblemsHolder holder;
87-
private final ContainerCollectionResolver.LazyServiceCollector lazyServiceCollector;
86+
private void visitYamlElement(@NotNull PsiElement psiElement, @NotNull ProblemsHolder holder, @NotNull NotNullLazyValue<ContainerCollectionResolver.LazyServiceCollector> lazyServiceCollector) {
87+
if (YamlElementPatternHelper.getSingleLineScalarKey("class").accepts(psiElement)) {
8888

89-
public YmlClassElementWalkingVisitor(ProblemsHolder holder, ContainerCollectionResolver.LazyServiceCollector lazyServiceCollector) {
90-
this.holder = holder;
91-
this.lazyServiceCollector = lazyServiceCollector;
92-
}
93-
94-
@Override
95-
public void visitElement(@NotNull PsiElement psiElement) {
96-
if(YamlElementPatternHelper.getSingleLineScalarKey("class").accepts(psiElement)) {
97-
98-
// class: '\Foo'
99-
String text = PsiElementUtils.trimQuote(psiElement.getText());
100-
if(StringUtils.isBlank(text)) {
101-
super.visitElement(psiElement);
102-
return;
103-
}
89+
// class: '\Foo'
90+
String text = PsiElementUtils.trimQuote(psiElement.getText());
91+
if (StringUtils.isBlank(text)) {
92+
return;
93+
}
10494

105-
PsiElement yamlScalar = psiElement.getParent();
106-
if(!(yamlScalar instanceof YAMLScalar)) {
107-
super.visitElement(psiElement);
108-
return;
109-
}
95+
PsiElement yamlScalar = psiElement.getParent();
96+
if (!(yamlScalar instanceof YAMLScalar)) {
97+
return;
98+
}
11099

111-
PsiElement classKey = yamlScalar.getParent();
112-
if(classKey instanceof YAMLKeyValue) {
113-
PsiElement yamlCompoundValue = classKey.getParent();
114-
if(yamlCompoundValue instanceof YAMLCompoundValue) {
115-
PsiElement serviceKeyValue = yamlCompoundValue.getParent();
116-
if(serviceKeyValue instanceof YAMLKeyValue) {
117-
Set<String> tags = YamlHelper.collectServiceTags((YAMLKeyValue) serviceKeyValue);
118-
if(tags.size() > 0) {
119-
registerTaggedProblems(psiElement, tags, text, holder, this.lazyServiceCollector);
120-
}
100+
PsiElement classKey = yamlScalar.getParent();
101+
if (classKey instanceof YAMLKeyValue) {
102+
PsiElement yamlCompoundValue = classKey.getParent();
103+
if (yamlCompoundValue instanceof YAMLCompoundValue) {
104+
PsiElement serviceKeyValue = yamlCompoundValue.getParent();
105+
if (serviceKeyValue instanceof YAMLKeyValue) {
106+
Set<String> tags = YamlHelper.collectServiceTags((YAMLKeyValue) serviceKeyValue);
107+
if (tags.size() > 0) {
108+
registerTaggedProblems(psiElement, tags, text, holder, lazyServiceCollector);
121109
}
122110
}
123111
}
124-
} else if (psiElement.getNode().getElementType() == YAMLTokenTypes.SCALAR_KEY && YamlElementPatternHelper.getServiceIdKeyValuePattern().accepts(psiElement.getParent())) {
125-
// Foobar\Foo: ~
126-
String text = PsiElementUtils.getText(psiElement);
127-
if (StringUtils.isNotBlank(text) && YamlHelper.isClassServiceId(text) && text.contains("\\")) {
128-
PsiElement yamlKeyValue = psiElement.getParent();
129-
if (yamlKeyValue instanceof YAMLKeyValue && YamlHelper.getYamlKeyValue((YAMLKeyValue) yamlKeyValue, "resource") == null && YamlHelper.getYamlKeyValue((YAMLKeyValue) yamlKeyValue, "exclude") == null) {
130-
Set<String> tags = YamlHelper.collectServiceTags((YAMLKeyValue) yamlKeyValue);
131-
if(tags.size() > 0) {
132-
registerTaggedProblems(psiElement, tags, text, holder, this.lazyServiceCollector);
133-
}
112+
}
113+
} else if (psiElement.getNode().getElementType() == YAMLTokenTypes.SCALAR_KEY && YamlElementPatternHelper.getServiceIdKeyValuePattern().accepts(psiElement.getParent())) {
114+
// Foobar\Foo: ~
115+
String text = PsiElementUtils.getText(psiElement);
116+
if (StringUtils.isNotBlank(text) && YamlHelper.isClassServiceId(text) && text.contains("\\")) {
117+
PsiElement yamlKeyValue = psiElement.getParent();
118+
if (yamlKeyValue instanceof YAMLKeyValue && YamlHelper.getYamlKeyValue((YAMLKeyValue) yamlKeyValue, "resource") == null && YamlHelper.getYamlKeyValue((YAMLKeyValue) yamlKeyValue, "exclude") == null) {
119+
Set<String> tags = YamlHelper.collectServiceTags((YAMLKeyValue) yamlKeyValue);
120+
if (tags.size() > 0) {
121+
registerTaggedProblems(psiElement, tags, text, holder, lazyServiceCollector);
134122
}
135123
}
136124
}
137-
138-
super.visitElement(psiElement);
139125
}
140126
}
141127

142-
private void registerTaggedProblems(@NotNull PsiElement source, @NotNull Set<String> tags, @NotNull String serviceClass, @NotNull ProblemsHolder holder, @NotNull ContainerCollectionResolver.LazyServiceCollector lazyServiceCollector) {
128+
private void registerTaggedProblems(@NotNull PsiElement source, @NotNull Set<String> tags, @NotNull String serviceClass, @NotNull ProblemsHolder holder, @NotNull NotNullLazyValue<ContainerCollectionResolver.LazyServiceCollector> lazyServiceCollector) {
143129
if (tags.size() == 0) {
144130
return;
145131
}
@@ -151,9 +137,9 @@ private void registerTaggedProblems(@NotNull PsiElement source, @NotNull Set<Str
151137

152138
for (String expectedClass : ServiceUtil.TAG_INTERFACES.getOrDefault(tag, new String[] {})) {
153139
// load PhpClass only if we need it, on error exit
154-
if(phpClass == null) {
155-
phpClass = ServiceUtil.getResolvedClassDefinition(holder.getProject(), serviceClass, lazyServiceCollector);
156-
if(phpClass == null) {
140+
if (phpClass == null) {
141+
phpClass = ServiceUtil.getResolvedClassDefinition(holder.getProject(), serviceClass, lazyServiceCollector.get());
142+
if (phpClass == null) {
157143
return;
158144
}
159145
}
@@ -164,7 +150,7 @@ private void registerTaggedProblems(@NotNull PsiElement source, @NotNull Set<Str
164150
}
165151

166152
// check interfaces
167-
if(!PhpElementsUtil.isInstanceOf(phpClass, expectedClass)) {
153+
if (!PhpElementsUtil.isInstanceOf(phpClass, expectedClass)) {
168154
missingTagInstance = expectedClass;
169155
continue;
170156
}

0 commit comments

Comments
 (0)