33import com .intellij .codeInspection .LocalInspectionTool ;
44import com .intellij .codeInspection .ProblemHighlightType ;
55import com .intellij .codeInspection .ProblemsHolder ;
6+ import com .intellij .lang .Language ;
7+ import com .intellij .lang .xml .XMLLanguage ;
8+ import com .intellij .openapi .util .NotNullLazyValue ;
69import com .intellij .psi .PsiElement ;
710import com .intellij .psi .PsiElementVisitor ;
8- import com .intellij .psi .PsiFile ;
9- import com .intellij .psi .PsiRecursiveElementWalkingVisitor ;
1011import com .intellij .psi .util .PsiTreeUtil ;
11- import com .intellij .psi .xml .XmlFile ;
1212import com .intellij .psi .xml .XmlTag ;
1313import com .jetbrains .php .lang .psi .elements .PhpClass ;
1414import fr .adrienbrault .idea .symfony2plugin .Symfony2ProjectComponent ;
2323import org .apache .commons .lang .StringUtils ;
2424import org .jetbrains .annotations .NotNull ;
2525import org .jetbrains .annotations .Nullable ;
26+ import org .jetbrains .yaml .YAMLLanguage ;
2627import org .jetbrains .yaml .YAMLTokenTypes ;
2728import org .jetbrains .yaml .psi .YAMLCompoundValue ;
28- import org .jetbrains .yaml .psi .YAMLFile ;
2929import org .jetbrains .yaml .psi .YAMLKeyValue ;
3030import 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