Skip to content

Commit 9fa4613

Browse files
author
Vitaliy
authored
Merge branch '4.0.0-develop' into adjust-php-class-types-builder
2 parents 376660a + d4c03c7 commit 9fa4613

File tree

9 files changed

+254
-0
lines changed

9 files changed

+254
-0
lines changed

resources/META-INF/plugin.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,13 @@
229229
enabledByDefault="true" level="WARNING"
230230
implementationClass="com.magento.idea.magento2plugin.inspections.xml.PreferenceDeclarationInspection"/>
231231

232+
<localInspection language="XML" groupPath="XML"
233+
shortName="PluginAttrTypeInspection"
234+
bundle="magento2.inspection" key="inspection.displayName.PluginAttrTypeInspection"
235+
groupBundle="magento2.inspection" groupKey="inspection.group.name"
236+
enabledByDefault="true" level="WARNING"
237+
implementationClass="com.magento.idea.magento2plugin.inspections.xml.PluginAttributeTypeInspection"/>
238+
232239
<internalFileTemplate name="Magento Composer JSON"/>
233240
<internalFileTemplate name="Magento Registration PHP"/>
234241
<internalFileTemplate name="Magento Module XML"/>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!--
2+
/*
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
-->
7+
<html>
8+
<body>
9+
<p>
10+
Validates if attribute `type` in the &lt;plugin/&gt; tag of di.xml files contains valid classes or interfaces
11+
and that it cannot be empty.
12+
</p>
13+
<p>This inspection inspects:
14+
<ul>
15+
<li>The existence of the class on the specified path</li>
16+
<li>Tag `type` is not empty</li>
17+
</ul>
18+
</body>
19+
</html>

resources/magento2/inspection.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ inspection.displayName.ModuleDeclarationInModuleXmlInspection=Inspection for the
88
inspection.displayName.AclResourceXmlInspection=Inspection for the Title XML required attribute in the `etc/acl.xml` file
99
inspection.displayName.WebApiServiceInspection=Inspection for the Web API XML service declaration
1010
inspection.displayName.InvalidDiTypeInspection=Invalid type configuration in the `etc/di.xml` file
11+
inspection.displayName.PluginAttrTypeInspection=Inspection for the attribute `type` in the `plugin` tag
1112
inspection.displayName.PreferenceXmlInspections=Inspection for the Preference declaration
1213
inspection.plugin.duplicateInSameFile=The plugin name already used in this file. For more details see Inspection Description.
1314
inspection.plugin.duplicateInOtherPlaces=The plugin name "{0}" for targeted "{1}" class is already used in the module "{2}" ({3} scope). For more details see Inspection Description.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.inspections.xml;
7+
8+
import com.intellij.codeInspection.ProblemHighlightType;
9+
import com.intellij.codeInspection.ProblemsHolder;
10+
import com.intellij.codeInspection.XmlSuppressableInspectionTool;
11+
import com.intellij.psi.PsiElement;
12+
import com.intellij.psi.PsiElementVisitor;
13+
import com.intellij.psi.PsiFile;
14+
import com.intellij.psi.XmlElementVisitor;
15+
import com.intellij.psi.xml.XmlAttribute;
16+
import com.intellij.psi.xml.XmlTag;
17+
import com.magento.idea.magento2plugin.bundles.InspectionBundle;
18+
import com.magento.idea.magento2plugin.inspections.validator.InspectionValidator;
19+
import com.magento.idea.magento2plugin.inspections.validator.NotEmptyValidator;
20+
import com.magento.idea.magento2plugin.inspections.validator.PhpClassExistenceValidator;
21+
import com.magento.idea.magento2plugin.magento.files.ModuleDiXml;
22+
import org.jetbrains.annotations.NotNull;
23+
24+
public class PluginAttributeTypeInspection extends XmlSuppressableInspectionTool {
25+
26+
@Override
27+
public @NotNull
28+
PsiElementVisitor buildVisitor(
29+
final @NotNull ProblemsHolder problemsHolder,
30+
final boolean isOnTheFly
31+
) {
32+
return new XmlElementVisitor() {
33+
34+
private final InspectionBundle inspectionBundle = new InspectionBundle();
35+
private final InspectionValidator phpClassExistenceValidator =
36+
new PhpClassExistenceValidator(problemsHolder.getProject());
37+
private final InspectionValidator notEmptyValidator = new NotEmptyValidator();
38+
39+
@Override
40+
public void visitXmlTag(final XmlTag xmlTag) {
41+
final PsiFile file = xmlTag.getContainingFile();
42+
43+
if (!file.getName().equals(ModuleDiXml.FILE_NAME)
44+
|| !xmlTag.getName().equals(ModuleDiXml.PLUGIN_TAG_NAME)) {
45+
return;
46+
}
47+
48+
final XmlAttribute pluginTypeAttribute =
49+
xmlTag.getAttribute(ModuleDiXml.TYPE_ATTR);
50+
51+
if (pluginTypeAttribute == null
52+
|| pluginTypeAttribute.getValue() == null
53+
|| pluginTypeAttribute.getValueElement() == null
54+
|| pluginTypeAttribute.getValueElement().getText().isEmpty()) {
55+
return;
56+
}
57+
58+
if (!notEmptyValidator.validate(pluginTypeAttribute.getValue())) {
59+
reportCouldNotBeEmpty(
60+
pluginTypeAttribute.getValueElement(),
61+
pluginTypeAttribute.getName()
62+
);
63+
}
64+
65+
if (!phpClassExistenceValidator.validate(pluginTypeAttribute.getValue())) {
66+
reportClassDoesNotExists(
67+
pluginTypeAttribute.getValueElement(),
68+
pluginTypeAttribute.getValue()
69+
);
70+
}
71+
}
72+
73+
/**
74+
* Report Attribute Value could not be empty.
75+
*
76+
* @param psiElement PsiElement
77+
* @param messageParams Object...
78+
*/
79+
private void reportCouldNotBeEmpty(
80+
final @NotNull PsiElement psiElement,
81+
final Object... messageParams
82+
) {
83+
problemsHolder.registerProblem(
84+
psiElement,
85+
inspectionBundle.message(
86+
"inspection.error.idAttributeCanNotBeEmpty",
87+
messageParams
88+
),
89+
ProblemHighlightType.ERROR
90+
);
91+
}
92+
93+
/**
94+
* Report class does not exists.
95+
*
96+
* @param psiElement PsiElement
97+
* @param messageParams Object...
98+
*/
99+
private void reportClassDoesNotExists(
100+
final @NotNull PsiElement psiElement,
101+
final Object... messageParams
102+
) {
103+
problemsHolder.registerProblem(
104+
psiElement,
105+
inspectionBundle.message(
106+
"inspection.warning.class.does.not.exist",
107+
messageParams
108+
),
109+
ProblemHighlightType.WARNING
110+
);
111+
}
112+
};
113+
}
114+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0"?>
2+
<config>
3+
<type name="Magento\CatalogSearch\Helper\Data">
4+
<plugin name="unique_plugin_name" type=""/>
5+
</type>
6+
</config>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0"?>
2+
<config>
3+
<type name="Magento\CatalogSearch\Helper\Data">
4+
<plugin name="unique_plugin_name" type="Magento\Catalog\Plugin\PluginClass"/>
5+
</type>
6+
</config>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0"?>
2+
<config>
3+
<type name="Magento\CatalogSearch\Helper\Data">
4+
<plugin name="unique_plugin_name" type="Not\Existent\Class"/>
5+
</type>
6+
</config>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0"?>
2+
<config>
3+
<type name="Magento\CatalogSearch\Helper\Data">
4+
<plugin name="unique_plugin_name" type="Magento\Catalog\Plugin\PluginClass"/>
5+
</type>
6+
</config>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.inspections.xml;
7+
8+
import com.magento.idea.magento2plugin.magento.files.ModuleDiXml;
9+
10+
public class PluginAttributeTypeInspectionTest extends InspectionXmlFixtureTestCase {
11+
12+
private static final String ARGUMENT_VALUE_IS_EMPTY =
13+
"inspection.error.idAttributeCanNotBeEmpty";
14+
private static final String CLASS_DOES_NOT_EXIST =
15+
"inspection.warning.class.does.not.exist";
16+
private static final String EXISTENT_CLASS =
17+
"Magento\\Catalog\\Plugin\\PluginClass";
18+
private static final String NOT_EXISTENT_CLASS =
19+
"Not\\Existent\\Class";
20+
21+
@Override
22+
public void setUp() throws Exception {
23+
super.setUp();
24+
myFixture.enableInspections(PluginAttributeTypeInspection.class);
25+
}
26+
27+
/**
28+
* Test for an error for the "type" attribute because it is empty.
29+
* <plugin name="unique_plugin_name" type=""/>
30+
*/
31+
public void testAttrArgTypeValueIsEmpty() {
32+
configureFixture();
33+
34+
final String forAttrIsEmptyMessage = inspectionBundle.message(
35+
ARGUMENT_VALUE_IS_EMPTY,
36+
ModuleDiXml.TYPE_ATTR
37+
);
38+
39+
assertHasHighlighting(forAttrIsEmptyMessage);
40+
}
41+
42+
/**
43+
* Test for no error for the "type" attribute because this class exists.
44+
* <plugin name="unique_plugin_name" type="Magento\Catalog\Plugin\PluginClass" />
45+
*/
46+
public void testAttrTypeClassExists() {
47+
configureFixture();
48+
49+
final String typeAttrIsEmptyMessage = inspectionBundle.message(
50+
ARGUMENT_VALUE_IS_EMPTY,
51+
ModuleDiXml.TYPE_ATTR
52+
);
53+
54+
assertHasNoHighlighting(typeAttrIsEmptyMessage);
55+
}
56+
57+
/**
58+
* Test for throwing an error for a class that does not exist for the "type" attribute.
59+
*/
60+
public void testClassAttrTypeDoesNotExists() {
61+
configureFixture();
62+
63+
final String forClassDoesNotExists = inspectionBundle.message(
64+
CLASS_DOES_NOT_EXIST,
65+
NOT_EXISTENT_CLASS
66+
);
67+
68+
assertHasHighlighting(forClassDoesNotExists);
69+
}
70+
71+
/**
72+
* Test for the absence of an error in the presence of
73+
* classes or interfaces specified for plugins.
74+
*/
75+
public void testClassAttrTypeIsExist() {
76+
configureFixture();
77+
78+
final String classOneExists = inspectionBundle.message(
79+
CLASS_DOES_NOT_EXIST,
80+
EXISTENT_CLASS
81+
);
82+
83+
assertHasNoHighlighting(classOneExists);
84+
}
85+
86+
private void configureFixture() {
87+
myFixture.configureByFile(getFixturePath(ModuleDiXml.FILE_NAME));
88+
}
89+
}

0 commit comments

Comments
 (0)