Skip to content

Commit 81b03eb

Browse files
UCT-713: Developed ImplementedNonExistentInterface inspection
1 parent d2f5e7d commit 81b03eb

File tree

7 files changed

+172
-113
lines changed

7 files changed

+172
-113
lines changed

resources/META-INF/plugin.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,13 @@
361361
enabledByDefault="false"
362362
level="ERROR"
363363
implementationClass="com.magento.idea.magento2uct.inspections.php.existence.InheritedNonExistentInterface"/>
364+
<localInspection language="PHP" groupPath="UCT"
365+
shortName="ImplementedNonExistentInterface"
366+
bundle="uct.bundle.inspection" key="inspection.displayName.ImplementedNonExistentInterface"
367+
groupBundle="uct.bundle.inspection" groupKey="inspection.existence.group.name"
368+
enabledByDefault="false"
369+
level="ERROR"
370+
implementationClass="com.magento.idea.magento2uct.inspections.php.existence.ImplementedNonExistentInterface"/>
364371
<!-- \UCT inspection -->
365372

366373
<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>[1318] The implemented interface is no longer present in the codebase.</p>
4+
<!-- tooltip end -->
5+
</body>
6+
</html>

resources/uct/bundle/inspection.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ inspection.displayName.UsingDeprecatedProperty=Using @deprecated property
1616
inspection.displayName.ImportingNonExistentClass=Importing non-existent Adobe Commerce class
1717
inspection.displayName.ImportingNonExistentInterface=Importing non-existent Adobe Commerce interface
1818
inspection.displayName.InheritedNonExistentInterface=Inherited non-existent Adobe Commerce interface
19+
inspection.displayName.ImplementedNonExistentInterface=Implemented non-existent Adobe Commerce interface
1920
customCode.warnings.deprecated.1131=[1131] Extending from @deprecated class ''{0}''
2021
customCode.warnings.deprecated.1132=[1132] Importing @deprecated class ''{0}''
2122
customCode.warnings.deprecated.1134=[1134] Using @deprecated class ''{0}''
@@ -34,3 +35,5 @@ customCode.critical.existence.1312=[1312] Imported non-existent interface ''{0}'
3435
customCode.critical.existence.1312.changelog=[1312] Imported interface ''{0}'' that is removed in the ''{1}''
3536
customCode.critical.existence.1317=[1317] Inherited non-existent interface ''{0}''
3637
customCode.critical.existence.1317.changelog=[1317] Inherited interface ''{0}'' that is removed in the ''{1}''
38+
customCode.critical.existence.1318=[1318] Implemented non-existent interface ''{0}''
39+
customCode.critical.existence.1318.changelog=[1318] Implemented interface ''{0}'' that is removed in the ''{1}''
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2uct.inspections.php;
7+
8+
import com.intellij.codeInspection.ProblemsHolder;
9+
import com.intellij.openapi.project.Project;
10+
import com.intellij.psi.PsiElement;
11+
import com.intellij.psi.PsiElementVisitor;
12+
import com.jetbrains.php.lang.inspections.PhpInspection;
13+
import com.jetbrains.php.lang.psi.elements.ClassReference;
14+
import com.jetbrains.php.lang.psi.elements.PhpClass;
15+
import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor;
16+
import com.magento.idea.magento2uct.packages.IssueSeverityLevel;
17+
import com.magento.idea.magento2uct.settings.UctSettingsService;
18+
import org.jetbrains.annotations.NotNull;
19+
20+
public abstract class ImplementInspection extends PhpInspection {
21+
22+
@Override
23+
public @NotNull PsiElementVisitor buildVisitor(
24+
final @NotNull ProblemsHolder problemsHolder,
25+
final boolean isOnTheFly
26+
) {
27+
return new PhpElementVisitor() {
28+
29+
@Override
30+
public void visitPhpClass(final PhpClass clazz) {
31+
final Project project = clazz.getProject();
32+
final UctSettingsService settings = UctSettingsService.getInstance(project);
33+
34+
if (clazz.isInterface()
35+
|| !settings.isEnabled()
36+
|| !settings.isIssueLevelSatisfiable(getSeverityLevel())) {
37+
return;
38+
}
39+
40+
for (final ClassReference ref : clazz.getImplementsList().getReferenceElements()) {
41+
final String interfaceFqn = ref.getFQN();
42+
final PsiElement interfaceClass = ref.resolve();
43+
44+
if (interfaceFqn == null || !(interfaceClass instanceof PhpClass)) {
45+
continue;
46+
}
47+
48+
execute(project, problemsHolder, ref, interfaceFqn);
49+
}
50+
}
51+
};
52+
}
53+
54+
/**
55+
* Implement this method to specify inspection logic.
56+
*
57+
* @param project Project
58+
* @param problemsHolder ProblemsHolder
59+
* @param reference ClassReference
60+
* @param interfaceFqn String
61+
*/
62+
protected abstract void execute(
63+
final Project project,
64+
final @NotNull ProblemsHolder problemsHolder,
65+
final ClassReference reference,
66+
final String interfaceFqn
67+
);
68+
69+
/**
70+
* Implement this method to specify issue severity level for target inspection.
71+
*
72+
* @return IssueSeverityLevel
73+
*/
74+
protected abstract IssueSeverityLevel getSeverityLevel();
75+
}

