/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.intentions; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind; import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.patterns.PsiElementPattern; import com.intellij.psi.PsiAnonymousClass; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClassObjectAccessExpression; import com.intellij.psi.PsiCodeFragment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiInstanceOfExpression; import com.intellij.psi.PsiJavaCodeReferenceCodeFragment; import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethodCallExpression; import com.intellij.psi.PsiReferenceExpression; import com.intellij.psi.PsiReferenceList; import com.intellij.psi.PsiReferenceParameterList; import com.intellij.psi.PsiTypeCastExpression; import com.intellij.psi.PsiTypeElement; import com.intellij.psi.PsiVariable; import com.intellij.psi.SmartPointerManager; import com.intellij.psi.SmartPsiElementPointer; import gw.lang.parser.expressions.IMethodCallExpression; import gw.lang.reflect.IFunctionType; import gw.lang.reflect.IMethodInfo; import gw.lang.reflect.IType; import gw.plugin.ij.lang.psi.impl.expressions.GosuExpressionListImpl; import gw.plugin.ij.lang.psi.impl.expressions.GosuMethodCallExpressionImpl; import gw.plugin.ij.lang.psi.impl.expressions.GosuNewExpressionImpl; import gw.plugin.ij.lang.psi.impl.expressions.GosuTypeLiteralImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author ven */ public abstract class CreateClassBaseFix extends BaseIntentionAction { protected static final Logger LOG = Logger.getInstance( "#com.intellij.codeInsight.daemon.impl.actions.CreateClassBaseFix"); protected final GosuCreateClassKind myKind; @NotNull private final SmartPsiElementPointer<GosuTypeLiteralImpl> myRefElement; public CreateClassBaseFix(GosuCreateClassKind kind, @NotNull final GosuTypeLiteralImpl refElement) { myKind = kind; myRefElement = SmartPointerManager.getInstance(refElement.getProject()).createLazyPointer(refElement); } protected abstract String getText(String varName); private boolean isAvailableInContext(final @NotNull GosuTypeLiteralImpl element) { return true; // PsiElement parent = element.getParent(); // // if (parent instanceof PsiJavaCodeReferenceCodeFragment) return true; // // if (parent instanceof PsiTypeElement) { // if (parent.getParent() instanceof PsiReferenceParameterList) return true; // // while (parent.getParent() instanceof PsiTypeElement) parent = parent.getParent(); // if (parent.getParent() instanceof PsiCodeFragment || // parent.getParent() instanceof PsiVariable || // parent.getParent() instanceof PsiMethod || // parent.getParent() instanceof PsiClassObjectAccessExpression || // parent.getParent() instanceof PsiTypeCastExpression || // (parent.getParent() instanceof PsiInstanceOfExpression && ((PsiInstanceOfExpression)parent.getParent()).getCheckType() == parent)) { // return true; // } // } // else if (parent instanceof PsiReferenceList) { // if (myKind == CreateClassKind.ENUM) return false; // if (parent.getParent() instanceof PsiClass) { // PsiClass psiClass = (PsiClass)parent.getParent(); // if (psiClass.getExtendsList() == parent) { // if (myKind == CreateClassKind.CLASS && !psiClass.isInterface()) return true; // if (myKind == CreateClassKind.INTERFACE && psiClass.isInterface()) return true; // } // if (psiClass.getImplementsList() == parent && myKind == CreateClassKind.INTERFACE) return true; // } // else if (parent.getParent() instanceof PsiMethod) { // PsiMethod method = (PsiMethod)parent.getParent(); // if (method.getThrowsList() == parent && myKind == CreateClassKind.CLASS) return true; // } // } // else if (parent instanceof PsiAnonymousClass && ((PsiAnonymousClass)parent).getBaseClassReference() == element) { // return true; // } // // if (element instanceof PsiReferenceExpression) { // if (parent instanceof PsiMethodCallExpression) { // return false; // } // return !(parent.getParent() instanceof PsiMethodCallExpression) || myKind == CreateClassKind.CLASS; // } // return false; } private static boolean checkClassName(@NotNull String name) { return Character.isUpperCase(name.charAt(0)); } public boolean isAvailable(@NotNull final Project project, @NotNull final Editor editor, final PsiFile file) { final GosuTypeLiteralImpl element = getRefElement(); if (element == null || !element.getManager().isInProject(element) || CreateFromUsageUtils.isValidReference(element, true)) return false; final String refName = element.getReferenceName(); if (refName == null || !checkClassName(refName)) return false; PsiElement nameElement = element.getReferenceNameElement(); if (nameElement == null) return false; // PsiElement parent = element.getParent(); // if (parent instanceof PsiExpression && !(parent instanceof PsiReferenceExpression)) return false; if (!isAvailableInContext(element)) return false; final int offset = editor.getCaretModel().getOffset(); if (CreateFromUsageUtils.shouldShowTag(offset, nameElement, element)) { setText(getText(nameElement.getText())); return true; } return false; } @NotNull public String getFamilyName() { return QuickFixBundle.message("create.class.from.usage.family"); } @Nullable protected GosuTypeLiteralImpl getRefElement() { return myRefElement.getElement(); } }