diff --git a/src/main/java/io/github/tandemdude/hklbsupport/CommandParameterInspector.java b/src/main/java/io/github/tandemdude/hklbsupport/CommandParameterTypeInspector.java similarity index 75% rename from src/main/java/io/github/tandemdude/hklbsupport/CommandParameterInspector.java rename to src/main/java/io/github/tandemdude/hklbsupport/CommandParameterTypeInspector.java index 249bf8b..22154fd 100644 --- a/src/main/java/io/github/tandemdude/hklbsupport/CommandParameterInspector.java +++ b/src/main/java/io/github/tandemdude/hklbsupport/CommandParameterTypeInspector.java @@ -12,30 +12,24 @@ import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyKeywordArgument; -import com.jetbrains.python.psi.types.PyCollectionType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.PyTypeChecker; import com.jetbrains.python.psi.types.PyTypeParser; import com.jetbrains.python.psi.types.TypeEvalContext; import io.github.tandemdude.hklbsupport.utils.Utils; +import org.jetbrains.annotations.NotNull; + import java.util.Arrays; -import java.util.Objects; +import java.util.Map; import java.util.stream.Collectors; -import org.jetbrains.annotations.NotNull; -/** - * Local inspection provider allowing problem reporting within Lightbulb command metaclass parameters. - */ -public class CommandParameterInspector extends PyInspection { +public class CommandParameterTypeInspector extends PyInspection { @Override public @NotNull PsiElementVisitor buildVisitor( @NotNull ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) { - return new Visitor(holder, PyInspectionVisitor.getContext(session)); + return new CommandRequiredParametersInspector.Visitor(holder, PyInspectionVisitor.getContext(session)); } - /** - * Visitor that checks for the presence of problems within Lightbulb command definitions. - */ static final class Visitor extends PyInspectionVisitor { Visitor(@NotNull ProblemsHolder holder, @NotNull TypeEvalContext context) { super(holder, context); @@ -63,6 +57,19 @@ void registerProblemIfIncorrectType(PyExpression at, PyType expected, PyType act ProblemHighlightType.WARNING); } + void checkParamTypes(@NotNull PyClass node, Map existingParams, Map actualParams) { + actualParams.forEach((name, type) -> { + if (!existingParams.containsKey(name)) { + return; + } + + var expectedType = + PyTypeParser.parse(node, type, myTypeEvalContext).getType(); + var actualType = myTypeEvalContext.getType(existingParams.get(name)); + registerProblemIfIncorrectType(existingParams.get(name), expectedType, actualType); + }); + } + @Override public void visitPyClass(@NotNull PyClass node) { var module = ModuleUtilCore.findModuleForFile(node.getContainingFile()); @@ -98,30 +105,8 @@ public void visitPyClass(@NotNull PyClass node) { var optionalParams = lbData.paramData().get(lbSuperclass.getQualifiedName()).optional(); - requiredParams.forEach((name, type) -> { - if (!existingParameters.containsKey(name)) { - registerProblem( - node.getSuperClassExpressionList(), - "Command missing required parameter '" + name + "'", - ProblemHighlightType.GENERIC_ERROR); - return; - } - - var expectedType = - PyTypeParser.parse(node, type, myTypeEvalContext).getType(); - var actualType = myTypeEvalContext.getType(existingParameters.get(name)); - registerProblemIfIncorrectType(existingParameters.get(name), expectedType, actualType); - }); - optionalParams.forEach((name, type) -> { - if (!existingParameters.containsKey(name)) { - return; - } - - var expectedType = - PyTypeParser.parse(node, type, myTypeEvalContext).getType(); - var actualType = myTypeEvalContext.getType(existingParameters.get(name)); - registerProblemIfIncorrectType(existingParameters.get(name), expectedType, actualType); - }); + checkParamTypes(node, existingParameters, requiredParams); + checkParamTypes(node, existingParameters, optionalParams); } } } diff --git a/src/main/java/io/github/tandemdude/hklbsupport/CommandRequiredParametersInspector.java b/src/main/java/io/github/tandemdude/hklbsupport/CommandRequiredParametersInspector.java new file mode 100644 index 0000000..1ebba4a --- /dev/null +++ b/src/main/java/io/github/tandemdude/hklbsupport/CommandRequiredParametersInspector.java @@ -0,0 +1,84 @@ +package io.github.tandemdude.hklbsupport; + +import com.intellij.codeInspection.LocalInspectionToolSession; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiElementVisitor; +import com.jetbrains.python.documentation.PythonDocumentationProvider; +import com.jetbrains.python.inspections.PyInspection; +import com.jetbrains.python.inspections.PyInspectionVisitor; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyExpression; +import com.jetbrains.python.psi.PyKeywordArgument; +import com.jetbrains.python.psi.types.PyType; +import com.jetbrains.python.psi.types.PyTypeChecker; +import com.jetbrains.python.psi.types.PyTypeParser; +import com.jetbrains.python.psi.types.TypeEvalContext; +import io.github.tandemdude.hklbsupport.utils.Utils; +import java.util.Arrays; +import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; + +/** + * Local inspection provider allowing problem reporting within Lightbulb command metaclass parameters. + */ +public class CommandRequiredParametersInspector extends PyInspection { + @Override + public @NotNull PsiElementVisitor buildVisitor( + @NotNull ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) { + return new Visitor(holder, PyInspectionVisitor.getContext(session)); + } + + /** + * Visitor that checks for the presence of problems within Lightbulb command definitions. + */ + static final class Visitor extends PyInspectionVisitor { + Visitor(@NotNull ProblemsHolder holder, @NotNull TypeEvalContext context) { + super(holder, context); + } + + @Override + public void visitPyClass(@NotNull PyClass node) { + var module = ModuleUtilCore.findModuleForFile(node.getContainingFile()); + if (module == null) { + return; + } + + var service = module.getProject().getService(CommandParameterCompletionLoader.class); + if (service == null) { + return; + } + + var lbData = service.getLightbulbData(module); + if (lbData == null) { + return; + } + + var lbSuperclass = Utils.getLightbulbSuperclass(myTypeEvalContext, node, lbData); + if (lbSuperclass == null) { + return; + } + + var existingParameters = Arrays.stream(node.getSuperClassExpressions()) + .filter(expr -> expr instanceof PyKeywordArgument) + // I had a null pointer exception from this previously so probably good to just make sure + .filter(expr -> expr.getName() != null) + .map(expr -> Pair.create( + ((PyKeywordArgument) expr).getKeyword(), ((PyKeywordArgument) expr).getValueExpression())) + .collect(Collectors.toMap(p -> p.getFirst(), p -> p.getSecond())); + + var requiredParams = + lbData.paramData().get(lbSuperclass.getQualifiedName()).required(); + requiredParams.forEach((name, type) -> { + if (!existingParameters.containsKey(name)) { + registerProblem( + node.getSuperClassExpressionList(), + "Command missing required parameter '" + name + "'", + ProblemHighlightType.GENERIC_ERROR); + } + }); + } + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 0e366c3..e9a72c3 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -33,17 +33,27 @@ + + + - - + + diff --git a/src/main/resources/inspectionDescriptions/CommandParameterInspector.html b/src/main/resources/inspectionDescriptions/CommandParameterInspector.html deleted file mode 100644 index 9ea62b3..0000000 --- a/src/main/resources/inspectionDescriptions/CommandParameterInspector.html +++ /dev/null @@ -1,5 +0,0 @@ - - -Reports missing required parameters and parameter type mismatch from Lightbulb command definitions. - - \ No newline at end of file diff --git a/src/main/resources/inspectionDescriptions/CommandParameterTypeInspector.html b/src/main/resources/inspectionDescriptions/CommandParameterTypeInspector.html new file mode 100644 index 0000000..73cac0f --- /dev/null +++ b/src/main/resources/inspectionDescriptions/CommandParameterTypeInspector.html @@ -0,0 +1,5 @@ + + +Reports items of incorrect type being passed to Lightbulb command definition parameters. + + diff --git a/src/main/resources/inspectionDescriptions/CommandRequiredParametersInspector.html b/src/main/resources/inspectionDescriptions/CommandRequiredParametersInspector.html new file mode 100644 index 0000000..f64b989 --- /dev/null +++ b/src/main/resources/inspectionDescriptions/CommandRequiredParametersInspector.html @@ -0,0 +1,5 @@ + + +Reports missing required parameters from Lightbulb command definitions. + + \ No newline at end of file