Skip to content

UCT-1030: Added configuration files support #1038

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,50 @@
enabledByDefault="false"
level="WARNING"
implementationClass="com.magento.idea.magento2uct.inspections.php.api.CalledNonInterfaceMethod"/>

<localInspection language="XML" groupPath="UCT"
shortName="UsedDeprecatedTypeInConfig"
bundle="uct.bundle.inspection" key="inspection.displayName.UsedDeprecatedTypeInConfig"
groupBundle="uct.bundle.inspection" groupKey="inspection.deprecation.group.name"
enabledByDefault="false"
level="WARNING"
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedDeprecatedTypeInConfig"/>
<localInspection language="XML" groupPath="UCT"
shortName="UsedDeprecatedConstantInConfig"
bundle="uct.bundle.inspection" key="inspection.displayName.UsedDeprecatedConstantInConfig"
groupBundle="uct.bundle.inspection" groupKey="inspection.deprecation.group.name"
enabledByDefault="false"
level="WARNING"
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedDeprecatedConstantInConfig"/>
<localInspection language="XML" groupPath="UCT"
shortName="UsedDeprecatedMethodInConfig"
bundle="uct.bundle.inspection" key="inspection.displayName.UsedDeprecatedMethodInConfig"
groupBundle="uct.bundle.inspection" groupKey="inspection.deprecation.group.name"
enabledByDefault="false"
level="WARNING"
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedDeprecatedMethodInConfig"/>

<localInspection language="XML" groupPath="UCT"
shortName="UsedNonExistentTypeInConfig"
bundle="uct.bundle.inspection" key="inspection.displayName.UsedNonExistentTypeInConfig"
groupBundle="uct.bundle.inspection" groupKey="inspection.existence.group.name"
enabledByDefault="false"
level="ERROR"
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedNonExistentTypeInConfig"/>
<localInspection language="XML" groupPath="UCT"
shortName="UsedNonExistentConstantInConfig"
bundle="uct.bundle.inspection" key="inspection.displayName.UsedNonExistentConstantInConfig"
groupBundle="uct.bundle.inspection" groupKey="inspection.existence.group.name"
enabledByDefault="false"
level="ERROR"
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedNonExistentConstantInConfig"/>
<localInspection language="XML" groupPath="UCT"
shortName="UsedNonExistentMethodInConfig"
bundle="uct.bundle.inspection" key="inspection.displayName.UsedNonExistentMethodInConfig"
groupBundle="uct.bundle.inspection" groupKey="inspection.existence.group.name"
enabledByDefault="false"
level="ERROR"
implementationClass="com.magento.idea.magento2uct.inspections.xml.UsedNonExistentMethodInConfig"/>
<!-- \UCT inspection -->

