Skip to content

Commit fd6e4e2

Browse files
authored
Merge pull request #762 from bohdan-harniuk/uct-inspection-overridden-non-existent-constant
UCT-708: Developed OverriddenNonExistentConstant inspection
2 parents 48f7c34 + adfdf5a commit fd6e4e2

File tree

8 files changed

+215
-63
lines changed

8 files changed

+215
-63
lines changed

resources/META-INF/plugin.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,13 @@
375375
enabledByDefault="false"
376376
level="ERROR"
377377
implementationClass="com.magento.idea.magento2uct.inspections.php.existence.ExtendedNonExistentClass"/>
378+
<localInspection language="PHP" groupPath="UCT"
379+
shortName="OverriddenNonExistentConstant"
380+
bundle="uct.bundle.inspection" key="inspection.displayName.OverriddenNonExistentConstant"
381+
groupBundle="uct.bundle.inspection" groupKey="inspection.existence.group.name"
382+
enabledByDefault="false"
383+
level="ERROR"
384+
implementationClass="com.magento.idea.magento2uct.inspections.php.existence.OverriddenNonExistentConstant"/>
378385
<!-- \UCT inspection -->
379386

380387
<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>[1215] The overridden constant 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
@@ -18,6 +18,7 @@ inspection.displayName.ImportingNonExistentInterface=Importing non-existent Adob
1818
inspection.displayName.InheritedNonExistentInterface=Inherited non-existent Adobe Commerce interface
1919
inspection.displayName.ImplementedNonExistentInterface=Implemented non-existent Adobe Commerce interface
2020
inspection.displayName.ExtendedNonExistentClass=Extended non-existent Adobe Commerce class
21+
inspection.displayName.OverriddenNonExistentConstant=Overridden non-existent Adobe Commerce constant
2122
customCode.warnings.deprecated.1131=[1131] Extending from @deprecated class ''{0}''
2223
customCode.warnings.deprecated.1132=[1132] Importing @deprecated class ''{0}''
2324
customCode.warnings.deprecated.1134=[1134] Using @deprecated class ''{0}''
@@ -40,3 +41,5 @@ customCode.critical.existence.1318=[1318] Implemented non-existent interface ''{
4041
customCode.critical.existence.1318.changelog=[1318] Implemented interface ''{0}'' that is removed in the ''{1}''
4142
customCode.critical.existence.1111=[1111] Extended non-existent class ''{0}''
4243
customCode.critical.existence.1111.changelog=[1111] Extended class ''{0}'' that is removed in the ''{1}''
44+
customCode.critical.existence.1215=[1215] Overridden non-existent constant ''{0}''
45+
customCode.critical.existence.1215.changelog=[1215] Overridden constant ''{0}'' that is removed in the ''{1}''

src/com/magento/idea/magento2uct/inspections/php/ExtendInspection.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
public abstract class ExtendInspection extends PhpInspection {
2020

2121
@Override
22-
public @NotNull
23-
PsiElementVisitor buildVisitor(
22+
public @NotNull PsiElementVisitor buildVisitor(
2423
final @NotNull ProblemsHolder problemsHolder,
2524
final boolean isOnTheFly
2625
) {
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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.PsiElementVisitor;
11+
import com.jetbrains.php.lang.inspections.PhpInspection;
12+
import com.jetbrains.php.lang.psi.elements.Field;
13+
import com.jetbrains.php.lang.psi.elements.PhpClass;
14+
import com.jetbrains.php.lang.psi.resolve.types.PhpTypeAnalyserVisitor;
15+
import com.magento.idea.magento2uct.packages.IssueSeverityLevel;
16+
import com.magento.idea.magento2uct.settings.UctSettingsService;
17+
import org.jetbrains.annotations.NotNull;
18+
19+
public abstract class OverriddenFieldInspection extends PhpInspection {
20+
21+
@Override
22+
public @NotNull PsiElementVisitor buildVisitor(
23+
final @NotNull ProblemsHolder problemsHolder,
24+
final boolean isOnTheFly
25+
) {
26+
return new PhpTypeAnalyserVisitor() {
27+
28+
@Override
29+
public void visitPhpField(final Field field) {
30+
final Project project = field.getProject();
31+
final UctSettingsService settings = UctSettingsService.getInstance(project);
32+
final PhpClass phpClass = field.getContainingClass();
33+
34+
if (!settings.isEnabled()
35+
|| phpClass == null
36+
|| !isTypeValid(field)
37+
|| !settings.isIssueLevelSatisfiable(getSeverityLevel())) {
38+
return;
39+
}
40+
super.visitPhpField(field);
41+
42+
PhpClass parentClass = phpClass.getSuperClass();
43+
boolean isFound = false;
44+
45+
while (parentClass != null && !isFound) {
46+
for (final Field ownField : parentClass.getOwnFields()) {
47+
if (!ownField.getModifier().isPrivate()
48+
&& isTypeValid(ownField)
49+
&& ownField.getName().equals(field.getName())
50+
) {
51+
execute(project, problemsHolder, field, ownField, parentClass);
52+
isFound = true;
53+
break;
54+
}
55+
}
56+
parentClass = parentClass.getSuperClass();
57+
}
58+
}
59+
};
60+
}
61+
62+
/**
63+
* Implement this method to specify inspection logic.
64+
*
65+
* @param project Project
66+
* @param problemsHolder ProblemsHolder
67+
* @param field Field
68+
* @param overriddenField Field
69+
* @param parentClass PhpClass
70+
*/
71+
protected abstract void execute(
72+
final Project project,
73+
final @NotNull ProblemsHolder problemsHolder,
74+
final Field field,
75+
final Field overriddenField,
76+
final PhpClass parentClass
77+
);
78+
79+
/**
80+
* Implement this method to specify type check for the field.
81+
*
82+
* @param field Field
83+
*
84+
* @return boolean
85+
*/
86+
protected abstract boolean isTypeValid(final Field field);
87+
88+
/**
89+
* Implement this method to specify issue severity level for target inspection.
90+
*
91+
* @return IssueSeverityLevel
92+
*/
93+
protected abstract IssueSeverityLevel getSeverityLevel();
94+
}

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

Lines changed: 34 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8,80 +8,53 @@
88
import com.intellij.codeInspection.ProblemHighlightType;
99
import com.intellij.codeInspection.ProblemsHolder;
1010
import com.intellij.openapi.project.Project;
11-
import com.intellij.psi.PsiElementVisitor;
12-
import com.jetbrains.php.lang.inspections.PhpInspection;
1311
import com.jetbrains.php.lang.psi.elements.Field;
1412
import com.jetbrains.php.lang.psi.elements.PhpClass;
1513
import com.jetbrains.php.lang.psi.elements.impl.ClassConstImpl;
16-
import com.jetbrains.php.lang.psi.resolve.types.PhpTypeAnalyserVisitor;
1714
import com.magento.idea.magento2uct.inspections.UctProblemsHolder;
15+
import com.magento.idea.magento2uct.inspections.php.OverriddenFieldInspection;
16+
import com.magento.idea.magento2uct.packages.IssueSeverityLevel;
1817
import com.magento.idea.magento2uct.packages.SupportedIssue;
19-
import com.magento.idea.magento2uct.settings.UctSettingsService;
2018
import com.magento.idea.magento2uct.versioning.VersionStateManager;
2119
import org.jetbrains.annotations.NotNull;
2220

23-
public class OverridingDeprecatedConstant extends PhpInspection {
21+
public class OverridingDeprecatedConstant extends OverriddenFieldInspection {
2422

2523
@Override
26-
@SuppressWarnings("PMD.CognitiveComplexity")
27-
public @NotNull PsiElementVisitor buildVisitor(
24+
protected void execute(
25+
final Project project,
2826
final @NotNull ProblemsHolder problemsHolder,
29-
final boolean isOnTheFly
27+
final Field field,
28+
final Field overriddenField,
29+
final PhpClass parentClass
3030
) {
31-
return new PhpTypeAnalyserVisitor() {
32-
33-
@Override
34-
public void visitPhpField(final Field field) {
35-
final Project project = field.getProject();
36-
final UctSettingsService settings = UctSettingsService.getInstance(project);
37-
38-
if (!settings.isEnabled() || !settings.isIssueLevelSatisfiable(
39-
SupportedIssue.OVERRIDING_DEPRECATED_CONSTANT.getLevel())
40-
) {
41-
return;
42-
}
43-
super.visitPhpField(field);
44-
45-
if (!(field instanceof ClassConstImpl)) {
46-
return;
47-
}
48-
final PhpClass phpClass = field.getContainingClass();
31+
if (!VersionStateManager.getInstance(project).isDeprecated(overriddenField.getFQN())) {
32+
return;
33+
}
34+
35+
if (problemsHolder instanceof UctProblemsHolder) {
36+
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
37+
SupportedIssue.OVERRIDING_DEPRECATED_CONSTANT.getCode()
38+
);
39+
}
40+
problemsHolder.registerProblem(
41+
field,
42+
SupportedIssue.OVERRIDING_DEPRECATED_CONSTANT.getMessage(
43+
parentClass.getFQN()
44+
.concat("::")
45+
.concat(overriddenField.getName())
46+
),
47+
ProblemHighlightType.LIKE_DEPRECATED
48+
);
49+
}
4950

50-
if (phpClass == null) {
51-
return;
52-
}
53-
PhpClass parentClass = phpClass.getSuperClass();
54-
boolean isFound = false;
55-
final ClassConstImpl constant = (ClassConstImpl) field;
51+
@Override
52+
protected boolean isTypeValid(final Field field) {
53+
return field instanceof ClassConstImpl;
54+
}
5655

57-
while (parentClass != null && !isFound) {
58-
for (final Field ownField : parentClass.getOwnFields()) {
59-
if (ownField instanceof ClassConstImpl
60-
&& ownField.getName().equals(constant.getName())
61-
&& VersionStateManager.getInstance(project)
62-
.isDeprecated(ownField.getFQN())
63-
) {
64-
if (problemsHolder instanceof UctProblemsHolder) {
65-
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
66-
SupportedIssue.OVERRIDING_DEPRECATED_CONSTANT.getCode()
67-
);
68-
}
69-
problemsHolder.registerProblem(
70-
constant,
71-
SupportedIssue.OVERRIDING_DEPRECATED_CONSTANT.getMessage(
72-
parentClass.getFQN()
73-
.concat("::")
74-
.concat(ownField.getName())
75-
),
76-
ProblemHighlightType.LIKE_DEPRECATED
77-
);
78-
isFound = true;
79-
break;
80-
}
81-
}
82-
parentClass = parentClass.getSuperClass();
83-
}
84-
}
85-
};
56+
@Override
57+
protected IssueSeverityLevel getSeverityLevel() {
58+
return SupportedIssue.OVERRIDING_DEPRECATED_CONSTANT.getLevel();
8659
}
8760
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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.Field;
12+
import com.jetbrains.php.lang.psi.elements.PhpClass;
13+
import com.jetbrains.php.lang.psi.elements.impl.ClassConstImpl;
14+
import com.magento.idea.magento2uct.inspections.UctProblemsHolder;
15+
import com.magento.idea.magento2uct.inspections.php.OverriddenFieldInspection;
16+
import com.magento.idea.magento2uct.packages.IssueSeverityLevel;
17+
import com.magento.idea.magento2uct.packages.SupportedIssue;
18+
import com.magento.idea.magento2uct.versioning.VersionStateManager;
19+
import org.jetbrains.annotations.NotNull;
20+
21+
public class OverriddenNonExistentConstant extends OverriddenFieldInspection {
22+
23+
@Override
24+
protected void execute(
25+
final Project project,
26+
final @NotNull ProblemsHolder problemsHolder,
27+
final Field field,
28+
final Field overriddenField,
29+
final PhpClass parentClass
30+
) {
31+
if (VersionStateManager.getInstance(project).isExists(overriddenField.getFQN())) {
32+
return;
33+
}
34+
final String messageArg = parentClass
35+
.getFQN()
36+
.concat("::")
37+
.concat(overriddenField.getName());
38+
39+
final String removedIn = VersionStateManager.getInstance(project).getRemovedInVersion();
40+
final String message = removedIn.isEmpty()
41+
? SupportedIssue.OVERRIDDEN_NON_EXISTENT_CONSTANT.getMessage(messageArg)
42+
: SupportedIssue.OVERRIDDEN_NON_EXISTENT_CONSTANT.getChangelogMessage(
43+
messageArg, removedIn);
44+
45+
if (problemsHolder instanceof UctProblemsHolder) {
46+
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
47+
SupportedIssue.OVERRIDDEN_NON_EXISTENT_CONSTANT.getCode()
48+
);
49+
}
50+
problemsHolder.registerProblem(field, message, ProblemHighlightType.ERROR);
51+
}
52+
53+
@Override
54+
protected boolean isTypeValid(final Field field) {
55+
return field instanceof ClassConstImpl;
56+
}
57+
58+
@Override
59+
protected IssueSeverityLevel getSeverityLevel() {
60+
return SupportedIssue.OVERRIDDEN_NON_EXISTENT_CONSTANT.getLevel();
61+
}
62+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.magento.idea.magento2uct.inspections.php.existence.ImportingNonExistentClass;
2727
import com.magento.idea.magento2uct.inspections.php.existence.ImportingNonExistentInterface;
2828
import com.magento.idea.magento2uct.inspections.php.existence.InheritedNonExistentInterface;
29+
import com.magento.idea.magento2uct.inspections.php.existence.OverriddenNonExistentConstant;
2930
import java.lang.reflect.InvocationTargetException;
3031
import java.util.LinkedList;
3132
import java.util.List;
@@ -139,6 +140,13 @@ public enum SupportedIssue {
139140
"customCode.critical.existence.1111",
140141
ExtendedNonExistentClass.class,
141142
"customCode.critical.existence.1111.changelog"
143+
),
144+
OVERRIDDEN_NON_EXISTENT_CONSTANT(
145+
1215,
146+
IssueSeverityLevel.CRITICAL,
147+
"customCode.critical.existence.1215",
148+
OverriddenNonExistentConstant.class,
149+
"customCode.critical.existence.1215.changelog"
142150
);
143151

144152
private final int code;

0 commit comments

Comments
 (0)