src/com/magento/idea/magento2uct/inspections/php/deprecation/ImplementedDeprecatedInterface.java

Lines changed: 24 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -8,130 +8,41 @@
88
import com.intellij.codeInspection.ProblemHighlightType;
99
import com.intellij.codeInspection.ProblemsHolder;
1010
import com.intellij.openapi.project.Project;
11-
import com.intellij.openapi.util.Pair;
12-
import com.intellij.psi.PsiElement;
13-
import com.intellij.psi.PsiElementVisitor;
14-
import com.jetbrains.php.lang.inspections.PhpInspection;
1511
import com.jetbrains.php.lang.psi.elements.ClassReference;
16-
import com.jetbrains.php.lang.psi.elements.PhpClass;
17-
import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor;
1812
import com.magento.idea.magento2uct.inspections.UctProblemsHolder;
13+
import com.magento.idea.magento2uct.inspections.php.ImplementInspection;
14+
import com.magento.idea.magento2uct.packages.IssueSeverityLevel;
1915
import com.magento.idea.magento2uct.packages.SupportedIssue;
20-
import com.magento.idea.magento2uct.settings.UctSettingsService;
2116
import com.magento.idea.magento2uct.versioning.VersionStateManager;
22-
import java.util.List;
2317
import org.jetbrains.annotations.NotNull;
2418