<internalFileTemplate name="Magento Composer JSON"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<html>
<body>
<p>[1234] Using Magento 2 @deprecated constant: consider using Magento Open Source|Adobe Commerce constant marked as @api instead.</p>
<!-- tooltip end -->
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<html>
<body>
<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>
<!-- tooltip end -->
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<html>
<body>
<p>[1134] Using Magento 2 @deprecated type: consider using Magento Open Source|Adobe Commerce type marked as @api instead.</p>
<!-- tooltip end -->
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<html>
<body>
<p>[1214] The used constant is no longer present in the codebase.</p>
<!-- tooltip end -->
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<html>
<body>
<p>[1410] The used method is no longer present in the codebase.</p>
<!-- tooltip end -->
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<html>
<body>
<p>[1110] The used type is no longer present in the codebase.</p>
<!-- tooltip end -->
</body>
</html>
6 changes: 6 additions & 0 deletions resources/uct/bundle/inspection.properties
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ inspection.displayName.ExtendedNonApiClass=Extended non Magento 2 API class
inspection.displayName.InheritedNonApiInterface=Inherited non Magento 2 API interface
inspection.displayName.PossibleDependencyOnImplDetails=Possible dependency on implementation details
inspection.displayName.CalledNonInterfaceMethod=Called non-interface method
inspection.displayName.UsedNonExistentTypeInConfig=Used non-existent Magento 2 type in the configuration file
inspection.displayName.UsedDeprecatedTypeInConfig=Used deprecated Magento 2 type in the configuration file
inspection.displayName.UsedDeprecatedConstantInConfig=Used deprecated Magento 2 constant in the configuration file
inspection.displayName.UsedDeprecatedMethodInConfig=Used deprecated Magento 2 method in the configuration file
inspection.displayName.UsedNonExistentConstantInConfig=Used non-existent Magento 2 constant in the configuration file
inspection.displayName.UsedNonExistentMethodInConfig=Used non-existent Magento 2 method in the configuration file
customCode.warnings.deprecated.1131=[1131] Extended class ''{0}'' that is @deprecated in the ''{1}''
customCode.warnings.deprecated.1132=[1132] Imported class ''{0}'' that is @deprecated in the ''{1}''
customCode.warnings.deprecated.1134=[1134] Used class ''{0}'' that is @deprecated in the ''{1}''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.jetbrains.php.lang.psi.PhpFile;
import com.magento.idea.magento2plugin.util.magento.MagentoVersionUtil;
import com.magento.idea.magento2uct.execution.output.ReportBuilder;
import com.magento.idea.magento2uct.execution.output.Summary;
Expand Down Expand Up @@ -135,9 +134,6 @@ public void execute() {
boolean isModuleHeaderPrinted = false;

for (final PsiFile psiFile : new ModuleFilesScanner(componentData)) {
if (!(psiFile instanceof PhpFile)) {
continue;
}
final String filename = psiFile.getVirtualFile().getPath();
final UctInspectionManager inspectionManager = new UctInspectionManager(
project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.jetbrains.php.lang.psi.PhpFile;
import com.magento.idea.magento2uct.execution.scanner.data.ComponentData;
import com.magento.idea.magento2uct.packages.SupportedIssue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -53,9 +53,12 @@ private List<PsiFile> run() {
*/
private void collectFilesInDirectoryRecursively(final @NotNull PsiDirectory directory) {
for (final PsiFile file : directory.getFiles()) {
if (file instanceof PhpFile) {
files.add(file);
if (SupportedIssue.getSupportedFileTypes().stream().noneMatch(
clazz -> clazz.isInstance(file))
) {
continue;
}
files.add(file);
}

for (final PsiDirectory subDirectory : directory.getSubdirectories()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlFile;
import com.jetbrains.php.codeInsight.PhpCodeInsightUtil;
import com.jetbrains.php.lang.psi.PhpFile;
import com.jetbrains.php.lang.psi.elements.AssignmentExpression;
Expand Down Expand Up @@ -49,7 +50,9 @@ public UctInspectionManager(final @NotNull Project project) {
* @return ProblemsHolder
*/
public @Nullable UctProblemsHolder run(final PsiFile psiFile) {
if (!(psiFile instanceof PhpFile)) {
if (SupportedIssue.getSupportedFileTypes().stream().noneMatch(
clazz -> clazz.isInstance(psiFile))
) {
return null;
}
final UctProblemsHolder problemsHolder = new UctProblemsHolder(
Expand Down Expand Up @@ -78,25 +81,29 @@ public UctInspectionManager(final @NotNull Project project) {
private List<PsiElement> collectElements(final @NotNull PsiFile psiFile) {
final List<PsiElement> elements = new LinkedList<>();

final PhpClass phpClass = GetFirstClassOfFile.getInstance().execute((PhpFile) psiFile);
if (psiFile instanceof PhpFile) {
final PhpClass phpClass = GetFirstClassOfFile.getInstance().execute((PhpFile) psiFile);

if (phpClass != null) {
elements.add(phpClass);
final PhpPsiElement scopeForUseOperator = PhpCodeInsightUtil.findScopeForUseOperator(
phpClass
);
if (phpClass != null) {
elements.add(phpClass);
final PhpPsiElement scopeForUseOperator = PhpCodeInsightUtil
.findScopeForUseOperator(phpClass);

if (scopeForUseOperator != null) {
elements.addAll(PhpCodeInsightUtil.collectImports(scopeForUseOperator));
if (scopeForUseOperator != null) {
elements.addAll(PhpCodeInsightUtil.collectImports(scopeForUseOperator));
}
elements.addAll(Arrays.asList(phpClass.getOwnFields()));
}
elements.addAll(Arrays.asList(phpClass.getOwnFields()));
}
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, ClassConstantReference.class));
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, MethodReference.class));
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, AssignmentExpression.class));
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, ClassReference.class));
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, FieldReference.class));

elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, ClassConstantReference.class));
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, MethodReference.class));
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, AssignmentExpression.class));
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, ClassReference.class));
elements.addAll(PsiTreeUtil.findChildrenOfType(psiFile, FieldReference.class));
} else if (psiFile instanceof XmlFile) {
elements.add(psiFile);
}

