Skip to content

Commit cb76518

Browse files
Merge pull request #1038 from bohdan-harniuk/uct-1030-add-config-files-support
UCT-1030: Added configuration files support
2 parents db7ef2d + 334b769 commit cb76518

24 files changed

+788
-28
lines changed

resources/META-INF/plugin.xml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,50 @@
543543
enabledByDefault="false"
544544
level="WARNING"
545545
implementationClass="com.magento.idea.magento2uct.inspections.php.api.CalledNonInterfaceMethod"/>
546+
547+
<localInspection language="XML" groupPath="UCT"
548+
shortName="UsedDeprecatedTypeInConfig"
549+
bundle="uct.bundle.inspection" key="inspection.displayName.UsedDeprecatedTypeInConfig"
550+
groupBundle="uct.bundle.inspection" groupKey="inspection.deprecation.group.name"
551+
enabledByDefault="false"
552+
level="WARNING"
553+
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedDeprecatedTypeInConfig"/>
554+
<localInspection language="XML" groupPath="UCT"
555+
shortName="UsedDeprecatedConstantInConfig"
556+
bundle="uct.bundle.inspection" key="inspection.displayName.UsedDeprecatedConstantInConfig"
557+
groupBundle="uct.bundle.inspection" groupKey="inspection.deprecation.group.name"
558+
enabledByDefault="false"
559+
level="WARNING"
560+
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedDeprecatedConstantInConfig"/>
561+
<localInspection language="XML" groupPath="UCT"
562+
shortName="UsedDeprecatedMethodInConfig"
563+
bundle="uct.bundle.inspection" key="inspection.displayName.UsedDeprecatedMethodInConfig"
564+
groupBundle="uct.bundle.inspection" groupKey="inspection.deprecation.group.name"
565+
enabledByDefault="false"
566+
level="WARNING"
567+
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedDeprecatedMethodInConfig"/>
568+
569+
<localInspection language="XML" groupPath="UCT"
570+
shortName="UsedNonExistentTypeInConfig"
571+
bundle="uct.bundle.inspection" key="inspection.displayName.UsedNonExistentTypeInConfig"
572+
groupBundle="uct.bundle.inspection" groupKey="inspection.existence.group.name"
573+
enabledByDefault="false"
574+
level="ERROR"
575+
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedNonExistentTypeInConfig"/>
576+
<localInspection language="XML" groupPath="UCT"
577+
shortName="UsedNonExistentConstantInConfig"
578+
bundle="uct.bundle.inspection" key="inspection.displayName.UsedNonExistentConstantInConfig"
579+
groupBundle="uct.bundle.inspection" groupKey="inspection.existence.group.name"
580+
enabledByDefault="false"
581+
level="ERROR"
582+
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedNonExistentConstantInConfig"/>
583+
<localInspection language="XML" groupPath="UCT"
584+
shortName="UsedNonExistentMethodInConfig"
585+
bundle="uct.bundle.inspection" key="inspection.displayName.UsedNonExistentMethodInConfig"
586+
groupBundle="uct.bundle.inspection" groupKey="inspection.existence.group.name"
587+
enabledByDefault="false"
588+
level="ERROR"
589+
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedNonExistentMethodInConfig"/>
546590
<!-- \UCT inspection -->
547591

548592
<internalFileTemplate name="Magento Composer JSON"/>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<body>
3+
<p>[1234] Using Magento 2 @deprecated constant: consider using Magento Open Source|Adobe Commerce constant marked as @api instead.</p>
4+
<!-- tooltip end -->
5+
</body>
6+
</html>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<body>
3+
<p>[1439] Using Magento 2 @deprecated method: this method will be removed in upcoming versions. Consider relying on methods declared in API interfaces instead.</p>
4+
<!-- tooltip end -->
5+
</body>
6+
</html>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<body>
3+
<p>[1134] Using Magento 2 @deprecated type: consider using Magento Open Source|Adobe Commerce type marked as @api instead.</p>
4+
<!-- tooltip end -->
5+
</body>
6+
</html>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<body>
3+
<p>[1214] The used constant is no longer present in the codebase.</p>
4+
<!-- tooltip end -->
5+
</body>
6+
</html>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<body>
3+
<p>[1410] The used method is no longer present in the codebase.</p>
4+
<!-- tooltip end -->
5+
</body>
6+
</html>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<body>
3+
<p>[1110] The used type is no longer present in the codebase.</p>
4+
<!-- tooltip end -->
5+
</body>
6+
</html>

