Skip to content

Commit 4765696

Browse files
authored
Merge pull request #796 from bohdan-harniuk/uct-inspection-call-non-interface-method
UCT-731: Added inspection call non-interface method
2 parents 8fc125b + ba6308c commit 4765696

File tree

7 files changed

+114
-2
lines changed

7 files changed

+114
-2
lines changed

resources/META-INF/plugin.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,13 @@
501501
enabledByDefault="false"
502502
level="WARNING"
503503
implementationClass="com.magento.idea.magento2uct.inspections.php.api.PossibleDependencyOnImplDetails"/>
504+
<localInspection language="PHP" groupPath="UCT"
505+
shortName="CalledNonInterfaceMethod"
506+
bundle="uct.bundle.inspection" key="inspection.displayName.CalledNonInterfaceMethod"
507+
groupBundle="uct.bundle.inspection" groupKey="inspection.api.group.name"
508+
enabledByDefault="false"
509+
level="WARNING"
510+
implementationClass="com.magento.idea.magento2uct.inspections.php.api.CalledNonInterfaceMethod"/>
504511
<!-- \UCT inspection -->
505512

506513
<internalFileTemplate name="Magento Composer JSON"/>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<html>
2+
<body>
3+
<p>[1449] Called non-interface method (that is present in implementation).</p>
4+
<!-- tooltip end -->
5+
<p>The purpose of this inspection is to find places where there is called a method that is not declared in the interface.</p>
6+
</body>
7+
</html>

