diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java index 70c5151212eb..70b65cc3d874 100644 --- a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXQuickfixTest.java @@ -60,6 +60,14 @@ public class JavaFXQuickfixTest extends LightCodeInsightFixtureTestCase { doTest("Create method 'void bar(ActionEvent)'", ".groovy"); } + public void testCreateControllerMethodGeneric() throws Exception { + doTest("Create method 'void onSort(SortEvent)'", ".java"); + } + + public void testCreateControllerMethodHalfRaw() throws Exception { + doTest("Create method 'void onSort(SortEvent)'", ".java"); + } + public void testCreateFieldPublicVisibility() throws Exception { doTestWithDefaultVisibility("Create field 'btn'", "CreateField", PsiModifier.PUBLIC, ".java"); } diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxEventHandlerInspectionTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxEventHandlerInspectionTest.java new file mode 100644 index 000000000000..d7548ba56ba9 --- /dev/null +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxEventHandlerInspectionTest.java @@ -0,0 +1,55 @@ +package org.jetbrains.plugins.javaFX.fxml; + +import com.intellij.openapi.application.PluginPathManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.javaFX.fxml.codeInsight.inspections.JavaFxEventHandlerInspection; + +/** + * @author Pavel.Dolgov + */ +public class JavaFxEventHandlerInspectionTest extends AbstractJavaFXTestCase { + + @Override + protected void enableInspections() { + myFixture.enableInspections(new JavaFxEventHandlerInspection()); + } + + + public void testHighlightExact() throws Exception { + doHighlightingTest(); + } + + public void testHighlightNonVoid() throws Exception { + final JavaFxEventHandlerInspection inspection = new JavaFxEventHandlerInspection(); + inspection.myDetectNonVoidReturnType = true; + myFixture.enableInspections(inspection); + doHighlightingTest(); + } + + public void testHighlightAmbiguous() throws Exception { + doHighlightingTest(); + } + + public void testHighlightSimpleGeneric() throws Exception { + doHighlightingTest(); + } + + public void testHighlightMixedGeneric() throws Exception { + doHighlightingTest(); + } + + public void testHighlightWildcard() throws Exception { + doHighlightingTest(); + } + + private void doHighlightingTest() throws Exception { + myFixture.configureByFiles(getTestName(true) + ".fxml", getTestName(false) + "Controller.java"); + myFixture.checkHighlighting(); + } + + @NotNull + @Override + protected String getTestDataPath() { + return PluginPathManager.getPluginHomePath("javaFX") + "/testData/inspections/eventHandler/"; + } +} diff --git a/plugins/javaFX/resources/inspectionDescriptions/JavaFxEventHandler.html b/plugins/javaFX/resources/inspectionDescriptions/JavaFxEventHandler.html new file mode 100644 index 000000000000..823157cb5c92 --- /dev/null +++ b/plugins/javaFX/resources/inspectionDescriptions/JavaFxEventHandler.html @@ -0,0 +1,5 @@ + + +This inspection reports event handler issues, including incompatible argument type, ambiguous event handler method, and incorrect return type. + + diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml index 8a4ae2897de2..4254ed7768e6 100644 --- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml +++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml @@ -26,6 +26,8 @@ enabledByDefault="true" level="WARNING" displayName="JavaFX redundant property values" groupName="JavaFX"/> + diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java index 07608b6e1949..74ace5e83b0d 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java @@ -820,6 +820,40 @@ public class JavaFxPsiUtil { InheritanceUtil.isInheritor(fieldType, JavaFxCommonNames.JAVAFX_COLLECTIONS_OBSERVABLE_MAP); } + public static boolean isNotFullyResolvedGeneric(@NotNull PsiClassType classType) { + final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); + final PsiClass psiClass = resolveResult.getElement(); + if (psiClass == null || psiClass instanceof PsiTypeParameter) return true; + final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(psiClass)) { + final PsiType substitute = substitutor.substitute(parameter); + if (substitute == null || substitute instanceof PsiClassType && isNotFullyResolvedGeneric((PsiClassType)substitute)) { + return true; + } + } + return false; + } + + @Nullable + public static PsiSubstitutor getTagClassSubstitutor(@NotNull XmlTag xmlTag, + @Nullable PsiClass fieldClass, + @Nullable PsiClass controllerClass) { + if (fieldClass != null && controllerClass != null) { + final String tagFieldName = xmlTag.getAttributeValue(FxmlConstants.FX_ID); + if (tagFieldName != null) { + final PsiField tagField = controllerClass.findFieldByName(tagFieldName, true); + if (tagField != null && !tagField.hasModifierProperty(PsiModifier.STATIC) && isVisibleInFxml(tagField)) { + final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(tagField.getType()); + final PsiClass resolvedClass = resolveResult.getElement(); + if (resolvedClass != null) { + return TypeConversionUtil.getClassSubstitutor(fieldClass, resolvedClass, resolveResult.getSubstitutor()); + } + } + } + } + return null; + } + private static class JavaFxControllerCachedValueProvider implements CachedValueProvider { private final Project myProject; private final PsiFile myContainingFile; diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxEventHandlerInspection.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxEventHandlerInspection.java new file mode 100644 index 000000000000..6fce1ce6d307 --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxEventHandlerInspection.java @@ -0,0 +1,219 @@ +package org.jetbrains.plugins.javaFX.fxml.codeInsight.inspections; + +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.codeInspection.XmlSuppressableInspectionTool; +import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.xml.XmlElementDescriptor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonNames; +import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory; +import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil; + +import javax.swing.*; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil.isNotFullyResolvedGeneric; + +/** + * @author Pavel.Dolgov + */ +public class JavaFxEventHandlerInspection extends XmlSuppressableInspectionTool { + public boolean myDetectNonVoidReturnType; + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new XmlElementVisitor() { + @Override + public void visitXmlFile(XmlFile file) { + if (!JavaFxFileTypeFactory.isFxml(file)) return; + super.visitXmlFile(file); + } + + @Override + public void visitXmlAttribute(XmlAttribute attribute) { + super.visitXmlAttribute(attribute); + + final PsiFile containingFile = attribute.getContainingFile(); + final PsiClass controllerClass = JavaFxPsiUtil.getControllerClass(containingFile); + if (controllerClass == null) return; + + final String valueText = attribute.getValue(); + if (valueText == null || !valueText.startsWith("#")) return; + final String eventHandlerMethodName = valueText.substring(1); + + List eventHandlerMethods = + Arrays.stream(controllerClass.findMethodsByName(eventHandlerMethodName, true)) + .filter(method -> !method.hasModifierProperty(PsiModifier.STATIC) && JavaFxPsiUtil.isVisibleInFxml(method)) + .filter(JavaFxEventHandlerInspection::hasEventArgument) + .collect(Collectors.toList()); + if (eventHandlerMethods.size() == 0) return; + if (eventHandlerMethods.size() != 1) { + holder.registerProblem(getHighlightedElement(attribute), "Ambiguous event handler name: more than one matching method found"); + } + + if (myDetectNonVoidReturnType) { + eventHandlerMethods.stream() + .map(PsiMethod::getReturnType) + .filter(returnType -> !PsiType.VOID.equals(returnType)) + .findAny() + .ifPresent(ignored -> holder.registerProblem(getHighlightedElement(attribute), "Return type of event handler should be void")); + } + + final PsiClassType eventClassType = getHandlerArgumentClassType(attribute, controllerClass); + if (eventClassType == null) return; + final boolean eventClassTypeNotFullyResolved = isNotFullyResolvedGeneric(eventClassType); + + eventHandlerMethods.stream() + .map(method -> method.getParameterList().getParameters()) + .filter(parameters -> parameters.length == 1) + .map(parameters -> parameters[0].getType()) + .forEach(argType -> { + if (argType instanceof PsiClassType) { + final boolean assignable; + if (eventClassTypeNotFullyResolved || isNotFullyResolvedGeneric((PsiClassType)argType)) { + assignable = isAssignableFromIgnoringUnresolved((PsiClassType)argType, eventClassType); + } + else { + assignable = argType.isAssignableFrom(eventClassType); + } + if (!assignable) { + holder.registerProblem(getHighlightedElement(attribute), + "Incompatible event handler argument: " + argType.getPresentableText() + + " is not assignable from " + eventClassType.getPresentableText()); + } + } + else { + holder.registerProblem(getHighlightedElement(attribute), + "Unresolved event handler argument type " + argType.getCanonicalText()); + } + }); + } + }; + } + + private static boolean isAssignableFromIgnoringUnresolved(@Nullable PsiClassType left, @Nullable PsiClassType right) { + if (left == null || right == null) return true; + final PsiClassType.ClassResolveResult leftResolveResult = left.resolveGenerics(); + final PsiClassType.ClassResolveResult rightResolveResult = right.resolveGenerics(); + + final PsiClass leftClass = leftResolveResult.getElement(); + final PsiClass rightClass = rightResolveResult.getElement(); + + if (leftClass == null || rightClass == null || leftClass instanceof PsiTypeParameter || rightClass instanceof PsiTypeParameter) { + return true; + } + if (leftClass.getManager().areElementsEquivalent(leftClass, rightClass)) { + // generic args are assignable or unresolved + if (!leftClass.hasTypeParameters()) return true; + final PsiSubstitutor leftSubstitutor = leftResolveResult.getSubstitutor(); + final PsiSubstitutor rightSubstitutor = rightResolveResult.getSubstitutor(); + final PsiTypeParameter[] typeParameters = leftClass.getTypeParameters(); + for (PsiTypeParameter typeParameter : typeParameters) { + final PsiType leftParameter = leftSubstitutor.substitute(typeParameter); + if (leftParameter == null || leftParameter instanceof PsiTypeParameter) continue; + final PsiType rightParameter = rightSubstitutor.substitute(typeParameter); + if (rightParameter == null || rightParameter instanceof PsiTypeParameter) continue; + final PsiClassType leftParameterClass = getBoundClassType(leftParameter, true); + final PsiClassType rightParameterClass = getBoundClassType(rightParameter, false); + if (!isAssignableFromIgnoringUnresolved(leftParameterClass, rightParameterClass)) { + return false; + } + } + return true; + } + else if (leftClass.isInheritor(rightClass, true)) { + // generic args are equal + final PsiType rightSubstitute = leftResolveResult.getSubstitutor().substitute(right); + return rightSubstitute.isAssignableFrom(left); + } + return false; + } + + @Nullable + private static PsiClassType getBoundClassType(PsiType psiType, boolean isSuper) { + if (psiType instanceof PsiClassType) { + return (PsiClassType)psiType; + } + if (psiType instanceof PsiWildcardType) { + PsiWildcardType wildcardType = (PsiWildcardType)psiType; + if (isSuper && wildcardType.isSuper() || !isSuper && wildcardType.isExtends()) { + final PsiType bound = wildcardType.getBound(); + if (bound instanceof PsiClassType) return (PsiClassType)bound; + } + } + return null; + } + + private static PsiElement getHighlightedElement(XmlAttribute attribute) { + final XmlAttributeValue valueElement = attribute.getValueElement(); + return valueElement != null ? valueElement : attribute; + } + + @Nullable + private static PsiClassType getHandlerArgumentClassType(@NotNull XmlAttribute attribute, PsiClass controllerClass) { + final XmlTag xmlTag = attribute.getParent(); + final XmlElementDescriptor descriptor = xmlTag.getDescriptor(); + if (descriptor == null) return null; + final PsiElement declaration = descriptor.getDeclaration(); + if (!(declaration instanceof PsiClass)) return null; + final PsiClass tagClass = (PsiClass)declaration; + + final String handlerSetterName = PropertyUtil.suggestSetterName(attribute.getName()); + final PsiMethod[] handlerSetterCandidates = tagClass.findMethodsByName(handlerSetterName, true); + if (handlerSetterCandidates.length == 0) return null; + + final Project project = attribute.getProject(); + final PsiClass javaFxEventHandlerClass = JavaPsiFacade.getInstance(project).findClass(JavaFxCommonNames.JAVAFX_EVENT_EVENT_HANDLER, + GlobalSearchScope.allScope(project)); + if (javaFxEventHandlerClass != null) { + final PsiTypeParameter[] typeParameters = javaFxEventHandlerClass.getTypeParameters(); + if (typeParameters.length == 1) { + final PsiTypeParameter javaFxEventHandlerTypeParameter = typeParameters[0]; + final PsiSubstitutor tagClassSubstitutor = JavaFxPsiUtil.getTagClassSubstitutor(xmlTag, tagClass, controllerClass); + for (PsiMethod handlerSetter : handlerSetterCandidates) { + if (handlerSetter.hasModifierProperty(PsiModifier.STATIC) || !handlerSetter.hasModifierProperty(PsiModifier.PUBLIC)) continue; + final PsiParameter[] parameters = handlerSetter.getParameterList().getParameters(); + if (parameters.length == 1) { + PsiType handlerParameterType = parameters[0].getType(); + if (tagClassSubstitutor != null) { + handlerParameterType = tagClassSubstitutor.substitute(handlerParameterType); + } + if (handlerParameterType instanceof PsiClassType && + InheritanceUtil.isInheritorOrSelf(((PsiClassType)handlerParameterType).resolve(), javaFxEventHandlerClass, true)) { + final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)handlerParameterType).resolveGenerics(); + final PsiType eventType = resolveResult.getSubstitutor().substitute(javaFxEventHandlerTypeParameter); + PsiClassType eventClassType = getBoundClassType(eventType, true); + if (eventClassType != null) return eventClassType; + } + } + } + } + } + return null; + } + + private static boolean hasEventArgument(@NotNull PsiMethod method) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + return parameters.length == 0 || + parameters.length == 1 && InheritanceUtil.isInheritor(parameters[0].getType(), JavaFxCommonNames.JAVAFX_EVENT); + } + + @Nullable + @Override + public JComponent createOptionsPanel() { + return new SingleCheckboxOptionsPanel("Detect event handler method having non-void return type", this, "myDetectNonVoidReturnType"); + } +} diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java index 12bda8520d26..387dde67d20a 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java @@ -26,6 +26,7 @@ import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlTag; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -71,7 +72,8 @@ public class JavaFxEventHandlerReference extends PsiReferenceBase new JavaFxEventHandlerReference(xmlAttributeValue, currentTagClass, handlerMethod, controllerClass)) + .toArray(PsiReference.ARRAY_FACTORY::create); + + if (references.length == 1) { + return references; } - if (handlerMethod == null) { + if (references.length > 1) { + return new PsiReference[]{new PsiMultiReference(references, xmlAttributeValue)}; + } + + if (references.length == 0) { final XmlTag rootTag = ((XmlFile)xmlAttributeValue.getContainingFile()).getRootTag(); if (rootTag == null || FxmlConstants.FX_ROOT.equals(rootTag.getName())) { return PsiReference.EMPTY_ARRAY; } } - return new PsiReference[]{new JavaFxEventHandlerReference(xmlAttributeValue, (PsiClass)currentTagClass, handlerMethod, controllerClass)}; + return new PsiReference[]{new JavaFxEventHandlerReference(xmlAttributeValue, currentTagClass, null, controllerClass)}; } } diff --git a/plugins/javaFX/testData/inspections/eventHandler/HighlightAmbiguousController.java b/plugins/javaFX/testData/inspections/eventHandler/HighlightAmbiguousController.java new file mode 100644 index 000000000000..0a10fd7fbe4c --- /dev/null +++ b/plugins/javaFX/testData/inspections/eventHandler/HighlightAmbiguousController.java @@ -0,0 +1,12 @@ +import javafx.event.ActionEvent; +import javafx.event.Event; + +public class HighlightAmbiguousController { + public void onArgType(ActionEvent e) {} + public void onArgType(Event e) {} + public void onNoArg(ActionEvent e) {} + public void onNoArg() {} + public void onNotEvent(Event e) {} + public void onNotEvent(String notEvent) {} + public void onNotEvent(int notEvent) {} +} diff --git a/plugins/javaFX/testData/inspections/eventHandler/HighlightExactController.java b/plugins/javaFX/testData/inspections/eventHandler/HighlightExactController.java new file mode 100644 index 000000000000..6c68372c9569 --- /dev/null +++ b/plugins/javaFX/testData/inspections/eventHandler/HighlightExactController.java @@ -0,0 +1,13 @@ +import javafx.event.ActionEvent; +import javafx.event.Event; +import javafx.scene.input.ScrollEvent; + +public class HighlightExactController { + public void onSameArg(ActionEvent e) {} + public void onSuperArg(Event e) {} + public void onNoArg() {} + public String onSameArgNotVoid(ActionEvent e) {return "";} + public Boolean onSuperArgNotVoid(Event e) {return false;} + public int onNoArgNotVoid() {return 1;} + public void onIncompatible(ScrollEvent e) {} +} diff --git a/plugins/javaFX/testData/inspections/eventHandler/HighlightMixedGenericController.java b/plugins/javaFX/testData/inspections/eventHandler/HighlightMixedGenericController.java new file mode 100644 index 000000000000..32c5e07d3f3c --- /dev/null +++ b/plugins/javaFX/testData/inspections/eventHandler/HighlightMixedGenericController.java @@ -0,0 +1,37 @@ +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.util.Pair; +import java.util.Map; + +public class HighlightMixedGenericController { + @FXML TableView> specificTable; + @FXML TableView> specificTableHalfRawArg; + @FXML TableView> specificTableIncompatibleArg; + @FXML TableView> specificTableIncompatibleHalfRawArg; + + @FXML TableView halfRawTable; + @FXML TableView halfRawTableHalfRawArg; + @FXML TableView halfRawTableIncompatibleArg; + @FXML TableView halfRawTableIncompatibleHalfRawArg; + + @FXML TableView rawTable; + @FXML TableView rawTableHalfRawArg; + @FXML TableView rawTableIncompatibleArg; + @FXML TableView rawTableIncompatibleHalfRawArg; + + public void onSort(SortEvent>> e) {} + public void onScrollTo(ScrollToEvent e) {} + public void onScrollToColumn(ScrollToEvent, ?>> e) {} + + public void onSortHalfRawArg(SortEvent e) {} + public void onScrollToHalfRawArg(ScrollToEvent e) {} + public void onScrollToColumnHalfRawArg(ScrollToEvent e) {} + + public void onSortIncompatibleArg(SortEvent>> e) {} + public void onScrollToIncompatibleArg(ScrollToEvent e) {} + public void onScrollToColumnIncompatibleArg(ScrollToEvent, ?>> e) {} + + public void onSortIncompatibleHalfRawArg(SortEvent> e) {} + public void onScrollToIncompatibleHalfRawArg(ScrollToEvent e) {} + public void onScrollToColumnIncompatibleHalfRawArg(ScrollToEvent> e) {} +} diff --git a/plugins/javaFX/testData/inspections/eventHandler/HighlightNonVoidController.java b/plugins/javaFX/testData/inspections/eventHandler/HighlightNonVoidController.java new file mode 100644 index 000000000000..d14be2642bd5 --- /dev/null +++ b/plugins/javaFX/testData/inspections/eventHandler/HighlightNonVoidController.java @@ -0,0 +1,8 @@ +import javafx.event.ActionEvent; +import javafx.event.Event; + +public class HighlightNonVoidController { + public String onSameArgNotVoid(ActionEvent e) {return "";} + public Boolean onSuperArgNotVoid(Event e) {return false;} + public int onNoArgNotVoid() {return 1;} +} diff --git a/plugins/javaFX/testData/inspections/eventHandler/HighlightSimpleGenericController.java b/plugins/javaFX/testData/inspections/eventHandler/HighlightSimpleGenericController.java new file mode 100644 index 000000000000..de82494ff233 --- /dev/null +++ b/plugins/javaFX/testData/inspections/eventHandler/HighlightSimpleGenericController.java @@ -0,0 +1,10 @@ +import javafx.fxml.FXML; +import javafx.scene.control.*; + +public class HighlightSimpleGenericController { + @FXML ListView list; + + public void onEditStart(ListView.EditEvent e) {} + public void onEditCancel(ListView.EditEvent e) {} + public void onEditCommit(ListView.EditEvent e) {} +} diff --git a/plugins/javaFX/testData/inspections/eventHandler/HighlightWildcardController.java b/plugins/javaFX/testData/inspections/eventHandler/HighlightWildcardController.java new file mode 100644 index 000000000000..4bb1b0f45474 --- /dev/null +++ b/plugins/javaFX/testData/inspections/eventHandler/HighlightWildcardController.java @@ -0,0 +1,13 @@ +import javafx.event.Event; +import javafx.fxml.FXML; +import javafx.scene.control.SortEvent; +import javafx.scene.input.MouseDragEvent; +import javafx.scene.input.MouseEvent; + +public class HighlightWildcardController { + @FXML private void onSameArg(MouseEvent e) {} + @FXML private void onSuperArg(Event e) {} + @FXML private void onNoArg() {} + @FXML private void onNotSuper(MouseDragEvent e) {} + @FXML private void onNotRelated(SortEvent e) {} +} diff --git a/plugins/javaFX/testData/inspections/eventHandler/highlightAmbiguous.fxml b/plugins/javaFX/testData/inspections/eventHandler/highlightAmbiguous.fxml new file mode 100644 index 000000000000..56b8dab341dc --- /dev/null +++ b/plugins/javaFX/testData/inspections/eventHandler/highlightAmbiguous.fxml @@ -0,0 +1,7 @@ + + + +