resources/uct/bundle/inspection.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ inspection.displayName.ExtendedNonApiClass=Extended non Magento 2 API class
3838
inspection.displayName.InheritedNonApiInterface=Inherited non Magento 2 API interface
3939
inspection.displayName.PossibleDependencyOnImplDetails=Possible dependency on implementation details
4040
inspection.displayName.CalledNonInterfaceMethod=Called non-interface method
41+
inspection.displayName.UsedNonExistentTypeInConfig=Used non-existent Magento 2 type in the configuration file
42+
inspection.displayName.UsedDeprecatedTypeInConfig=Used deprecated Magento 2 type in the configuration file
43+
inspection.displayName.UsedDeprecatedConstantInConfig=Used deprecated Magento 2 constant in the configuration file
44+
inspection.displayName.UsedDeprecatedMethodInConfig=Used deprecated Magento 2 method in the configuration file
45+
inspection.displayName.UsedNonExistentConstantInConfig=Used non-existent Magento 2 constant in the configuration file
46+
inspection.displayName.UsedNonExistentMethodInConfig=Used non-existent Magento 2 method in the configuration file
4147
customCode.warnings.deprecated.1131=[1131] Extended class ''{0}'' that is @deprecated in the ''{1}''
4248
customCode.warnings.deprecated.1132=[1132] Imported class ''{0}'' that is @deprecated in the ''{1}''
4349
customCode.warnings.deprecated.1134=[1134] Used class ''{0}'' that is @deprecated in the ''{1}''

src/com/magento/idea/magento2uct/execution/GenerateUctReportCommand.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.intellij.psi.PsiDocumentManager;
2121
import com.intellij.psi.PsiFile;
2222
import com.intellij.psi.PsiManager;
23-
import com.jetbrains.php.lang.psi.PhpFile;
2423
import com.magento.idea.magento2plugin.util.magento.MagentoVersionUtil;
2524
import com.magento.idea.magento2uct.execution.output.ReportBuilder;
2625
import com.magento.idea.magento2uct.execution.output.Summary;
@@ -135,9 +134,6 @@ public void execute() {
135134
boolean isModuleHeaderPrinted = false;
136135

137136
for (final PsiFile psiFile : new ModuleFilesScanner(componentData)) {
138-
if (!(psiFile instanceof PhpFile)) {
139-
continue;
140-
}
141137
final String filename = psiFile.getVirtualFile().getPath();
142138
final UctInspectionManager inspectionManager = new UctInspectionManager(
143139
project

src/com/magento/idea/magento2uct/execution/scanner/ModuleFilesScanner.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
import com.intellij.psi.PsiDirectory;
99
import com.intellij.psi.PsiFile;
10-
import com.jetbrains.php.lang.psi.PhpFile;
1110
import com.magento.idea.magento2uct.execution.scanner.data.ComponentData;
11+
import com.magento.idea.magento2uct.packages.SupportedIssue;
1212
import java.util.ArrayList;
1313
import java.util.Iterator;
1414
import java.util.List;
@@ -53,9 +53,12 @@ private List<PsiFile> run() {
5353
*/
5454
private void collectFilesInDirectoryRecursively(final @NotNull PsiDirectory directory) {
5555
for (final PsiFile file : directory.getFiles()) {
56-
if (file instanceof PhpFile) {
57-
files.add(file);
56+
if (SupportedIssue.getSupportedFileTypes().stream().noneMatch(
57+
clazz -> clazz.isInstance(file))
58+
) {
59+
continue;
5860
}
61+
files.add(file);
5962
}
6063

6164
for (final PsiDirectory subDirectory : directory.getSubdirectories()) {

src/com/magento/idea/magento2uct/inspections/UctInspectionManager.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.intellij.psi.PsiElementVisitor;
1212
import com.intellij.psi.PsiFile;
1313
import com.intellij.psi.util.PsiTreeUtil;
14+
import com.intellij.psi.xml.XmlFile;
1415
import com.jetbrains.php.codeInsight.PhpCodeInsightUtil;
1516
import com.jetbrains.php.lang.psi.PhpFile;
1617
import com.jetbrains.php.lang.psi.elements.AssignmentExpression;
@@ -49,7 +50,9 @@ public UctInspectionManager(final @NotNull Project project) {
4950
* @return ProblemsHolder
5051
*/
5152
public @Nullable UctProblemsHolder run(final PsiFile psiFile) {
52-
if (!(psiFile instanceof PhpFile)) {
53+
if (SupportedIssue.getSupportedFileTypes().stream().noneMatch(
54+
clazz -> clazz.isInstance(psiFile))
55+
) {
5356
return null;
5457
}
5558
final UctProblemsHolder problemsHolder = new UctProblemsHolder(
@@ -78,25 +81,29 @@ public UctInspectionManager(final @NotNull Project project) {
7881
private List<PsiElement> collectElements(final @NotNull PsiFile psiFile) {
7982
final List<PsiElement> elements = new LinkedList<>();
8083

81-
final PhpClass phpClass = GetFirstClassOfFile.getInstance().execute((PhpFile) psiFile);
84+
if (psiFile instanceof PhpFile) {
85+
final PhpClass phpClass = GetFirstClassOfFile.getInstance().execute((PhpFile) psiFile);
8286

83-
if (phpClass != null) {
84-
elements.add(phpClass);
85-
final PhpPsiElement scopeForUseOperator = PhpCodeInsightUtil.findScopeForUseOperator(
86-
phpClass
87-
);
87+
if (phpClass != null) {
88+
elements.add(phpClass);
89+
final PhpPsiElement scopeForUseOperator = PhpCodeInsightUtil
90+
.findScopeForUseOperator(phpClass);
8891

89-
if (scopeForUseOperator != null) {
90-
elements.addAll(PhpCodeInsightUtil.collectImports(scopeForUseOperator));
92+
if (scopeForUseOperator != null) {
93+
elements.addAll(PhpCodeInsightUtil.collectImports(scopeForUseOperator));
94+
}
95+
elements.addAll(Arrays.asList(phpClass.getOwnFields()));
9196
}
92-
elements.addAll(Arrays.asList(phpClass.getOwnFields()));
93-
}
94-
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, ClassConstantReference.class));
95-
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, MethodReference.class));
96-
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, AssignmentExpression.class));
97-
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, ClassReference.class));
98-
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, FieldReference.class));
9997

98+
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, ClassConstantReference.class));
99+
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, MethodReference.class));
100+
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, AssignmentExpression.class));
101+
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, ClassReference.class));
102+
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, FieldReference.class));
103+
} else if (psiFile instanceof XmlFile) {
104+
elements.add(psiFile);
105+
}
106+
100107
return elements;
101108
}
102109
}