resources/uct/bundle/inspection.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ inspection.displayName.ImplementedNonApiInterface=Implemented non Adobe Commerce
3737
inspection.displayName.ExtendedNonApiClass=Extended non Adobe Commerce API class
3838
inspection.displayName.InheritedNonApiInterface=Inherited non Adobe Commerce API interface
3939
inspection.displayName.PossibleDependencyOnImplDetails=Possible dependency on implementation details
40+
inspection.displayName.CalledNonInterfaceMethod=Called non-interface method
4041
customCode.warnings.deprecated.1131=[1131] Extended class ''{0}'' that is @deprecated in the ''{1}''
4142
customCode.warnings.deprecated.1132=[1132] Imported class ''{0}'' that is @deprecated in the ''{1}''
4243
customCode.warnings.deprecated.1134=[1134] Used class ''{0}'' that is @deprecated in the ''{1}''
@@ -72,3 +73,4 @@ customCode.errors.api.1328=[1328] Implemented interface ''{0}'' is not marked as
7273
customCode.errors.api.1121=[1121] Extended class ''{0}'' is not marked as an API
7374
customCode.errors.api.1327=[1327] Inherited interface ''{0}'' is not marked as an API
7475
customCode.errors.api.1428=[1428] Possible dependency on implementation details. Consider using the interface ''{0}''
76+
customCode.errors.api.1449=[1449] Called non-interface method. Consider using only methods declared in ''{0}''
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.magento2uct.inspections.php.api;
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.PhpIndex;
12+
import com.jetbrains.php.actions.PhpExpressionTypeProvider;
13+
import com.jetbrains.php.lang.psi.elements.Method;
14+
import com.jetbrains.php.lang.psi.elements.MethodReference;
15+
import com.jetbrains.php.lang.psi.elements.PhpClass;
16+
import com.magento.idea.magento2plugin.inspections.php.util.PhpClassImplementsInterfaceUtil;
17+
import com.magento.idea.magento2uct.inspections.UctProblemsHolder;
18+
import com.magento.idea.magento2uct.inspections.php.CallMethodInspection;
19+
import com.magento.idea.magento2uct.packages.IssueSeverityLevel;
20+
import com.magento.idea.magento2uct.packages.SupportedIssue;
21+
import java.util.Collection;
22+
import java.util.List;
23+
import java.util.stream.Collectors;
24+
import org.jetbrains.annotations.NotNull;
25+
26+
public class CalledNonInterfaceMethod extends CallMethodInspection {
27+
28+
private final PhpExpressionTypeProvider typeProvider = new PhpExpressionTypeProvider();
29+
30+
@Override
31+
protected void execute(
32+
final Project project,
33+
final @NotNull ProblemsHolder problemsHolder,
34+
final MethodReference methodReference,
35+
final Method method
36+
) {
37+
final PhpClass parentClass = method.getContainingClass();
38+
39+
if (parentClass == null) {
40+
return;
41+
}
42+
final String informationHint = typeProvider.getInformationHint(methodReference);
43+
44+
if (informationHint.isEmpty()) {
45+
return;
46+
}
47+
final Collection<PhpClass> searchResult = PhpIndex.getInstance(project)
48+
.getInterfacesByFQN(informationHint);
49+
50+
if (searchResult.isEmpty()) {
51+
return;
52+
}
53+
final PhpClass interfaceCandidate = searchResult.stream().iterator().next();
54+
55+
if (interfaceCandidate == null
56+
|| !interfaceCandidate.isInterface()
57+
|| !PhpClassImplementsInterfaceUtil.execute(interfaceCandidate, parentClass)
58+
) {
59+
return;
60+
}
61+
final Collection<Method> methodList = interfaceCandidate.getMethods();
62+
final List<String> methodNames = methodList
63+
.stream()
64+
.map(Method::getName)
65+
.collect(Collectors.toList());
66+
67+
if (methodNames.contains(method.getName())) {
68+
return;
69+
}
70+
71+
if (problemsHolder instanceof UctProblemsHolder) {
72+
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
73+
SupportedIssue.CALLED_NON_INTERFACE_METHOD.getCode()
74+
);
75+
}
76+
problemsHolder.registerProblem(
77+
methodReference,
78+
SupportedIssue.CALLED_NON_INTERFACE_METHOD.getMessage(
79+
interfaceCandidate.getFQN()
80+
),
81+
ProblemHighlightType.WARNING
82+
);
83+
}
84+
85+
@Override
86+
protected IssueSeverityLevel getSeverityLevel() {
87+
return SupportedIssue.CALLED_NON_INTERFACE_METHOD.getLevel();
88+
}
89+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.magento.idea.magento2uct.bundles.UctInspectionBundle;
1111
import com.magento.idea.magento2uct.inspections.UctProblemsHolder;
1212
import com.magento.idea.magento2uct.inspections.php.api.CalledNonApiMethod;
13+
import com.magento.idea.magento2uct.inspections.php.api.CalledNonInterfaceMethod;
1314
import com.magento.idea.magento2uct.inspections.php.api.ExtendedNonApiClass;
1415
import com.magento.idea.magento2uct.inspections.php.api.ImplementedNonApiInterface;
1516
import com.magento.idea.magento2uct.inspections.php.api.ImportedNonApiClass;
@@ -261,6 +262,12 @@ public enum SupportedIssue {
261262
IssueSeverityLevel.ERROR,
262263
"customCode.errors.api.1428",
263264
PossibleDependencyOnImplDetails.class
265+
),
266+
CALLED_NON_INTERFACE_METHOD(
267+
1449,
268+
IssueSeverityLevel.ERROR,
269+
"customCode.errors.api.1449",
270+
CalledNonInterfaceMethod.class
264271
);
265272

266273
private final int code;

src/com/magento/idea/magento2uct/versioning/indexes/data/DeprecationStateIndex.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public synchronized boolean has(final @NotNull String key) {
7272
public String getVersion(final @NotNull String fqn) {
7373
final String version = changelog.get(fqn);
7474

75-
return version == null ? "some" : version;
75+
return version == null ? "2.3.0 or before" : version;
7676
}
7777

7878
@Override

src/com/magento/idea/magento2uct/versioning/indexes/data/ExistenceStateIndex.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public synchronized boolean has(final @NotNull String fqn) {
7676
public String getVersion(final @NotNull String fqn) {
7777
final String version = changelog.get(fqn);
7878

79-
return version == null ? "some" : version;
79+
return version == null ? "2.3.0 or before" : version;
8080
}
8181

8282
/**

0 commit comments

Comments
 (0)