Skip to content

Commit 8d0b7d8

Browse files
authored
Merge pull request #778 from bohdan-harniuk/uct-inspection-imported-non-api-class
UCT-722: Inspection imported non api class
2 parents 261ec80 + ac4f828 commit 8d0b7d8

File tree

10 files changed

+168
-26
lines changed

10 files changed

+168
-26
lines changed

resources/META-INF/plugin.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,13 @@
403403
enabledByDefault="false"
404404
level="ERROR"
405405
implementationClass="com.magento.idea.magento2uct.inspections.php.existence.UsedNonExistentType"/>
406+
<localInspection language="PHP" groupPath="UCT"
407+
shortName="ImportedNonApiClass"
408+
bundle="uct.bundle.inspection" key="inspection.displayName.ImportedNonApiClass"
409+
groupBundle="uct.bundle.inspection" groupKey="inspection.api.group.name"
410+
enabledByDefault="false"
411+
level="WARNING"
412+
implementationClass="com.magento.idea.magento2uct.inspections.php.api.ImportedNonApiClass"/>
406413
<!-- \UCT inspection -->
407414

408415
<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>[1122] The imported class is not marked as an API.</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
@@ -1,5 +1,6 @@
11
inspection.deprecation.group.name=Deprecation
22
inspection.existence.group.name=Existence
3+
inspection.api.group.name=API
34
inspection.issues.description.link=Check https://devdocs.magento.com/upgrade-compatibility-tool/errors.html for a detailed list of Upgrade Compatibility Tool errors.
45
inspection.displayName.ExtendingDeprecatedClass=Extending from @deprecated class
56
inspection.displayName.ImportingDeprecatedClass=Importing @deprecated class
@@ -22,6 +23,7 @@ inspection.displayName.OverriddenNonExistentConstant=Overridden non-existent Ado
2223
inspection.displayName.OverriddenNonExistentProperty=Overridden non-existent Adobe Commerce property
2324
inspection.displayName.CalledNonExistentMethod=Call non-existent Adobe Commerce method
2425
inspection.displayName.UsedNonExistentType=Used non-existent Adobe Commerce type
26+
inspection.displayName.ImportedNonApiClass=Imported non Adobe Commerce API class
2527
customCode.warnings.deprecated.1131=[1131] Extending from @deprecated class ''{0}''
2628
customCode.warnings.deprecated.1132=[1132] Importing @deprecated class ''{0}''
2729
customCode.warnings.deprecated.1134=[1134] Using @deprecated class ''{0}''
@@ -43,3 +45,4 @@ customCode.critical.existence.1215=[1215] Overridden constant ''{0}'' that is re
4345
customCode.critical.existence.1515=[1515] Overridden property ''{0}'' that is removed in the ''{1}''
4446
customCode.critical.existence.1410=[1410] Called method ''{0}'' that is removed in the ''{1}''
4547
customCode.critical.existence.1110=[1110] Used type ''{0}'' that is removed in the ''{1}''
48+
customCode.critical.api.1122=[1122] Imported class ''{0}'' is not marked as an API
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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.lang.psi.elements.PhpUse;
12+
import com.magento.idea.magento2uct.inspections.UctProblemsHolder;
13+
import com.magento.idea.magento2uct.inspections.php.ImportInspection;
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 ImportedNonApiClass extends ImportInspection {
20+
21+
@Override
22+
protected void execute(
23+
final Project project,
24+
final @NotNull ProblemsHolder problemsHolder,
25+
final PhpUse use,
26+
final boolean isInterface
27+
) {
28+
if (isInterface || VersionStateManager.getInstance(project).isApi(use.getFQN())) {
29+
return;
30+
}
31+
final String message = SupportedIssue.IMPORTED_NON_API_CLASS.getMessage(use.getFQN());
32+
33+
if (problemsHolder instanceof UctProblemsHolder) {
34+
((UctProblemsHolder) problemsHolder).setReservedErrorCode(
35+
SupportedIssue.IMPORTED_NON_API_CLASS.getCode()
36+
);
37+
}
38+
problemsHolder.registerProblem(use, message, ProblemHighlightType.WARNING);
39+
}
40+
41+
@Override
42+
protected IssueSeverityLevel getSeverityLevel() {
43+
return SupportedIssue.IMPORTED_NON_API_CLASS.getLevel();
44+
}
45+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.intellij.psi.PsiElementVisitor;
1010
import com.magento.idea.magento2uct.bundles.UctInspectionBundle;
1111
import com.magento.idea.magento2uct.inspections.UctProblemsHolder;
12+
import com.magento.idea.magento2uct.inspections.php.api.ImportedNonApiClass;
1213
import com.magento.idea.magento2uct.inspections.php.deprecation.CallingDeprecatedMethod;
1314
import com.magento.idea.magento2uct.inspections.php.deprecation.ExtendingDeprecatedClass;
1415
import com.magento.idea.magento2uct.inspections.php.deprecation.ImplementedDeprecatedInterface;
@@ -35,6 +36,7 @@
3536
import java.util.List;
3637
import org.jetbrains.annotations.Nullable;
3738

39+
@SuppressWarnings("PMD.ExcessiveImports")
3840
public enum SupportedIssue {
3941

4042
EXTENDING_DEPRECATED_CLASS(
@@ -162,6 +164,12 @@ public enum SupportedIssue {
162164
IssueSeverityLevel.CRITICAL,
163165
"customCode.critical.existence.1110",
164166
UsedNonExistentType.class
167+
),
168+
IMPORTED_NON_API_CLASS(
169+
1122,
170+
IssueSeverityLevel.ERROR,
171+
"customCode.critical.api.1122",
172+
ImportedNonApiClass.class
165173
);
166174

167175
private final int code;

src/com/magento/idea/magento2uct/versioning/VersionStateManager.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.intellij.openapi.project.Project;
99
import com.magento.idea.magento2uct.packages.SupportedVersion;
1010
import com.magento.idea.magento2uct.settings.UctSettingsService;
11+
import com.magento.idea.magento2uct.versioning.indexes.data.ApiCoverageStateIndex;
1112
import com.magento.idea.magento2uct.versioning.indexes.data.DeprecationStateIndex;
1213
import com.magento.idea.magento2uct.versioning.indexes.data.ExistenceStateIndex;
1314
import com.magento.idea.magento2uct.versioning.indexes.data.VersionStateIndex;
@@ -20,6 +21,7 @@ public final class VersionStateManager {
2021
private static VersionStateManager instance;
2122
private final DeprecationStateIndex deprecationStateIndex;
2223
private final ExistenceStateIndex existenceStateIndex;
24+
private final ApiCoverageStateIndex apiCoverageStateIndex;
2325
private final Boolean isSetIgnoreFlag;
2426
private final SupportedVersion currentVersion;
2527
private final SupportedVersion targetVersion;
@@ -81,6 +83,17 @@ public String getRemovedInVersion(final @NotNull String fqn) {
8183
return existenceStateIndex.getVersion(fqn);
8284
}
8385

86+
/**
87+
* Check if specified FQN is marked as API.
88+
*
89+
* @param fqn String
90+
*
91+
* @return boolean
92+
*/
93+
public boolean isApi(final @NotNull String fqn) {
94+
return apiCoverageStateIndex.has(fqn);
95+
}
96+
8497
/**
8598
* Version state manager constructor.
8699
*/
@@ -96,6 +109,9 @@ private VersionStateManager(final @NotNull Project project) {
96109

97110
existenceStateIndex = new ExistenceStateIndex();
98111
compute(existenceStateIndex);
112+
113+
apiCoverageStateIndex = new ApiCoverageStateIndex(existenceStateIndex.getAllData());
114+
compute(apiCoverageStateIndex);
99115
}
100116

101117
/**

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

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,29 @@ public class ApiCoverageStateIndex implements VersionStateIndex {
2525

2626
private static final String RESOURCE_DIR = "api";
2727

28-
private final Map<String, Map<String, Boolean>> data;
29-
private final Map<String, String> changelog = new HashMap<>();//NOPMD
28+
private final Map<String, Map<String, Boolean>> versioningData;
29+
private final Map<String, Boolean> targetVersionData;
30+
private final Map<String, Boolean> codebaseSet;
3031
private String projectBasePath;
31-
private String version;//NOPMD
3232

33+
/**
34+
* Api coverage state index constructor.
35+
*/
3336
public ApiCoverageStateIndex() {
34-
data = new LinkedHashMap<>();
37+
this(new HashMap<>());
38+
}
39+
40+
/**
41+
* Api coverage state index constructor.
42+
*
43+
* @param existenceVersioningData Map
44+
*/
45+
public ApiCoverageStateIndex(final Map<String, Map<String, Boolean>> existenceVersioningData) {
46+
versioningData = new LinkedHashMap<>();
47+
targetVersionData = new HashMap<>();
48+
codebaseSet = new HashMap<>(
49+
VersioningDataOperationsUtil.unionVersionData(existenceVersioningData)
50+
);
3551
}
3652

3753
/**
@@ -44,12 +60,21 @@ public void setProjectBasePath(final @NotNull String projectBasePath) {
4460
}
4561

4662
/**
47-
* Get version state after lookup.
63+
* Check if the specified FQN exists in the existence index.
64+
*
65+
* @param fqn String
4866
*
49-
* @return String
67+
* @return boolean
5068
*/
51-
public String getVersion() {
52-
return version;
69+
@SuppressWarnings("PMD.AvoidSynchronizedAtMethodLevel")
70+
public synchronized boolean has(final @NotNull String fqn) {
71+
groupLoadedData();
72+
73+
if (targetVersionData.containsKey(fqn)) {
74+
return true;
75+
}
76+
77+
return !codebaseSet.containsKey(fqn);
5378
}
5479

5580
/**
@@ -58,16 +83,9 @@ public String getVersion() {
5883
* @return Map[String, Boolean]
5984
*/
6085
public Map<String, Boolean> getIndexData() {
61-
final Pair<Map<String, Boolean>, Map<String, String>> gatheredData =
62-
VersioningDataOperationsUtil.unionVersionDataWithChangelog(
63-
data,
64-
new ArrayList<>(Collections.singletonList(
65-
SupportedVersion.V230.getVersion()
66-
)),
67-
true
68-
);
86+
groupLoadedData();
6987

70-
return gatheredData.getFirst();
88+
return targetVersionData;
7189
}
7290

7391
@Override
@@ -139,7 +157,24 @@ private void putIndexData(
139157
final Map<String, Boolean> indexData
140158
) {
141159
if (indexData != null) {
142-
data.put(version, indexData);
160+
versioningData.put(version, indexData);
161+
}
162+
}
163+
164+
/**
165+
* Group data according to purpose.
166+
*/
167+
private void groupLoadedData() {
168+
if (targetVersionData.isEmpty() && !versioningData.isEmpty()) {
169+
final Pair<Map<String, Boolean>, Map<String, String>> gatheredData =
170+
VersioningDataOperationsUtil.unionVersionDataWithChangelog(
171+
versioningData,
172+
new ArrayList<>(Collections.singletonList(
173+
SupportedVersion.V230.getVersion()
174+
)),
175+
true
176+
);
177+
targetVersionData.putAll(gatheredData.getFirst());
143178
}
144179
}
145180
}

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import com.magento.idea.magento2uct.versioning.indexes.storage.FileLoader;
1212
import com.magento.idea.magento2uct.versioning.indexes.storage.IndexLoader;
1313
import com.magento.idea.magento2uct.versioning.indexes.storage.ResourceLoader;
14+
import com.magento.idea.magento2uct.versioning.processors.util.VersioningDataOperationsUtil;
1415
import java.io.IOException;
15-
import java.util.HashMap;
1616
import java.util.LinkedHashMap;
1717
import java.util.List;
1818
import java.util.Map;
@@ -92,13 +92,7 @@ public void loadFromFile(final @NotNull List<SupportedVersion> versions) {
9292
* @return Map[String, Boolean]
9393
*/
9494
public Map<String, Boolean> getIndexData() {
95-
final Map<String, Boolean> data = new HashMap<>();
96-
97-
for (final Map.Entry<String, Map<String, Boolean>> vData : versioningData.entrySet()) {
98-
data.putAll(vData.getValue());
99-
}
100-
101-
return data;
95+
return VersioningDataOperationsUtil.unionVersionData(versioningData);
10296
}
10397

10498
/**

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ public String getVersion(final @NotNull String fqn) {
7979
return version == null ? "some" : version;
8080
}
8181

82+
/**
83+
* Get versioning data.
84+
*
85+
* @return Map
86+
*/
87+
public Map<String, Map<String, Boolean>> getAllData() {
88+
return versioningData;
89+
}
90+
8291
/**
8392
* Get deprecation index data.
8493
*

src/com/magento/idea/magento2uct/versioning/processors/util/VersioningDataOperationsUtil.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,23 @@ public static Pair<Map<String, Boolean>, Map<String, String>> unionVersionDataWi
115115

116116
return new Pair<>(new HashMap<>(filteredUnion), new HashMap<>(changelog));
117117
}
118+
119+
/**
120+
* Union versioning data into single set.
121+
*
122+
* @param versioningData Map
123+
*
124+
* @return Map[String, Boolean]
125+
*/
126+
public static Map<String, Boolean> unionVersionData(
127+
final Map<String, Map<String, Boolean>> versioningData
128+
) {
129+
final Map<String, Boolean> union = new HashMap<>();
130+
131+
for (final Map.Entry<String, Map<String, Boolean>> vData : versioningData.entrySet()) {
132+
union.putAll(vData.getValue());
133+
}
134+
135+
return union;
136+
}
118137
}

0 commit comments

Comments
 (0)