src/com/magento/idea/magento2uct/inspections/UctProblemsHolder.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ public void registerProblem(final @NotNull ProblemDescriptor problemDescriptor)
7474
// if problem has been added successfully
7575
if (problemCount != getMyProblems().size()) {
7676
myProblemCodes.put(problemDescriptor, issue);
77-
issue = null;//NOPMD
7877
}
7978
}
8079

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2uct.inspections.xml;
7+
8+
import com.intellij.codeInspection.InspectionManager;
9+
import com.intellij.codeInspection.ProblemDescriptor;
10+
import com.intellij.codeInspection.ProblemsHolder;
11+
import com.intellij.codeInspection.XmlSuppressableInspectionTool;
12+
import com.intellij.openapi.project.Project;
13+
import com.intellij.openapi.vfs.VirtualFile;
14+
import com.intellij.psi.PsiElement;
15+
import com.intellij.psi.PsiElementVisitor;
16+
import com.intellij.psi.PsiFile;
17+
import com.intellij.psi.tree.IElementType;
18+
import com.intellij.psi.util.PsiTreeUtil;
19+
import com.intellij.psi.xml.XmlToken;
20+
import com.intellij.psi.xml.XmlTokenType;
21+
import com.magento.idea.magento2uct.settings.UctSettingsService;
22+
import com.magento.idea.magento2uct.versioning.VersionStateManager;
23+
import java.util.ArrayList;
24+
import java.util.Arrays;
25+
import java.util.List;
26+
import java.util.regex.Pattern;
27+
import org.jetbrains.annotations.NotNull;
28+
import org.jetbrains.annotations.Nullable;
29+
30+
abstract class ModuleConfigFileInspection extends XmlSuppressableInspectionTool {
31+
32+
private static final String LAYOUT_FILE_REGEX = "\\/(layout|ui_component)\\/.*\\.xml";
33+
private static final Pattern LAYOUT_FILE_PATTERN = Pattern.compile(LAYOUT_FILE_REGEX);
34+
35+
private final String[] supportedFiles = {
36+
"di.xml",
37+
"system.xml",
38+
"events.xml",
39+
"extension_attributes.xml",
40+
"webapi.xml",
41+
"communication.xml",
42+
"queue_consumer.xml",
43+
"crontab.xml",
44+
"indexer.xml",
45+
"mview.xml",
46+
"product_types.xml",
47+
"widget.xml",
48+
"queue.xml",
49+
"product_options.xml",
50+
"export.xml",
51+
"import.xml",
52+
"analytics.xml",
53+
"reports.xml",
54+
"pdf.xml",
55+
"cache.xml",
56+
"validation.xml"
57+
};
58+
private ProblemsHolder problemsHolder;
59+
60+
@Override
61+
public @NotNull PsiElementVisitor buildVisitor(
62+
final @NotNull ProblemsHolder holder,
63+
final boolean isOnTheFly
64+
) {
65+
problemsHolder = holder;
66+
67+
return super.buildVisitor(holder, isOnTheFly);
68+
}
69+
70+
@Override
71+
public @Nullable ProblemDescriptor[] checkFile(
72+
final @NotNull PsiFile file,
73+
final @NotNull InspectionManager manager,
74+
final boolean isOnTheFly
75+
) {
76+
final Project project = file.getProject();
77+
final UctSettingsService settings = UctSettingsService.getInstance(project);
78+
final ProblemsHolder holder = getProblemsHolder();
79+
80+
if (!settings.isEnabled() || holder == null) {
81+
return getEmptyResult();
82+
}
83+
84+
if (Arrays.stream(supportedFiles).noneMatch(name -> name.equals(file.getName()))
85+
&& !isLayoutFile(file)) {
86+
return getEmptyResult();
87+
}
88+
final List<IElementType> allowedTokenTypes = new ArrayList<>();
89+
allowedTokenTypes.add(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN);
90+
allowedTokenTypes.add(XmlTokenType.XML_DATA_CHARACTERS);
91+
92+
final List<ProblemDescriptor> descriptors = new ArrayList<>();
93+
94+
for (final XmlToken token : PsiTreeUtil.findChildrenOfType(file, XmlToken.class)) {
95+
if (!allowedTokenTypes.contains(token.getTokenType())) {
96+
continue;
97+
}
98+
final String fqn = token.getText().trim();
99+
100+
if (!VersionStateManager.getInstance(project).isPresentInCodebase(fqn)) {
101+
continue;
102+
}
103+
// Inspection logic.
104+
doInspection(fqn, token, manager, holder, isOnTheFly, descriptors);
105+
}
106+
107+
return descriptors.toArray(new ProblemDescriptor[0]);
108+
}
109+
110+
/**
111+
* Implement this method to specify inspection logic.
112+
*
113+
* @param fqn String
114+
* @param target PsiElement
115+
* @param manager InspectionManager
116+
* @param holder ProblemsHolder
117+
* @param isOnTheFly boolean
118+
* @param descriptors List[ProblemDescriptor]
119+
*/
120+
protected abstract void doInspection(
121+
final @NotNull String fqn,
122+
final @NotNull PsiElement target,
123+
final @NotNull InspectionManager manager,
124+
final @NotNull ProblemsHolder holder,
125+
final boolean isOnTheFly,
126+
final @NotNull List<ProblemDescriptor> descriptors
127+
);
128+
129+
private @Nullable ProblemsHolder getProblemsHolder() {
130+
return problemsHolder;
131+
}
132+
133+
/**
134+
* Retrieves an empty result.
135+
*
136+
* @return ProblemDescriptor[]
137+
*/
138+
private ProblemDescriptor[] getEmptyResult() {
139+
return new ProblemDescriptor[0];
140+
}
141+
142+
private boolean isLayoutFile(final @NotNull PsiFile file) {
143+
final VirtualFile virtualFile = file.getVirtualFile();
144+
145+
if (virtualFile == null) {
146+
return false;
147+
}
148+
149+
return LAYOUT_FILE_PATTERN.matcher(virtualFile.getPath()).find();
150+
}
151+
}

0 commit comments

Comments
 (0)