return elements;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ public void registerProblem(final @NotNull ProblemDescriptor problemDescriptor)
// if problem has been added successfully
if (problemCount != getMyProblems().size()) {
myProblemCodes.put(problemDescriptor, issue);
issue = null;//NOPMD
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2uct.inspections.xml;

import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.XmlSuppressableInspectionTool;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlToken;
import com.intellij.psi.xml.XmlTokenType;
import com.magento.idea.magento2uct.settings.UctSettingsService;
import com.magento.idea.magento2uct.versioning.VersionStateManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

abstract class ModuleConfigFileInspection extends XmlSuppressableInspectionTool {

private static final String LAYOUT_FILE_REGEX = "\\/(layout|ui_component)\\/.*\\.xml";
private static final Pattern LAYOUT_FILE_PATTERN = Pattern.compile(LAYOUT_FILE_REGEX);

private final String[] supportedFiles = {
"di.xml",
"system.xml",
"events.xml",
"extension_attributes.xml",
"webapi.xml",
"communication.xml",
"queue_consumer.xml",
"crontab.xml",
"indexer.xml",
"mview.xml",
"product_types.xml",
"widget.xml",
"queue.xml",
"product_options.xml",
"export.xml",
"import.xml",
"analytics.xml",
"reports.xml",
"pdf.xml",
"cache.xml",
"validation.xml"
};
private ProblemsHolder problemsHolder;

@Override
public @NotNull PsiElementVisitor buildVisitor(
final @NotNull ProblemsHolder holder,
final boolean isOnTheFly
) {
problemsHolder = holder;

return super.buildVisitor(holder, isOnTheFly);
}

@Override
public @Nullable ProblemDescriptor[] checkFile(
final @NotNull PsiFile file,
final @NotNull InspectionManager manager,
final boolean isOnTheFly
) {
final Project project = file.getProject();
final UctSettingsService settings = UctSettingsService.getInstance(project);
final ProblemsHolder holder = getProblemsHolder();

if (!settings.isEnabled() || holder == null) {
return getEmptyResult();
}

if (Arrays.stream(supportedFiles).noneMatch(name -> name.equals(file.getName()))
&& !isLayoutFile(file)) {
return getEmptyResult();
}
final List<IElementType> allowedTokenTypes = new ArrayList<>();
allowedTokenTypes.add(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN);
allowedTokenTypes.add(XmlTokenType.XML_DATA_CHARACTERS);

final List<ProblemDescriptor> descriptors = new ArrayList<>();

for (final XmlToken token : PsiTreeUtil.findChildrenOfType(file, XmlToken.class)) {
if (!allowedTokenTypes.contains(token.getTokenType())) {
continue;
}
final String fqn = token.getText().trim();

if (!VersionStateManager.getInstance(project).isPresentInCodebase(fqn)) {
continue;
}
// Inspection logic.
doInspection(fqn, token, manager, holder, isOnTheFly, descriptors);
}

return descriptors.toArray(new ProblemDescriptor[0]);
}

/**
* Implement this method to specify inspection logic.
*
* @param fqn String
* @param target PsiElement
* @param manager InspectionManager
* @param holder ProblemsHolder
* @param isOnTheFly boolean
* @param descriptors List[ProblemDescriptor]
*/
protected abstract void doInspection(
final @NotNull String fqn,
final @NotNull PsiElement target,
final @NotNull InspectionManager manager,
final @NotNull ProblemsHolder holder,
final boolean isOnTheFly,
final @NotNull List<ProblemDescriptor> descriptors
);

private @Nullable ProblemsHolder getProblemsHolder() {
return problemsHolder;
}

/**
* Retrieves an empty result.
*
* @return ProblemDescriptor[]
*/
private ProblemDescriptor[] getEmptyResult() {
return new ProblemDescriptor[0];
}

private boolean isLayoutFile(final @NotNull PsiFile file) {
final VirtualFile virtualFile = file.getVirtualFile();

if (virtualFile == null) {
return false;
}

return LAYOUT_FILE_PATTERN.matcher(virtualFile.getPath()).find();
}
}
Loading