@Nullable public static PsiType getQualifiedMemberReferenceType( @Nullable PsiType qualifierType, @NotNull final PsiMember member) { final Ref<PsiSubstitutor> subst = Ref.create(PsiSubstitutor.EMPTY); class MyProcessor extends BaseScopeProcessor implements NameHint, ElementClassHint { @Override public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) { if (element == member) { subst.set(state.get(PsiSubstitutor.KEY)); } return true; } @Override public String getName(@NotNull ResolveState state) { return member.getName(); } @Override public boolean shouldProcess(DeclarationKind kind) { return member instanceof PsiEnumConstant ? kind == DeclarationKind.ENUM_CONST : member instanceof PsiField ? kind == DeclarationKind.FIELD : kind == DeclarationKind.METHOD; } @Override public <T> T getHint(@NotNull Key<T> hintKey) { return hintKey == NameHint.KEY || hintKey == ElementClassHint.KEY ? (T) this : null; } } PsiScopesUtil.processTypeDeclarations(qualifierType, member, new MyProcessor()); PsiType rawType = member instanceof PsiField ? ((PsiField) member).getType() : member instanceof PsiMethod ? ((PsiMethod) member).getReturnType() : JavaPsiFacade.getElementFactory(member.getProject()) .createType((PsiClass) member); return subst.get().substitute(rawType); }
@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { if (!FileModificationService.getInstance() .preparePsiElementForWrite(descriptor.getPsiElement())) return; final PsiElement psiElement = descriptor.getPsiElement(); if (psiElement instanceof PsiInstanceOfExpression) { try { final PsiExpression compareToNull = JavaPsiFacade.getInstance(psiElement.getProject()) .getElementFactory() .createExpressionFromText( ((PsiInstanceOfExpression) psiElement).getOperand().getText() + " != null", psiElement.getParent()); psiElement.replace(compareToNull); } catch (IncorrectOperationException e) { LOG.error(e); } } }
public static boolean isSourceLevelAccessible( PsiElement context, PsiClass psiClass, final boolean pkgContext) { if (!JavaPsiFacade.getInstance(psiClass.getProject()) .getResolveHelper() .isAccessible(psiClass, context, null)) { return false; } if (pkgContext) { PsiClass topLevel = PsiUtil.getTopLevelClass(psiClass); if (topLevel != null) { String fqName = topLevel.getQualifiedName(); if (fqName != null && StringUtil.isEmpty(StringUtil.getPackageName(fqName))) { return false; } } } return true; }
@Nullable private LocalQuickFix[] createNPEFixes( PsiExpression qualifier, PsiExpression expression, boolean onTheFly) { if (qualifier == null || expression == null) return null; if (qualifier instanceof PsiMethodCallExpression) return null; try { final List<LocalQuickFix> fixes = new SmartList<LocalQuickFix>(); if (!(qualifier instanceof PsiLiteralExpression && ((PsiLiteralExpression) qualifier).getValue() == null)) { if (PsiUtil.getLanguageLevel(qualifier).isAtLeast(LanguageLevel.JDK_1_4)) { final Project project = qualifier.getProject(); final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); final PsiBinaryExpression binary = (PsiBinaryExpression) elementFactory.createExpressionFromText("a != null", null); binary.getLOperand().replace(qualifier); ContainerUtil.addIfNotNull(fixes, createAssertFix(binary, expression)); } addSurroundWithIfFix(qualifier, fixes, onTheFly); if (ReplaceWithTernaryOperatorFix.isAvailable(qualifier, expression)) { fixes.add(new ReplaceWithTernaryOperatorFix(qualifier)); } } ContainerUtil.addIfNotNull( fixes, DfaOptionalSupport.registerReplaceOptionalOfWithOfNullableFix(qualifier)); return fixes.isEmpty() ? null : fixes.toArray(new LocalQuickFix[fixes.size()]); } catch (IncorrectOperationException e) { LOG.error(e); return null; } }
@Override protected String validateAndCommitData() { PsiManager manager = PsiManager.getInstance(myProject); PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); String name = getMethodName(); if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) { return RefactoringMessageUtil.getIncorrectIdentifierMessage(name); } if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite) { try { ((PsiTypeCodeFragment) myReturnTypeCodeFragment).getType(); } catch (PsiTypeCodeFragment.TypeSyntaxException e) { myReturnTypeField.requestFocus(); return RefactoringBundle.message( "changeSignature.wrong.return.type", myReturnTypeCodeFragment.getText()); } catch (PsiTypeCodeFragment.NoTypeException e) { myReturnTypeField.requestFocus(); return RefactoringBundle.message("changeSignature.no.return.type"); } } List<ParameterTableModelItemBase<ParameterInfoImpl>> parameterInfos = myParametersTableModel.getItems(); final int newParametersNumber = parameterInfos.size(); for (int i = 0; i < newParametersNumber; i++) { final ParameterTableModelItemBase<ParameterInfoImpl> item = parameterInfos.get(i); if (!JavaPsiFacade.getInstance(manager.getProject()) .getNameHelper() .isIdentifier(item.parameter.getName())) { return RefactoringMessageUtil.getIncorrectIdentifierMessage(item.parameter.getName()); } final PsiType type; try { type = ((PsiTypeCodeFragment) parameterInfos.get(i).typeCodeFragment).getType(); } catch (PsiTypeCodeFragment.TypeSyntaxException e) { return RefactoringBundle.message( "changeSignature.wrong.type.for.parameter", item.typeCodeFragment.getText(), item.parameter.getName()); } catch (PsiTypeCodeFragment.NoTypeException e) { return RefactoringBundle.message( "changeSignature.no.type.for.parameter", item.parameter.getName()); } item.parameter.setType(type); if (type instanceof PsiEllipsisType && i != newParametersNumber - 1) { return RefactoringBundle.message("changeSignature.vararg.not.last"); } if (item.parameter.oldParameterIndex < 0) { item.parameter.defaultValue = ApplicationManager.getApplication() .runWriteAction( new Computable<String>() { @Override public String compute() { return JavaCodeStyleManager.getInstance(myProject) .qualifyClassReferences(item.defaultValueCodeFragment) .getText(); } }); String def = item.parameter.defaultValue; def = def.trim(); if (!(type instanceof PsiEllipsisType)) { try { if (!StringUtil.isEmpty(def)) { factory.createExpressionFromText(def, null); } } catch (IncorrectOperationException e) { return e.getMessage(); } } } } ThrownExceptionInfo[] exceptionInfos = myExceptionsModel.getThrownExceptions(); PsiTypeCodeFragment[] typeCodeFragments = myExceptionsModel.getTypeCodeFragments(); for (int i = 0; i < exceptionInfos.length; i++) { ThrownExceptionInfo exceptionInfo = exceptionInfos[i]; PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i]; try { PsiType type = typeCodeFragment.getType(); if (!(type instanceof PsiClassType)) { return RefactoringBundle.message( "changeSignature.wrong.type.for.exception", typeCodeFragment.getText()); } PsiClassType throwable = JavaPsiFacade.getInstance(myProject) .getElementFactory() .createTypeByFQClassName("java.lang.Throwable", type.getResolveScope()); if (!throwable.isAssignableFrom(type)) { return RefactoringBundle.message( "changeSignature.not.throwable.type", typeCodeFragment.getText()); } exceptionInfo.setType((PsiClassType) type); } catch (PsiTypeCodeFragment.TypeSyntaxException e) { return RefactoringBundle.message( "changeSignature.wrong.type.for.exception", typeCodeFragment.getText()); } catch (PsiTypeCodeFragment.NoTypeException e) { return RefactoringBundle.message("changeSignature.no.type.for.exception"); } } // warnings try { if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite) { if (!RefactoringUtil.isResolvableType( ((PsiTypeCodeFragment) myReturnTypeCodeFragment).getType())) { if (Messages.showOkCancelDialog( myProject, RefactoringBundle.message( "changeSignature.cannot.resolve.return.type", myReturnTypeCodeFragment.getText()), RefactoringBundle.message("changeSignature.refactoring.name"), Messages.getWarningIcon()) != 0) { return EXIT_SILENTLY; } } } for (ParameterTableModelItemBase<ParameterInfoImpl> item : parameterInfos) { if (!RefactoringUtil.isResolvableType( ((PsiTypeCodeFragment) item.typeCodeFragment).getType())) { if (Messages.showOkCancelDialog( myProject, RefactoringBundle.message( "changeSignature.cannot.resolve.parameter.type", item.typeCodeFragment.getText(), item.parameter.getName()), RefactoringBundle.message("changeSignature.refactoring.name"), Messages.getWarningIcon()) != 0) { return EXIT_SILENTLY; } } } } catch (PsiTypeCodeFragment.IncorrectTypeException ignored) { } return null; }
public static Set<LookupElement> processJavaReference( PsiElement element, PsiJavaReference javaReference, ElementFilter elementFilter, JavaCompletionProcessor.Options options, final PrefixMatcher matcher, CompletionParameters parameters) { final Set<LookupElement> set = new LinkedHashSet<LookupElement>(); final Condition<String> nameCondition = new Condition<String>() { @Override public boolean value(String s) { return matcher.prefixMatches(s); } }; PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); boolean checkInitialized = parameters.getInvocationCount() <= 1 && call != null && PsiKeyword.SUPER.equals(call.getMethodExpression().getText()); final JavaCompletionProcessor processor = new JavaCompletionProcessor( element, elementFilter, options.withInitialized(checkInitialized), nameCondition); final PsiType plainQualifier = processor.getQualifierType(); PsiType qualifierType = plainQualifier; PsiType runtimeQualifier = getQualifierCastType(javaReference, parameters); if (runtimeQualifier != null) { PsiType composite = qualifierType == null ? runtimeQualifier : PsiIntersectionType.createIntersection(qualifierType, runtimeQualifier); PsiElement ctx = createContextWithXxxVariable(element, composite); javaReference = (PsiReferenceExpression) JavaPsiFacade.getElementFactory(element.getProject()) .createExpressionFromText("xxx.xxx", ctx); qualifierType = runtimeQualifier; processor.setQualifierType(qualifierType); } javaReference.processVariants(processor); final PsiTypeLookupItem castItem = runtimeQualifier == null ? null : PsiTypeLookupItem.createLookupItem( runtimeQualifier, (PsiReferenceExpression) javaReference); final boolean pkgContext = inSomePackage(element); final Set<PsiMember> mentioned = new THashSet<PsiMember>(); for (CompletionElement completionElement : processor.getResults()) { for (LookupElement item : createLookupElements(completionElement, javaReference)) { item.putUserData(QUALIFIER_TYPE_ATTR, qualifierType); final Object o = item.getObject(); if (o instanceof PsiClass && !isSourceLevelAccessible(element, (PsiClass) o, pkgContext)) { continue; } if (o instanceof PsiMember) { if (isInExcludedPackage((PsiMember) o, true)) { continue; } mentioned.add(CompletionUtil.getOriginalOrSelf((PsiMember) o)); } set.add( highlightIfNeeded( qualifierType, castQualifier(item, castItem, plainQualifier, processor), o, element)); } } if (javaReference instanceof PsiJavaCodeReferenceElement && !((PsiJavaCodeReferenceElement) javaReference).isQualified()) { final StaticMemberProcessor memberProcessor = new JavaStaticMemberProcessor(parameters); memberProcessor.processMembersOfRegisteredClasses( matcher, new PairConsumer<PsiMember, PsiClass>() { @Override public void consume(PsiMember member, PsiClass psiClass) { if (!mentioned.contains(member) && processor.satisfies(member, ResolveState.initial())) { set.add(memberProcessor.createLookupElement(member, psiClass, true)); } } }); } return set; }
@NotNull static PsiReferenceExpression createReference(@NotNull String text, @NotNull PsiElement context) { return (PsiReferenceExpression) JavaPsiFacade.getElementFactory(context.getProject()) .createExpressionFromText(text, context); }