private static PsiType removeClassWildcard(PsiType type) { if (type instanceof PsiClassType) { final PsiClass psiClass = ((PsiClassType) type).resolve(); if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) { return GenericsUtil.eliminateWildcards(type); } } return type; }
@Override public boolean accepts( @NotNull PsiSwitchStatement psiSwitchStatement, ProcessingContext context) { final PsiExpression expression = psiSwitchStatement.getExpression(); if (expression == null) return false; PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(expression.getType()); return aClass != null && aClass.isEnum(); }
private static PsiType removeClassWildcard(PsiType type) { if (type instanceof PsiClassType) { final PsiClass psiClass = ((PsiClassType) type).resolve(); if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) { PsiClassType erased = (PsiClassType) GenericsUtil.eliminateWildcards(type); PsiType[] parameters = erased.getParameters(); if (parameters.length == 1 && !parameters[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) { return erased; } } } return type; }
public static boolean hasAccessibleConstructor(PsiType type) { if (type instanceof PsiArrayType) return true; final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass == null || psiClass.isEnum() || psiClass.isAnnotationType()) return false; if (!(psiClass instanceof PsiCompiledElement)) return true; final PsiMethod[] methods = psiClass.getConstructors(); if (methods.length == 0) return true; for (final PsiMethod method : methods) { if (!method.hasModifierProperty(PsiModifier.PRIVATE)) return true; } return false; }
@NotNull private static ExpectedTypeMatching preferByMemberName( @Nullable String expectedMemberName, @Nullable PsiType itemType) { if (expectedMemberName != null) { PsiClass itemClass = PsiUtil.resolveClassInClassTypeOnly(itemType); if (itemClass != null) { if (itemClass.findMethodsByName(expectedMemberName, true).length > 0 || itemClass.findFieldByName(expectedMemberName, true) != null || itemClass.findInnerClassByName(expectedMemberName, true) != null) { return ExpectedTypeMatching.expected; } } } return ExpectedTypeMatching.normal; }
private static boolean superConstructorHasParameters(PsiMethod method) { final PsiClass psiClass = method.getContainingClass(); if (psiClass == null) { return false; } final PsiClass superClass = psiClass.getSuperClass(); if (superClass != null) { for (final PsiMethod psiMethod : superClass.getConstructors()) { final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(method.getProject()).getResolveHelper(); if (resolveHelper.isAccessible(psiMethod, method, null) && psiMethod.getParameterList().getParameters().length > 0) { return true; } } } return false; }
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; }
public static Set<String> getAllLookupStrings(@NotNull PsiMember member) { Set<String> allLookupStrings = ContainerUtil.newLinkedHashSet(); String name = member.getName(); allLookupStrings.add(name); PsiClass containingClass = member.getContainingClass(); while (containingClass != null) { final String className = containingClass.getName(); if (className == null) { break; } name = className + "." + name; allLookupStrings.add(name); final PsiElement parent = containingClass.getParent(); if (!(parent instanceof PsiClass)) { break; } containingClass = (PsiClass) parent; } return allLookupStrings; }
public static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object) { if (qualifierType instanceof PsiArrayType && object instanceof PsiMember) { // length and clone() PsiFile file = ((PsiMember) object).getContainingFile(); if (file == null || file.getVirtualFile() == null) { // yes, they're a bit dummy return true; } } else if (qualifierType instanceof PsiClassType) { PsiClass qualifierClass = ((PsiClassType) qualifierType).resolve(); if (qualifierClass == null) return false; if (object instanceof PsiMethod && qualifierClass.findMethodBySignature((PsiMethod) object, false) != null) { return true; } if (object instanceof PsiMember) { return qualifierClass.equals(((PsiMember) object).getContainingClass()); } } return false; }
private static void completeAnnotationAttributeName( CompletionResultSet result, PsiElement insertedElement, CompletionParameters parameters) { PsiNameValuePair pair = PsiTreeUtil.getParentOfType(insertedElement, PsiNameValuePair.class); PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList) pair.getParent(); PsiAnnotation anno = (PsiAnnotation) parameterList.getParent(); boolean showClasses = psiElement().afterLeaf("(").accepts(insertedElement); PsiClass annoClass = null; final PsiJavaCodeReferenceElement referenceElement = anno.getNameReferenceElement(); if (referenceElement != null) { final PsiElement element = referenceElement.resolve(); if (element instanceof PsiClass) { annoClass = (PsiClass) element; if (annoClass.findMethodsByName("value", false).length == 0) { showClasses = false; } } } if (showClasses && insertedElement.getParent() instanceof PsiReferenceExpression) { final Set<LookupElement> set = JavaCompletionUtil.processJavaReference( insertedElement, (PsiJavaReference) insertedElement.getParent(), new ElementExtractorFilter(createAnnotationFilter(insertedElement)), JavaCompletionProcessor.Options.DEFAULT_OPTIONS, result.getPrefixMatcher(), parameters); for (final LookupElement element : set) { result.addElement(element); } addAllClasses(parameters, result, new InheritorsHolder(insertedElement, result)); } if (annoClass != null) { final PsiNameValuePair[] existingPairs = parameterList.getAttributes(); methods: for (PsiMethod method : annoClass.getMethods()) { if (!(method instanceof PsiAnnotationMethod)) continue; final String attrName = method.getName(); for (PsiNameValuePair existingAttr : existingPairs) { if (PsiTreeUtil.isAncestor(existingAttr, insertedElement, false)) break; if (Comparing.equal(existingAttr.getName(), attrName) || PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(attrName) && existingAttr.getName() == null) continue methods; } LookupElementBuilder element = LookupElementBuilder.createWithIcon(method) .withInsertHandler( new InsertHandler<LookupElement>() { @Override public void handleInsert(InsertionContext context, LookupElement item) { final Editor editor = context.getEditor(); TailType.EQ.processTail(editor, editor.getCaretModel().getOffset()); context.setAddCompletionChar(false); context.commitDocument(); PsiAnnotationParameterList paramList = PsiTreeUtil.findElementOfClassAtOffset( context.getFile(), context.getStartOffset(), PsiAnnotationParameterList.class, false); if (paramList != null && paramList.getAttributes().length > 0 && paramList.getAttributes()[0].getName() == null) { int valueOffset = paramList.getAttributes()[0].getTextRange().getStartOffset(); context .getDocument() .insertString( valueOffset, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME); TailType.EQ.processTail( editor, valueOffset + PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.length()); } } }); PsiAnnotationMemberValue defaultValue = ((PsiAnnotationMethod) method).getDefaultValue(); if (defaultValue != null) { Object constant = JavaPsiFacade.getInstance(method.getProject()) .getConstantEvaluationHelper() .computeConstantExpression(defaultValue); if (constant != null) { element = element.withTailText( " default " + (constant instanceof String ? "\"" + constant + "\"" : constant), true); } } result.addElement(element); } } }
public static int insertClassReference( PsiClass psiClass, PsiFile file, int startOffset, int endOffset) { final Project project = file.getProject(); PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); documentManager.commitAllDocuments(); final PsiManager manager = file.getManager(); final Document document = FileDocumentManager.getInstance().getDocument(file.getViewProvider().getVirtualFile()); final PsiReference reference = file.findReferenceAt(startOffset); if (reference != null) { final PsiElement resolved = reference.resolve(); if (resolved instanceof PsiClass) { if (((PsiClass) resolved).getQualifiedName() == null || manager.areElementsEquivalent(psiClass, resolved)) { return endOffset; } } } String name = psiClass.getName(); if (name == null) { return endOffset; } assert document != null; document.replaceString(startOffset, endOffset, name); int newEndOffset = startOffset + name.length(); final RangeMarker toDelete = insertTemporary(newEndOffset, document, " "); documentManager.commitAllDocuments(); PsiElement element = file.findElementAt(startOffset); if (element instanceof PsiIdentifier) { PsiElement parent = element.getParent(); if (parent instanceof PsiJavaCodeReferenceElement && !((PsiJavaCodeReferenceElement) parent).isQualified() && !(parent.getParent() instanceof PsiPackageStatement)) { PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) parent; if (psiClass.isValid() && !psiClass.getManager().areElementsEquivalent(psiClass, resolveReference(ref))) { final boolean staticImport = ref instanceof PsiImportStaticReferenceElement; PsiElement newElement; try { newElement = staticImport ? ((PsiImportStaticReferenceElement) ref).bindToTargetClass(psiClass) : ref.bindToElement(psiClass); } catch (IncorrectOperationException e) { return endOffset; // can happen if fqn contains reserved words, for example } final RangeMarker rangeMarker = document.createRangeMarker(newElement.getTextRange()); documentManager.doPostponedOperationsAndUnblockDocument(document); documentManager.commitDocument(document); newElement = CodeInsightUtilCore.findElementInRange( file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), PsiJavaCodeReferenceElement.class, JavaLanguage.INSTANCE); rangeMarker.dispose(); if (newElement != null) { newEndOffset = newElement.getTextRange().getEndOffset(); if (!(newElement instanceof PsiReferenceExpression)) { PsiReferenceParameterList parameterList = ((PsiJavaCodeReferenceElement) newElement).getParameterList(); if (parameterList != null) { newEndOffset = parameterList.getTextRange().getStartOffset(); } } if (!staticImport && !psiClass .getManager() .areElementsEquivalent(psiClass, resolveReference((PsiReference) newElement)) && !PsiUtil.isInnerClass(psiClass)) { final String qName = psiClass.getQualifiedName(); if (qName != null) { document.replaceString( newElement.getTextRange().getStartOffset(), newEndOffset, qName); newEndOffset = newElement.getTextRange().getStartOffset() + qName.length(); } } } } } } if (toDelete.isValid()) { document.deleteString(toDelete.getStartOffset(), toDelete.getEndOffset()); } return newEndOffset; }
@NotNull private static LookupElement castQualifier( @NotNull LookupElement item, @Nullable final PsiTypeLookupItem castTypeItem, @Nullable PsiType plainQualifier, JavaCompletionProcessor processor) { if (castTypeItem == null) { return item; } if (plainQualifier != null) { Object o = item.getObject(); if (o instanceof PsiMethod) { PsiType castType = castTypeItem.getType(); if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) { PsiMethod method = (PsiMethod) o; PsiClassType.ClassResolveResult plainResult = ((PsiClassType) plainQualifier).resolveGenerics(); PsiClass plainClass = plainResult.getElement(); if (plainClass != null && plainClass.findMethodBySignature(method, true) != null) { PsiClass castClass = ((PsiClassType) castType).resolveGenerics().getElement(); if (castClass == null || !castClass.isInheritor(plainClass, true)) { return item; } PsiSubstitutor plainSub = plainResult.getSubstitutor(); PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType) castType); PsiType returnType = method.getReturnType(); if (method.getSignature(plainSub).equals(method.getSignature(castSub))) { PsiType typeAfterCast = toRaw(castSub.substitute(returnType)); PsiType typeDeclared = toRaw(plainSub.substitute(returnType)); if (typeAfterCast != null && typeDeclared != null && typeAfterCast.isAssignableFrom(typeDeclared) && processor.isAccessible(plainClass.findMethodBySignature(method, true))) { return item; } } } } } else if (containsMember(plainQualifier, o)) { return item; } } return LookupElementDecorator.withInsertHandler( item, new InsertHandlerDecorator<LookupElement>() { @Override public void handleInsert( InsertionContext context, LookupElementDecorator<LookupElement> item) { final Document document = context.getEditor().getDocument(); context.commitDocument(); final PsiFile file = context.getFile(); final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset( file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false); if (ref != null) { final PsiElement qualifier = ref.getQualifier(); if (qualifier != null) { final CommonCodeStyleSettings settings = context.getCodeStyleSettings(); final String parenSpace = settings.SPACE_WITHIN_PARENTHESES ? " " : ""; document.insertString(qualifier.getTextRange().getEndOffset(), parenSpace + ")"); final String spaceWithin = settings.SPACE_WITHIN_CAST_PARENTHESES ? " " : ""; final String prefix = "(" + parenSpace + "(" + spaceWithin; final String spaceAfter = settings.SPACE_AFTER_TYPE_CAST ? " " : ""; final int exprStart = qualifier.getTextRange().getStartOffset(); document.insertString(exprStart, prefix + spaceWithin + ")" + spaceAfter); CompletionUtil.emulateInsertion(context, exprStart + prefix.length(), castTypeItem); PsiDocumentManager.getInstance(file.getProject()) .doPostponedOperationsAndUnblockDocument(document); context.getEditor().getCaretModel().moveToOffset(context.getTailOffset()); } } item.getDelegate().handleInsert(context); } }); }