25-
public class ImplementedDeprecatedInterface extends PhpInspection {
19+
public class ImplementedDeprecatedInterface extends ImplementInspection {
2620

2721
@Override
28-
@SuppressWarnings({
29-
"PMD.CognitiveComplexity",
30-
"PMD.ExcessiveMethodLength",
31-
"PMD.NPathComplexity"
32-
})
33-
public @NotNull PsiElementVisitor buildVisitor(
22+
protected void execute(
23+
final Project project,
3424
final @NotNull ProblemsHolder problemsHolder,
35-
final boolean isOnTheFly
25+
final ClassReference reference,
26+
final String interfaceFqn
3627
) {
37-
return new PhpElementVisitor() {
38-
39-
@Override
40-
public void visitPhpClass(final PhpClass clazz) {
41-
final Project project = clazz.getProject();
42-
final UctSettingsService settings = UctSettingsService.getInstance(project);
43-
44-
if (!settings.isEnabled() || !settings.isIssueLevelSatisfiable(
45-
SupportedIssue.IMPLEMENTED_DEPRECATED_INTERFACE.getLevel())
46-
) {
47-
return;
48-
}
49-
50-
if (clazz.isInterface()) {
51-
return;
52-
}
53-
for (final ClassReference ref : clazz.getImplementsList().getReferenceElements()) {
54-
final String interfaceFqn = ref.getFQN();
55-
final PsiElement interfaceClass = ref.resolve();
56-
57-
if (interfaceFqn == null || !(interfaceClass instanceof PhpClass)) {
58-
continue;
59-
}
60-
final boolean isDeprecated = VersionStateManager
61-
.getInstance(project).isDeprecated(interfaceFqn);
62-
63-
if (isDeprecated) {
64-
if (problemsHolder instanceof UctProblemsHolder) {
65-
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
66-
SupportedIssue.IMPLEMENTED_DEPRECATED_INTERFACE.getCode()
67-
);
68-
}
69-
problemsHolder.registerProblem(
70-
ref,
71-
SupportedIssue.IMPLEMENTED_DEPRECATED_INTERFACE.getMessage(
72-
interfaceFqn
73-
),
74-
ProblemHighlightType.LIKE_DEPRECATED
75-
);
76-
}
77-
}
78-
79-
PhpClass parentClass = clazz.getSuperClass();
80-
81-
while (parentClass != null) {
82-
final Pair<Boolean, String> checkResult = checkImplements(parentClass);
83-
84-
if (checkResult.getFirst()) {
85-
final List<ClassReference> classExtends =
86-
clazz.getExtendsList().getReferenceElements();
87-
88-
if (classExtends.isEmpty()) {
89-
break;
90-
}
91-
if (problemsHolder instanceof UctProblemsHolder) {
92-
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
93-
SupportedIssue.IMPLEMENTED_DEPRECATED_INTERFACE.getCode()
94-
);
95-
}
96-
problemsHolder.registerProblem(
97-
classExtends.get(0),
98-
SupportedIssue.IMPLEMENTED_DEPRECATED_INTERFACE.getMessage(
99-
checkResult.getSecond()
100-
),
101-
ProblemHighlightType.LIKE_DEPRECATED
102-
);
103-
}
104-
parentClass = parentClass.getSuperClass();
105-
}
28+
if (VersionStateManager.getInstance(project).isDeprecated(interfaceFqn)) {
29+
if (problemsHolder instanceof UctProblemsHolder) {
30+
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
31+
SupportedIssue.IMPLEMENTED_DEPRECATED_INTERFACE.getCode()
32+
);
10633
}
34+
problemsHolder.registerProblem(
35+
reference,
36+
SupportedIssue.IMPLEMENTED_DEPRECATED_INTERFACE.getMessage(
37+
interfaceFqn
38+
),
39+
ProblemHighlightType.LIKE_DEPRECATED
40+
);
41+
}
42+
}
10743

108-
/**
109-
* Check class implements.
110-
*
111-
* @param clazz PhpClass
112-
*
113-
* @return Pair[Boolean, String]
114-
*/
115-
private Pair<Boolean, String> checkImplements(final PhpClass clazz) {
116-
if (clazz.isInterface()) {
117-
return new Pair<>(false, null);
118-
}
119-
for (final ClassReference ref : clazz.getImplementsList().getReferenceElements()) {
120-
final String interfaceFqn = ref.getFQN();
121-
final PsiElement interfaceClass = ref.resolve();
122-
123-
if (interfaceFqn == null || !(interfaceClass instanceof PhpClass)) {
124-
continue;
125-
}
126-
127-
if (VersionStateManager.getInstance(clazz.getProject())
128-
.isDeprecated(interfaceFqn)) {
129-
return new Pair<>(true, interfaceFqn);
130-
}
131-
}
132-
133-
return new Pair<>(false, null);
134-
}
135-
};
44+
@Override
45+
protected IssueSeverityLevel getSeverityLevel() {
46+
return SupportedIssue.IMPLEMENTED_DEPRECATED_INTERFACE.getLevel();
13647
}
13748
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2uct.inspections.php.existence;
7+
8+
import com.intellij.codeInspection.ProblemHighlightType;
9+
import com.intellij.codeInspection.ProblemsHolder;
10+
import com.intellij.openapi.project.Project;
11+
import com.jetbrains.php.lang.psi.elements.ClassReference;
12+
import com.magento.idea.magento2uct.inspections.UctProblemsHolder;
13+
import com.magento.idea.magento2uct.inspections.php.ImplementInspection;
14+
import com.magento.idea.magento2uct.packages.IssueSeverityLevel;
15+
import com.magento.idea.magento2uct.packages.SupportedIssue;
16+
import com.magento.idea.magento2uct.versioning.VersionStateManager;
17+
import org.jetbrains.annotations.NotNull;
18+
19+
public class ImplementedNonExistentInterface extends ImplementInspection {
20+
21+
@Override
22+
protected void execute(
23+
final Project project,
24+
final @NotNull ProblemsHolder problemsHolder,
25+
final ClassReference reference,
26+
final String interfaceFqn
27+
) {
28+
if (VersionStateManager.getInstance(project).isExists(interfaceFqn)) {
29+
return;
30+
}
31+
final String removedIn = VersionStateManager.getInstance(project).getRemovedInVersion();
32+
final String message = removedIn.isEmpty()
33+
? SupportedIssue.IMPLEMENTED_NON_EXISTENT_INTERFACE.getMessage(interfaceFqn)
34+
: SupportedIssue.IMPLEMENTED_NON_EXISTENT_INTERFACE.getChangelogMessage(
35+
interfaceFqn, removedIn);
36+
37+
if (problemsHolder instanceof UctProblemsHolder) {
38+
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
39+
SupportedIssue.IMPLEMENTED_NON_EXISTENT_INTERFACE.getCode()
40+
);
41+
}
42+
problemsHolder.registerProblem(reference, message, ProblemHighlightType.ERROR);
43+
}
44+
45+
@Override
46+
protected IssueSeverityLevel getSeverityLevel() {
47+
return SupportedIssue.IMPLEMENTED_NON_EXISTENT_INTERFACE.getLevel();
48+
}
49+
}

src/com/magento/idea/magento2uct/packages/SupportedIssue.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.magento.idea.magento2uct.inspections.php.deprecation.UsingDeprecatedConstant;
2222
import com.magento.idea.magento2uct.inspections.php.deprecation.UsingDeprecatedInterface;
2323
import com.magento.idea.magento2uct.inspections.php.deprecation.UsingDeprecatedProperty;
24+
import com.magento.idea.magento2uct.inspections.php.existence.ImplementedNonExistentInterface;
2425
import com.magento.idea.magento2uct.inspections.php.existence.ImportingNonExistentClass;
2526
import com.magento.idea.magento2uct.inspections.php.existence.ImportingNonExistentInterface;
2627
import com.magento.idea.magento2uct.inspections.php.existence.InheritedNonExistentInterface;
@@ -123,6 +124,13 @@ public enum SupportedIssue {
123124
"customCode.critical.existence.1317",
124125
InheritedNonExistentInterface.class,
125126
"customCode.critical.existence.1317.changelog"
127+
),
128+
IMPLEMENTED_NON_EXISTENT_INTERFACE(
129+
1318,
130+
IssueSeverityLevel.CRITICAL,
131+
"customCode.critical.existence.1318",
132+
ImplementedNonExistentInterface.class,
133+
"customCode.critical.existence.1318.changelog"
126134
);
127135

128136
private final int code;

0 commit comments

Comments
 (0)