mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
javafx: make field ref unresolvable when controller is set in .fxml; add create field quick fix (IDEA-103198)
(cherry picked from commit b16a973deb71e6d063f0e763cd4e15b6d7983a2f)
This commit is contained in:
+11
-3
@@ -66,8 +66,6 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
|
||||
}
|
||||
while (parentClass instanceof PsiAnonymousClass);
|
||||
|
||||
final PsiFile targetFile = targetClass.getContainingFile();
|
||||
|
||||
ExpectedTypeInfo[] expectedTypes = CreateFromUsageUtils.guessExpectedTypes(myReferenceExpression, false);
|
||||
|
||||
String fieldName = myReferenceExpression.getReferenceName();
|
||||
@@ -94,10 +92,20 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
|
||||
|
||||
setupVisibility(parentClass, targetClass, field.getModifierList());
|
||||
|
||||
createFieldFromUsageTemplate(targetClass, project, expectedTypes, field, createConstantField(), myReferenceExpression);
|
||||
}
|
||||
|
||||
public static void createFieldFromUsageTemplate(final PsiClass targetClass,
|
||||
final Project project,
|
||||
final ExpectedTypeInfo[] expectedTypes,
|
||||
final PsiField field,
|
||||
final boolean createConstantField,
|
||||
final PsiElement context) {
|
||||
final PsiFile targetFile = targetClass.getContainingFile();
|
||||
final Editor newEditor = positionCursor(project, targetFile, field);
|
||||
if (newEditor == null) return;
|
||||
Template template =
|
||||
CreateFieldFromUsageHelper.setupTemplate(field, expectedTypes, targetClass, newEditor, myReferenceExpression, createConstantField());
|
||||
CreateFieldFromUsageHelper.setupTemplate(field, expectedTypes, targetClass, newEditor, context, createConstantField);
|
||||
|
||||
startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
|
||||
@Override
|
||||
|
||||
+4
@@ -40,6 +40,10 @@ public class JavaFXQuickfixTest extends DaemonAnalyzerTestCase {
|
||||
doTest("Create Method 'void bar(ActionEvent)'", true);
|
||||
}
|
||||
|
||||
public void testCreateField() throws Exception {
|
||||
doTest("Create Field 'btn'", true);
|
||||
}
|
||||
|
||||
private void doTest(final String actionName) throws Exception {
|
||||
doTest(actionName, false);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<xml.schemaProvider implementation="org.jetbrains.plugins.javaFX.fxml.JavaFXSchemaHandler"/>
|
||||
<psi.referenceContributor implementation="org.jetbrains.plugins.javaFX.fxml.refs.FxmlReferencesContributor"/>
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxEventHandlerReference$JavaFxUnresolvedReferenceHandlerQuickfixProvider"/>
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxFieldIdReferenceProvider$JavaFxUnresolvedReferenceHandlerQuickfixProvider"/>
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxTagNameReference$JavaFxUnresolvedTagRefsProvider"/>
|
||||
<multiHostInjector implementation="org.jetbrains.plugins.javaFX.fxml.ScriptLanguageInjector"/>
|
||||
<annotator language="XML" implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxAnnotator"/>
|
||||
|
||||
+114
-5
@@ -15,28 +15,48 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.javaFX.fxml.refs;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfoImpl;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFieldFromUsageFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFieldFromUsageHelper;
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
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.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.xml.XmlElementDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
|
||||
import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxClassBackedElementDescriptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 1/17/13
|
||||
*/
|
||||
* User: anna
|
||||
* Date: 1/17/13
|
||||
*/
|
||||
class JavaFxFieldIdReferenceProvider extends JavaFxControllerBasedReferenceProvider {
|
||||
@Override
|
||||
protected PsiReference[] getReferencesByElement(@NotNull final PsiClass aClass,
|
||||
final XmlAttributeValue xmlAttributeValue,
|
||||
ProcessingContext context) {
|
||||
final PsiField field = aClass.findFieldByName(xmlAttributeValue.getValue(), false);
|
||||
return new PsiReference[] {new JavaFxControllerFieldRef(xmlAttributeValue, field, aClass)};
|
||||
return new PsiReference[]{new JavaFxControllerFieldRef(xmlAttributeValue, field, aClass)};
|
||||
}
|
||||
|
||||
public static class JavaFxControllerFieldRef extends PsiReferenceBase<XmlAttributeValue> {
|
||||
@@ -54,7 +74,19 @@ class JavaFxFieldIdReferenceProvider extends JavaFxControllerBasedReferenceProvi
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
return myField != null ? myField : myXmlAttributeValue;
|
||||
if (myField != null) {
|
||||
return myField;
|
||||
}
|
||||
else {
|
||||
if (myAClass != null) {
|
||||
final XmlFile xmlFile = (XmlFile)myXmlAttributeValue.getContainingFile();
|
||||
final XmlTag rootTag = xmlFile.getRootTag();
|
||||
if (rootTag != null && !FxmlConstants.FX_ROOT.equals(rootTag.getName())) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return myXmlAttributeValue;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -72,4 +104,81 @@ class JavaFxFieldIdReferenceProvider extends JavaFxControllerBasedReferenceProvi
|
||||
return ArrayUtil.toObjectArray(fieldsToSuggest);
|
||||
}
|
||||
}
|
||||
|
||||
public static class JavaFxUnresolvedReferenceHandlerQuickfixProvider extends UnresolvedReferenceQuickFixProvider<JavaFxControllerFieldRef> {
|
||||
@Override
|
||||
public void registerFixes(final JavaFxControllerFieldRef ref, final QuickFixActionRegistrar registrar) {
|
||||
if (ref.myAClass != null && ref.myField == null) {
|
||||
final PsiClass fieldClass = CreateFieldFix.checkContext(ref.myXmlAttributeValue);
|
||||
if (fieldClass != null) {
|
||||
registrar.register(new CreateFieldFix(ref, fieldClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Class<JavaFxControllerFieldRef> getReferenceClass() {
|
||||
return JavaFxControllerFieldRef.class;
|
||||
}
|
||||
|
||||
private static class CreateFieldFix extends PsiElementBaseIntentionAction {
|
||||
private final PsiClass myFieldClass;
|
||||
private final PsiClass myClass;
|
||||
private final String myCanonicalText;
|
||||
|
||||
public CreateFieldFix(JavaFxControllerFieldRef ref, PsiClass fieldClass) {
|
||||
myFieldClass = fieldClass;
|
||||
myClass = ref.myAClass;
|
||||
myCanonicalText = ref.getCanonicalText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(myClass.getContainingFile())) {
|
||||
return;
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
PsiField field = factory.createField(myCanonicalText, PsiType.INT);
|
||||
VisibilityUtil.setVisibility(field.getModifierList(), PsiModifier.PUBLIC);
|
||||
|
||||
field = CreateFieldFromUsageHelper.insertField(myClass, field, element);
|
||||
|
||||
final PsiClassType fieldType = factory.createType(myFieldClass);
|
||||
final ExpectedTypeInfo[] types = {new ExpectedTypeInfoImpl(fieldType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, 0, fieldType, TailType.NONE)};
|
||||
CreateFieldFromUsageFix.createFieldFromUsageTemplate(myClass, project, types, field, false, element);
|
||||
}
|
||||
|
||||
protected static PsiClass checkContext(final XmlAttributeValue attributeValue) {
|
||||
if (attributeValue == null) return null;
|
||||
final PsiElement parent = attributeValue.getParent();
|
||||
if (parent instanceof XmlAttribute){
|
||||
final XmlTag tag = ((XmlAttribute)parent).getParent();
|
||||
if (tag != null) {
|
||||
final XmlElementDescriptor descriptor = tag.getDescriptor();
|
||||
if (descriptor instanceof JavaFxClassBackedElementDescriptor) {
|
||||
final PsiElement declaration = descriptor.getDeclaration();
|
||||
if (declaration instanceof PsiClass) {
|
||||
return (PsiClass)declaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
setText(QuickFixBundle.message("create.field.from.usage.text", myCanonicalText));
|
||||
return element.isValid();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("create.field.from.usage.family");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
public class CreateControllerMethod {}
|
||||
@@ -0,0 +1,5 @@
|
||||
import javafx.scene.control.Button;
|
||||
|
||||
public class CreateControllerMethod {
|
||||
public Button btn;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<GridPane xmlns:fx="http://javafx.com/fxml" fx:controller="CreateControllerMethod">
|
||||
<Button fx:id="b<caret>tn"/>
|
||||
</GridPane>
|
||||
Reference in New Issue
Block a user