public static boolean proveExtendsBoundsDistinct( PsiType type1, PsiType type2, PsiClass boundClass1, PsiClass boundClass2) { if (boundClass1.isInterface() && boundClass2.isInterface()) return false; if (boundClass1.isInterface()) { return !(boundClass2.hasModifierProperty(PsiModifier.FINAL) ? InheritanceUtil.isInheritorOrSelf(boundClass2, boundClass1, true) : true); } if (boundClass2.isInterface()) { return !(boundClass1.hasModifierProperty(PsiModifier.FINAL) ? InheritanceUtil.isInheritorOrSelf(boundClass1, boundClass2, true) : true); } if (boundClass1 instanceof PsiTypeParameter) { return try2ProveTypeParameterDistinct(type2, boundClass1); } if (boundClass2 instanceof PsiTypeParameter) { return try2ProveTypeParameterDistinct(type1, boundClass2); } return !InheritanceUtil.isInheritorOrSelf(boundClass1, boundClass2, true) && !InheritanceUtil.isInheritorOrSelf(boundClass2, boundClass1, true); }
private boolean checkAccessibility(final PsiClass aClass) { // We don't care about accessibility in javadoc if (JavaResolveUtil.isInJavaDoc(myPlace)) { return true; } if (PsiImplUtil.isInServerPage(aClass.getContainingFile())) { PsiFile file = FileContextUtil.getContextFile(myPlace); if (PsiImplUtil.isInServerPage(file)) { return true; } } boolean accessible = true; if (aClass instanceof PsiTypeParameter) { accessible = !myStaticContext; } PsiManager manager = aClass.getManager(); if (aClass.hasModifierProperty(PsiModifier.PRIVATE)) { PsiElement parent = aClass.getParent(); while (true) { PsiElement parentScope = parent.getParent(); if (parentScope instanceof PsiJavaFile) break; parent = parentScope; if (!(parentScope instanceof PsiClass)) break; } if (parent instanceof PsiDeclarationStatement) { parent = parent.getParent(); } accessible = false; for (PsiElement placeParent = myPlace; placeParent != null; placeParent = placeParent.getContext()) { if (manager.areElementsEquivalent(placeParent, parent)) accessible = true; } } final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); if (aClass.hasModifierProperty(PsiModifier.PROTECTED)) { accessible = false; if (myPlace != null && facade.arePackagesTheSame(aClass, myPlace)) { accessible = true; } else { if (aClass.getContainingClass() != null) { accessible = myAccessClass == null || myPlace != null && facade.getResolveHelper().isAccessible(aClass, myPlace, myAccessClass); } } } if (aClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { if (myPlace == null || !facade.arePackagesTheSame(aClass, myPlace)) { accessible = false; } } return accessible; }
public static boolean nameCanBeImported(@NotNull String fqName, @NotNull PsiElement context) { final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class); if (containingClass != null) { if (fqName.equals(containingClass.getQualifiedName())) { return true; } final String shortName = ClassUtil.extractClassName(fqName); final PsiClass[] innerClasses = containingClass.getAllInnerClasses(); for (PsiClass innerClass : innerClasses) { if (innerClass.hasModifierProperty(PsiModifier.PRIVATE)) { continue; } if (innerClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { if (!ClassUtils.inSamePackage(innerClass, containingClass)) { continue; } } final String className = innerClass.getName(); if (shortName.equals(className)) { return false; } } PsiField field = containingClass.findFieldByName(shortName, false); if (field != null) { return false; } field = containingClass.findFieldByName(shortName, true); if (field != null && PsiUtil.isAccessible(containingClass.getProject(), field, containingClass, null)) { return false; } } final PsiJavaFile file = PsiTreeUtil.getParentOfType(context, PsiJavaFile.class); if (file == null) { return false; } if (hasExactImportConflict(fqName, file)) { return false; } if (hasOnDemandImportConflict(fqName, file, true)) { return false; } if (containsConflictingReference(file, fqName)) { return false; } if (containsConflictingClass(fqName, file)) { return false; } return !containsConflictingClassName(fqName, file); }
/** * Creates a new {@link ClassElement} object. * * @param clazz class information. * @return a new {@link ClassElement} object. */ public static ClassElement newClassElement(PsiClass clazz) { ClassElement ce = new ClassElement(); // name ce.setName(clazz.getName()); ce.setQualifiedName(clazz.getQualifiedName()); // super PsiClass superClass = clazz.getSuperClass(); if (superClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) { ce.setSuperName(superClass.getName()); } // interfaces ce.setImplementNames(PsiAdapter.getImplementsClassnames(clazz)); // other ce.setEnum(clazz.isEnum()); ce.setDeprecated(clazz.isDeprecated()); ce.setException(PsiAdapter.isExceptionClass(clazz)); ce.setAbstract(clazz.hasModifierProperty(PsiModifier.ABSTRACT)); ce.setTypeParams(clazz.getTypeParameters().length); return ce; }
@SuppressWarnings({"HardCodedStringLiteral"}) private static JVMName getJVMSignature( @Nullable PsiMethod method, boolean constructor, @Nullable PsiClass declaringClass) { JVMNameBuffer signature = new JVMNameBuffer(); signature.append("("); if (constructor) { if (declaringClass != null) { final PsiClass outerClass = declaringClass.getContainingClass(); if (outerClass != null) { // declaring class is an inner class if (!declaringClass.hasModifierProperty(PsiModifier.STATIC)) { appendJvmClassQualifiedName(signature, getJVMQualifiedName(outerClass)); } } } } if (method != null) { for (PsiParameter psiParameter : method.getParameterList().getParameters()) { appendJVMSignature(signature, psiParameter.getType()); } } signature.append(")"); if (!constructor && method != null) { appendJVMSignature(signature, method.getReturnType()); } else { signature.append(new JVMRawText("V")); } return signature.toName(); }
private static boolean isClassAccepted( final PsiClass clazz, @Nullable final ClassKind classKind, final boolean instantiatable, final boolean concrete, final boolean notInterface, final boolean notEnum) { if (classKind == ClassKind.ANNOTATION) return clazz.isAnnotationType(); if (classKind == ClassKind.ENUM) return clazz.isEnum(); if (instantiatable) { if (PsiUtil.isInstantiatable(clazz)) { return true; } } else if (concrete) { if (!clazz.hasModifierProperty(PsiModifier.ABSTRACT) && !clazz.isInterface()) { return true; } } else if (notInterface) { if (!clazz.isInterface()) { return true; } } else if (notEnum) { if (!clazz.isEnum()) { return true; } } else { return true; } return false; }
@NotNull public Object[] getVariants() { PsiElement context = getContext(); if (context == null) { context = JavaPsiFacade.getInstance(getElement().getProject()).findPackage(""); } if (context instanceof PsiPackage) { final String[] extendClasses = getExtendClassNames(); if (extendClasses != null) { return getSubclassVariants((PsiPackage) context, extendClasses); } return processPackage((PsiPackage) context); } if (context instanceof PsiClass) { final PsiClass aClass = (PsiClass) context; if (myInStaticImport) { return ArrayUtil.mergeArrays(aClass.getInnerClasses(), aClass.getFields(), Object.class); } else if (isDefinitelyStatic()) { final PsiClass[] psiClasses = aClass.getInnerClasses(); final List<PsiClass> staticClasses = new ArrayList<PsiClass>(psiClasses.length); for (PsiClass c : psiClasses) { if (c.hasModifierProperty(PsiModifier.STATIC)) { staticClasses.add(c); } } return staticClasses.isEmpty() ? PsiClass.EMPTY_ARRAY : staticClasses.toArray(new PsiClass[staticClasses.size()]); } } return ArrayUtil.EMPTY_OBJECT_ARRAY; }
@Override public void visitAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) { if (anonymousClass instanceof PsiEnumConstantInitializer) { return; } final PsiMember containingMember = PsiTreeUtil.getParentOfType(anonymousClass, PsiMember.class); if (containingMember == null || containingMember.hasModifierProperty(PsiModifier.STATIC)) { return; } final PsiJavaCodeReferenceElement reference = anonymousClass.getBaseClassReference(); if (reference.resolve() == null) { // don't warn on broken code return; } final PsiClass containingClass = PsiTreeUtil.getParentOfType(anonymousClass, PsiClass.class); if (containingClass == null) { return; } if (containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) { // strictly speaking can be named static inner class but not when part of the current // containing class return; } final InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(anonymousClass); anonymousClass.accept(visitor); if (!visitor.canInnerClassBeStatic()) { return; } if (hasReferenceToLocalClass(anonymousClass)) { return; } registerClassError(anonymousClass); }
@Nullable private String verifyInnerClassDestination() { PsiClass targetClass = findTargetClass(); if (targetClass == null) return null; for (PsiElement element : myElementsToMove) { if (PsiTreeUtil.isAncestor(element, targetClass, false)) { return RefactoringBundle.message("move.class.to.inner.move.to.self.error"); } final Language targetClassLanguage = targetClass.getLanguage(); if (!element.getLanguage().equals(targetClassLanguage)) { return RefactoringBundle.message( "move.to.different.language", UsageViewUtil.getType(element), ((PsiClass) element).getQualifiedName(), targetClass.getQualifiedName()); } if (element.getLanguage().equals(Language.findLanguageByID("Groovy"))) { return RefactoringBundle.message("dont.support.inner.classes", "Groovy"); } } while (targetClass != null) { if (targetClass.getContainingClass() != null && !targetClass.hasModifierProperty(PsiModifier.STATIC)) { return RefactoringBundle.message("move.class.to.inner.nonstatic.error"); } targetClass = targetClass.getContainingClass(); } return null; }
@NotNull public static SearchScope getClassUseScope(@NotNull PsiClass aClass) { if (aClass instanceof PsiAnonymousClass) { return new LocalSearchScope(aClass); } final GlobalSearchScope maximalUseScope = ResolveScopeManager.getElementUseScope(aClass); PsiFile file = aClass.getContainingFile(); if (PsiImplUtil.isInServerPage(file)) return maximalUseScope; final PsiClass containingClass = aClass.getContainingClass(); if (aClass.hasModifierProperty(PsiModifier.PUBLIC) || aClass.hasModifierProperty(PsiModifier.PROTECTED)) { return containingClass == null ? maximalUseScope : containingClass.getUseScope(); } else if (aClass.hasModifierProperty(PsiModifier.PRIVATE) || aClass instanceof PsiTypeParameter) { PsiClass topClass = PsiUtil.getTopLevelClass(aClass); return new LocalSearchScope(topClass == null ? aClass.getContainingFile() : topClass); } else { PsiPackage aPackage = null; if (file instanceof PsiJavaFile) { aPackage = JavaPsiFacade.getInstance(aClass.getProject()) .findPackage(((PsiJavaFile) file).getPackageName()); } if (aPackage == null) { PsiDirectory dir = file.getContainingDirectory(); if (dir != null) { aPackage = JavaDirectoryService.getInstance().getPackage(dir); } } if (aPackage != null) { SearchScope scope = PackageScope.packageScope(aPackage, false); scope = scope.intersectWith(maximalUseScope); return scope; } return new LocalSearchScope(file); } }
private boolean isAccessible(PsiClass otherClass) { if (otherClass.hasModifierProperty(PsiModifier.PRIVATE)) { final PsiClass containingClass = otherClass.getContainingClass(); PsiClass containingPlaceClass = PsiTreeUtil.getParentOfType(myPlace, PsiClass.class, false); while (containingPlaceClass != null) { if (containingClass == containingPlaceClass) { return true; } containingPlaceClass = PsiTreeUtil.getParentOfType(containingPlaceClass, PsiClass.class); } return false; } return true; }
/** * Allows to check if static import may be performed for the given element. * * @param element element to check * @return target class that may be statically imported if any; <code>null</code> otherwise */ @Nullable public static PsiClass getClassToPerformStaticImport(@NotNull PsiElement element) { if (!PsiUtil.isLanguageLevel5OrHigher(element)) return null; if (!(element instanceof PsiIdentifier) || !(element.getParent() instanceof PsiJavaCodeReferenceElement)) { return null; } PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement) element.getParent(); if (refExpr instanceof PsiMethodReferenceExpression) return null; final PsiElement gParent = refExpr.getParent(); if (gParent instanceof PsiMethodReferenceExpression) return null; if (!(gParent instanceof PsiJavaCodeReferenceElement) || isParameterizedReference((PsiJavaCodeReferenceElement) gParent)) return null; PsiElement resolved = refExpr.resolve(); if (!(resolved instanceof PsiClass)) { return null; } PsiClass psiClass = (PsiClass) resolved; if (PsiUtil.isFromDefaultPackage(psiClass) || psiClass.hasModifierProperty(PsiModifier.PRIVATE) || psiClass.getQualifiedName() == null) return null; final PsiElement ggParent = gParent.getParent(); if (ggParent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression call = (PsiMethodCallExpression) ggParent.copy(); final PsiElement qualifier = call.getMethodExpression().getQualifier(); if (qualifier == null) return null; qualifier.delete(); final PsiMethod method = call.resolveMethod(); if (method != null && method.getContainingClass() != psiClass) return null; } else { final PsiJavaCodeReferenceElement copy = (PsiJavaCodeReferenceElement) gParent.copy(); final PsiElement qualifier = copy.getQualifier(); if (qualifier == null) return null; qualifier.delete(); final PsiElement target = copy.resolve(); if (target != null && PsiTreeUtil.getParentOfType(target, PsiClass.class) != psiClass) return null; } PsiFile file = refExpr.getContainingFile(); if (!(file instanceof PsiJavaFile)) return null; PsiImportList importList = ((PsiJavaFile) file).getImportList(); if (importList == null) return null; return psiClass; }
@NotNull private PsiSubstitutor mapSubstitutor( PsiClass originalClass, PsiClass mappedClass, PsiSubstitutor substitutor) { PsiTypeParameter[] typeParameters = mappedClass.getTypeParameters(); PsiTypeParameter[] originalTypeParameters = originalClass.getTypeParameters(); if (typeParameters.length != originalTypeParameters.length) { if (originalTypeParameters.length == 0) { return JavaPsiFacade.getElementFactory(mappedClass.getProject()) .createRawSubstitutor(mappedClass); } return substitutor; } Map<PsiTypeParameter, PsiType> substitutionMap = substitutor.getSubstitutionMap(); PsiSubstitutor mappedSubstitutor = PsiSubstitutor.EMPTY; for (int i = 0; i < originalTypeParameters.length; i++) { if (!substitutionMap.containsKey(originalTypeParameters[i])) continue; PsiType originalSubstitute = substitutor.substitute(originalTypeParameters[i]); if (originalSubstitute != null) { PsiType substitute = mapType(originalSubstitute); if (substitute == null) return substitutor; mappedSubstitutor = mappedSubstitutor.put(typeParameters[i], substitute); } else { mappedSubstitutor = mappedSubstitutor.put(typeParameters[i], null); } } if (mappedClass.hasModifierProperty(PsiModifier.STATIC)) { return mappedSubstitutor; } PsiClass mappedContaining = mappedClass.getContainingClass(); PsiClass originalContaining = originalClass.getContainingClass(); //noinspection DoubleNegation if ((mappedContaining != null) != (originalContaining != null)) { return substitutor; } if (mappedContaining != null) { return mappedSubstitutor.putAll( mapSubstitutor(originalContaining, mappedContaining, substitutor)); } return mappedSubstitutor; }
@Override public boolean execute(@NotNull PsiElement element, ResolveState state) { if (!(element instanceof PsiClass)) return true; final PsiClass aClass = (PsiClass) element; final String name = aClass.getName(); if (!myClassName.equals(name)) { return true; } boolean accessible = myPlace == null || checkAccessibility(aClass); if (myCandidates == null) { myCandidates = new SmartList<ClassCandidateInfo>(); } else { String fqName = aClass.getQualifiedName(); if (fqName != null) { for (int i = myCandidates.size() - 1; i >= 0; i--) { ClassCandidateInfo info = myCandidates.get(i); Domination domination = dominates(aClass, accessible && isAccessible(aClass), fqName, info); if (domination == Domination.DOMINATED_BY) { return true; } else if (domination == Domination.DOMINATES) { myCandidates.remove(i); } } } } myHasAccessibleCandidate |= accessible; myHasInaccessibleCandidate |= !accessible; myCandidates.add( new ClassCandidateInfo( aClass, state.get(PsiSubstitutor.KEY), !accessible, myCurrentFileContext)); myResult = null; if (!accessible) return true; if (aClass.hasModifierProperty(PsiModifier.PRIVATE)) { final PsiClass containingPlaceClass = PsiTreeUtil.getParentOfType(myPlace, PsiClass.class, false); if (containingPlaceClass != null && !PsiTreeUtil.isAncestor(containingPlaceClass, aClass, true)) { return true; } } return myCurrentFileContext instanceof PsiImportStatementBase; }
private static boolean isRunnable(final PsiClass psiClass) { if (!(psiClass instanceof GrTypeDefinition)) return false; if (psiClass instanceof PsiAnonymousClass) return false; if (psiClass.isInterface()) return false; final PsiClass runnable = JavaPsiFacade.getInstance(psiClass.getProject()) .findClass("java.lang.Runnable", psiClass.getResolveScope()); if (runnable == null) return false; final PsiMethod runMethod = runnable.getMethods()[0]; final PsiMethod[] runImplementations = psiClass.findMethodsBySignature(runMethod, false); if (runImplementations.length == 1 && runImplementations[0] instanceof GrMethod && ((GrMethod) runImplementations[0]).getBlock() != null) { return psiClass.getContainingClass() == null || psiClass.hasModifierProperty(PsiModifier.STATIC); } return false; }
private boolean processClass( PsiClass resolve, PsiSubstitutor originalSubstitutor, final Map<PsiTypeParameter, PsiType> substMap) { final PsiTypeParameter[] params = resolve.getTypeParameters(); for (final PsiTypeParameter param : params) { final PsiType original = originalSubstitutor.substitute(param); if (original == null) { substMap.put(param, null); } else { substMap.put(param, substituteInternal(original)); } } if (resolve.hasModifierProperty(PsiModifier.STATIC)) return true; final PsiClass containingClass = resolve.getContainingClass(); return containingClass == null || processClass(containingClass, originalSubstitutor, substMap); }
@Override public void handleInsert(final InsertionContext context, LookupElement item) { final PsiClassType.ClassResolveResult resolveResult = myClassType.resolveGenerics(); final PsiClass psiClass = resolveResult.getElement(); if (psiClass == null || !psiClass.isValid()) { return; } GroovyPsiElement place = PsiTreeUtil.findElementOfClassAtOffset( context.getFile(), context.getStartOffset(), GroovyPsiElement.class, false); boolean hasParams = place != null && GroovyCompletionUtil.hasConstructorParameters(psiClass, place); if (myTriggerFeature) { FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW); } if (hasParams) { ParenthesesInsertHandler.WITH_PARAMETERS.handleInsert(context, item); } else { ParenthesesInsertHandler.NO_PARAMETERS.handleInsert(context, item); } shortenRefsInGenerics(context); if (hasParams) { AutoPopupController.getInstance(context.getProject()) .autoPopupParameterInfo(context.getEditor(), null); } PsiDocumentManager.getInstance(context.getProject()) .doPostponedOperationsAndUnblockDocument(context.getDocument()); if (psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) { final Editor editor = context.getEditor(); final int offset = context.getTailOffset(); editor.getDocument().insertString(offset, " {}"); editor.getCaretModel().moveToOffset(offset + 2); context.setLaterRunnable(generateAnonymousBody(editor, context.getFile())); } }
@Override public void visitNewExpression(PsiNewExpression expression) { if (FileTypeUtils.isInServerPageFile(expression)) { return; } super.visitNewExpression(expression); final PsiClass containingClass = getContainingContextClass(expression); if (containingClass == null) { return; } final PsiMethod constructor = expression.resolveConstructor(); if (constructor == null) { final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference(); if (classReference == null) { return; } final PsiElement target = classReference.resolve(); if (!(target instanceof PsiClass)) { return; } final PsiClass aClass = (PsiClass) target; if (!aClass.hasModifierProperty(PsiModifier.PRIVATE)) { return; } if (aClass.equals(containingClass)) { return; } registerNewExpressionError(expression, aClass); } else { if (!constructor.hasModifierProperty(PsiModifier.PRIVATE)) { return; } final PsiClass aClass = constructor.getContainingClass(); if (containingClass.equals(aClass)) { return; } registerNewExpressionError(expression, aClass); } }
public PsiClass getParentClass(@NotNull PsiExpression initializerExpression) { final PsiType type = initializerExpression.getType(); if (type != null && PsiUtil.isConstantExpression(initializerExpression)) { if (type instanceof PsiPrimitiveType || PsiType.getJavaLangString( initializerExpression.getManager(), initializerExpression.getResolveScope()) .equals(type)) { return super.getParentClass(initializerExpression); } } PsiElement parent = initializerExpression.getUserData(ElementToWorkOn.PARENT); if (parent == null) parent = initializerExpression; PsiClass aClass = PsiTreeUtil.getParentOfType(parent, PsiClass.class); while (aClass != null) { if (aClass.hasModifierProperty(PsiModifier.STATIC)) return aClass; if (aClass.getParent() instanceof PsiJavaFile) return aClass; aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class); } return null; }
private static boolean containsOnlyPrivates(final PsiClass aClass) { final PsiField[] fields = aClass.getFields(); for (PsiField field : fields) { if (!field.hasModifierProperty(PsiModifier.PRIVATE)) return false; } final PsiMethod[] methods = aClass.getMethods(); for (PsiMethod method : methods) { if (!method.hasModifierProperty(PsiModifier.PRIVATE)) { if (method.isConstructor()) { // skip non-private constructors with call to super only final PsiCodeBlock body = method.getBody(); if (body != null) { final PsiStatement[] statements = body.getStatements(); if (statements.length == 0) continue; if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) { final PsiExpression expression = ((PsiExpressionStatement) statements[0]).getExpression(); if (expression instanceof PsiMethodCallExpression) { PsiReferenceExpression methodExpression = ((PsiMethodCallExpression) expression).getMethodExpression(); if (methodExpression.getText().equals(PsiKeyword.SUPER)) { continue; } } } } } return false; } } final PsiClass[] inners = aClass.getInnerClasses(); for (PsiClass inner : inners) { if (!inner.hasModifierProperty(PsiModifier.PRIVATE)) return false; } return true; }
@Override public void visitClass(@NotNull PsiClass aClass) { // no call to super, so that it doesn't drill down to inner classes if (aClass.hasModifierProperty(PsiModifier.ABSTRACT)) { return; } if (!UtilityClassUtil.isUtilityClass(aClass)) { return; } if (ignoreClassesWithOnlyMain && hasOnlyMain(aClass)) { return; } if (hasPrivateConstructor(aClass)) { return; } final SearchScope scope = GlobalSearchScope.projectScope(aClass.getProject()); final Query<PsiClass> query = ClassInheritorsSearch.search(aClass, scope, true, true); final PsiClass subclass = query.findFirst(); if (subclass != null) { return; } registerClassError(aClass, aClass); }
@Override public void visitClass(@NotNull PsiClass aClass) { if (!aClass.isEnum()) { return; } if (!ClassUtils.isInnerClass(aClass)) { return; } if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { return; } final PsiModifierList modifiers = aClass.getModifierList(); if (modifiers == null) { return; } final PsiElement[] children = modifiers.getChildren(); for (final PsiElement child : children) { final String text = child.getText(); if (PsiModifier.STATIC.equals(text)) { registerError(child, child, aClass); } } }
private void checkExpression(PsiExpression expression) { if (expression == null) return; final PsiType type = expression.getType(); if (!(type instanceof PsiClassType)) return; if (IGNORE_TOSTRING && MethodUtils.isToString(PsiTreeUtil.getParentOfType(expression, PsiMethod.class))) return; if (IGNORE_EXCEPTION && (ExceptionUtils.isExceptionArgument(expression) || PsiTreeUtil.getParentOfType( expression, PsiThrowStatement.class, true, PsiCodeBlock.class, PsiClass.class) != null)) return; if (IGNORE_ASSERT && PsiTreeUtil.getParentOfType( expression, PsiAssertStatement.class, true, PsiCodeBlock.class, PsiClass.class) != null) { return; } if (IGNORE_NONNLS && NonNlsUtils.isNonNlsAnnotatedUse(expression)) return; final PsiClassType classType = (PsiClassType) type; if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return; final PsiClass referencedClass = classType.resolve(); if (referencedClass == null || referencedClass instanceof PsiTypeParameter) return; if (referencedClass.isEnum() || referencedClass.isInterface()) return; if (referencedClass.hasModifierProperty(PsiModifier.ABSTRACT) && !(expression instanceof PsiSuperExpression)) return; if (hasGoodToString(referencedClass)) return; registerError(expression); }
public static void renderClassItem( LookupElementPresentation presentation, LookupItem item, PsiClass psiClass, boolean diamond) { if (!(psiClass instanceof PsiTypeParameter)) { presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(item, presentation.isReal())); } final boolean bold = item.getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null; boolean strikeout = JavaElementLookupRenderer.isToStrikeout(item); presentation.setItemText(getName(psiClass, item, diamond)); presentation.setStrikeout(strikeout); presentation.setItemTextBold(bold); String tailText = StringUtil.notNullize((String) item.getAttribute(LookupItem.TAIL_TEXT_ATTR)); PsiSubstitutor substitutor = (PsiSubstitutor) item.getAttribute(LookupItem.SUBSTITUTOR); if (item instanceof PsiTypeLookupItem && ((PsiTypeLookupItem) item).isIndicateAnonymous() && (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT))) { tailText = "{...}" + tailText; } if (substitutor == null && !diamond && psiClass.getTypeParameters().length > 0) { tailText = "<" + StringUtil.join( psiClass.getTypeParameters(), new Function<PsiTypeParameter, String>() { @Override public String fun(PsiTypeParameter psiTypeParameter) { return psiTypeParameter.getName(); } }, "," + (showSpaceAfterComma(psiClass) ? " " : "")) + ">" + tailText; } presentation.setTailText(tailText, true); }
public Collection<String> findConflicts( @NotNull final PsiElement element, @NotNull final PsiElement[] allElementsToDelete) { if (element instanceof PsiMethod) { final PsiClass containingClass = ((PsiMethod) element).getContainingClass(); if (containingClass != null && !containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) { final PsiMethod[] superMethods = ((PsiMethod) element).findSuperMethods(); for (PsiMethod superMethod : superMethods) { if (isInside(superMethod, allElementsToDelete)) continue; if (superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { String message = RefactoringBundle.message( "0.implements.1", RefactoringUIUtil.getDescription(element, true), RefactoringUIUtil.getDescription(superMethod, true)); return Collections.singletonList(message); } } } } else if (element instanceof PsiParameter) { final PsiElement scope = ((PsiParameter) element).getDeclarationScope(); if (scope instanceof PsiMethod) { final PsiMethod method = (PsiMethod) scope; final PsiClass containingClass = method.getContainingClass(); if (containingClass != null) { final int parameterIndex = method.getParameterList().getParameterIndex((PsiParameter) element); final PsiMethod methodCopy = (PsiMethod) method.copy(); methodCopy.getParameterList().getParameters()[parameterIndex].delete(); final MultiMap<PsiElement, String> conflicts = new MultiMap<>(); ConflictsUtil.checkMethodConflicts(containingClass, method, methodCopy, conflicts); return (Collection<String>) conflicts.values(); } } } return null; }
public static MultiMap<PsiElement, String> checkConflicts( final MemberInfoBase<? extends PsiMember>[] infos, @NotNull final PsiClass subclass, @Nullable PsiClass superClass, @NotNull final PsiPackage targetPackage, @NotNull PsiDirectory targetDirectory, final InterfaceContainmentVerifier interfaceContainmentVerifier, boolean movedMembers2Super) { final Set<PsiMember> movedMembers = new HashSet<PsiMember>(); final Set<PsiMethod> abstractMethods = new HashSet<PsiMethod>(); final boolean isInterfaceTarget; final PsiElement targetRepresentativeElement; if (superClass != null) { isInterfaceTarget = superClass.isInterface(); targetRepresentativeElement = superClass; } else { isInterfaceTarget = false; targetRepresentativeElement = targetDirectory; } for (MemberInfoBase<? extends PsiMember> info : infos) { PsiMember member = info.getMember(); if (member instanceof PsiMethod) { if (!info.isToAbstract() && !isInterfaceTarget) { movedMembers.add(member); } else { abstractMethods.add((PsiMethod) member); } } else { movedMembers.add(member); } } final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); final Set<PsiMethod> abstrMethods = new HashSet<PsiMethod>(abstractMethods); if (superClass != null) { for (PsiMethod method : subclass.getMethods()) { if (!movedMembers.contains(method) && !method.hasModifierProperty(PsiModifier.PRIVATE)) { if (method.findSuperMethods(superClass).length > 0) { abstrMethods.add(method); } } } } RefactoringConflictsUtil.analyzeAccessibilityConflicts( movedMembers, superClass, conflicts, VisibilityUtil.ESCALATE_VISIBILITY, targetRepresentativeElement, abstrMethods); if (superClass != null) { if (movedMembers2Super) { checkSuperclassMembers(superClass, infos, conflicts); if (isInterfaceTarget) { checkInterfaceTarget(infos, conflicts); } } else { final String qualifiedName = superClass.getQualifiedName(); assert qualifiedName != null; if (superClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { if (!Comparing.strEqual( StringUtil.getPackageName(qualifiedName), targetPackage.getQualifiedName())) { conflicts.putValue( superClass, RefactoringUIUtil.getDescription(superClass, true) + " won't be accessible from " + RefactoringUIUtil.getDescription(targetPackage, true)); } } } } // check if moved methods use other members in the classes between Subclass and Superclass List<PsiElement> checkModuleConflictsList = new ArrayList<PsiElement>(); for (PsiMember member : movedMembers) { if (member instanceof PsiMethod || member instanceof PsiClass && !(member instanceof PsiCompiledElement)) { ClassMemberReferencesVisitor visitor = movedMembers2Super ? new ConflictingUsagesOfSubClassMembers( member, movedMembers, abstractMethods, subclass, superClass, superClass != null ? null : targetPackage, conflicts, interfaceContainmentVerifier) : new ConflictingUsagesOfSuperClassMembers( member, subclass, targetPackage, movedMembers, conflicts); member.accept(visitor); } ContainerUtil.addIfNotNull(checkModuleConflictsList, member); } for (final PsiMethod method : abstractMethods) { ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList()); ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement()); ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList()); } RefactoringConflictsUtil.analyzeModuleConflicts( subclass.getProject(), checkModuleConflictsList, new UsageInfo[0], targetRepresentativeElement, conflicts); final String fqName = subclass.getQualifiedName(); final String packageName; if (fqName != null) { packageName = StringUtil.getPackageName(fqName); } else { final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class); if (psiFile instanceof PsiClassOwner) { packageName = ((PsiClassOwner) psiFile).getPackageName(); } else { packageName = null; } } final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(), packageName); for (final PsiMethod abstractMethod : abstractMethods) { abstractMethod.accept( new ClassMemberReferencesVisitor(subclass) { @Override protected void visitClassMemberReferenceElement( PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { if (classMember != null && willBeMoved(classMember, movedMembers)) { boolean isAccessible = false; if (classMember.hasModifierProperty(PsiModifier.PRIVATE)) { isAccessible = true; } else if (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { isAccessible = true; } if (isAccessible) { String message = RefactoringUIUtil.getDescription(abstractMethod, false) + " uses " + RefactoringUIUtil.getDescription(classMember, true) + " which won't be accessible from the subclass."; message = CommonRefactoringUtil.capitalize(message); conflicts.putValue(classMember, message); } } } }); if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { if (!isInterfaceTarget) { String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) + " abstract as it won't be accessible from the subclass."; message = CommonRefactoringUtil.capitalize(message); conflicts.putValue(abstractMethod, message); } } } return conflicts; }
private void buildText( @NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @NotNull StringBuilder buffer, @NotNull TextType textType, boolean annotated) { if (aClass instanceof PsiAnonymousClass) { ClassResolveResult baseResolveResult = ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics(); PsiClass baseClass = baseResolveResult.getElement(); if (baseClass != null) { buildText(baseClass, baseResolveResult.getSubstitutor(), buffer, textType, false); } return; } boolean qualified = textType != TextType.PRESENTABLE; PsiClass enclosingClass = null; if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { PsiElement parent = aClass.getParent(); if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) { enclosingClass = (PsiClass) parent; } } if (enclosingClass != null) { buildText(enclosingClass, substitutor, buffer, textType, false); buffer.append('.'); } else if (qualified) { String fqn = aClass.getQualifiedName(); if (fqn != null) { String prefix = StringUtil.getPackageName(fqn); if (!StringUtil.isEmpty(prefix)) { buffer.append(prefix); buffer.append('.'); } } } if (annotated) { PsiNameHelper.appendAnnotations(buffer, getAnnotations(), qualified); } buffer.append(aClass.getName()); PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); if (typeParameters.length > 0) { int pos = buffer.length(); buffer.append('<'); for (int i = 0; i < typeParameters.length; i++) { PsiTypeParameter typeParameter = typeParameters[i]; PsiUtilCore.ensureValid(typeParameter); if (i > 0) { buffer.append(','); if (textType == TextType.PRESENTABLE) buffer.append(' '); } PsiType substitutionResult = substitutor.substitute(typeParameter); if (substitutionResult == null) { buffer.setLength(pos); pos = -1; break; } PsiUtil.ensureValidType(substitutionResult); if (textType == TextType.PRESENTABLE) { buffer.append(substitutionResult.getPresentableText()); } else if (textType == TextType.CANONICAL) { buffer.append(substitutionResult.getCanonicalText(annotated)); } else { buffer.append(substitutionResult.getInternalCanonicalText()); } } if (pos >= 0) { buffer.append('>'); } } }
private void buildText( @NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @NotNull StringBuilder buffer, boolean canonical, boolean internal) { if (aClass instanceof PsiAnonymousClass) { ClassResolveResult baseResolveResult = ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics(); PsiClass baseClass = baseResolveResult.getElement(); PsiSubstitutor baseSub = baseResolveResult.getSubstitutor(); if (baseClass != null) { buildText(baseClass, baseSub, buffer, canonical, internal); } return; } if (canonical == internal) { buffer.append(getAnnotationsTextPrefix(internal, false, true)); } PsiClass enclosingClass = null; if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { final PsiElement parent = aClass.getParent(); if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) { enclosingClass = (PsiClass) parent; } } if (enclosingClass != null) { buildText(enclosingClass, substitutor, buffer, canonical, false); buffer.append('.'); buffer.append(aClass.getName()); } else { final String name; if (!canonical) { name = aClass.getName(); } else { final String qualifiedName = aClass.getQualifiedName(); if (qualifiedName == null) { name = aClass.getName(); } else { name = qualifiedName; } } buffer.append(name); } PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); if (typeParameters.length > 0) { StringBuilder pineBuffer = new StringBuilder(); pineBuffer.append('<'); for (int i = 0; i < typeParameters.length; i++) { PsiTypeParameter typeParameter = typeParameters[i]; assert typeParameter.isValid(); if (i > 0) pineBuffer.append(','); final PsiType substitutionResult = substitutor.substitute(typeParameter); if (substitutionResult == null) { pineBuffer = null; break; } assert substitutionResult.isValid(); if (canonical) { if (internal) { pineBuffer.append(substitutionResult.getInternalCanonicalText()); } else { pineBuffer.append(substitutionResult.getCanonicalText()); } } else { pineBuffer.append(substitutionResult.getPresentableText()); } } if (pineBuffer != null) { buffer.append(pineBuffer); buffer.append('>'); } } }
protected void initialize() { myDefaultConstructor = null; final PsiClass psiClass = getElement(); LOG.assertTrue(psiClass != null); PsiElement psiParent = psiClass.getParent(); if (psiParent instanceof PsiFile) { if (isSyntheticJSP()) { final RefFileImpl refFile = (RefFileImpl) getRefManager().getReference(JspPsiUtil.getJspFile(psiClass)); LOG.assertTrue(refFile != null); refFile.add(this); } else if (psiParent instanceof PsiJavaFile) { PsiJavaFile psiFile = (PsiJavaFile) psiParent; String packageName = psiFile.getPackageName(); if (!"".equals(packageName)) { ((RefPackageImpl) getRefJavaManager().getPackage(packageName)).add(this); } else { ((RefPackageImpl) getRefJavaManager().getDefaultPackage()).add(this); } } final Module module = ModuleUtil.findModuleForPsiElement(psiClass); LOG.assertTrue(module != null); final RefModuleImpl refModule = ((RefModuleImpl) getRefManager().getRefModule(module)); LOG.assertTrue(refModule != null); refModule.add(this); } else { while (!(psiParent instanceof PsiClass || psiParent instanceof PsiMethod || psiParent instanceof PsiField)) { psiParent = psiParent.getParent(); } RefElement refParent = getRefManager().getReference(psiParent); LOG.assertTrue(refParent != null); ((RefElementImpl) refParent).add(this); } setAbstract(psiClass.hasModifierProperty(PsiModifier.ABSTRACT)); setAnonymous(psiClass instanceof PsiAnonymousClass); setIsLocal(!(isAnonymous() || psiParent instanceof PsiClass || psiParent instanceof PsiFile)); setInterface(psiClass.isInterface()); initializeSuperReferences(psiClass); PsiMethod[] psiMethods = psiClass.getMethods(); PsiField[] psiFields = psiClass.getFields(); setUtilityClass(psiMethods.length > 0 || psiFields.length > 0); for (PsiField psiField : psiFields) { getRefManager().getReference(psiField); } if (!isApplet()) { final PsiClass servlet = getRefJavaManager().getServlet(); setServlet(servlet != null && psiClass.isInheritor(servlet, true)); } if (!isApplet() && !isServlet()) { setTestCase(TestUtil.isTestClass(psiClass)); for (RefClass refBase : getBaseClasses()) { ((RefClassImpl) refBase).setTestCase(true); } } for (PsiMethod psiMethod : psiMethods) { RefMethod refMethod = (RefMethod) getRefManager().getReference(psiMethod); if (refMethod != null) { if (psiMethod.isConstructor()) { if (psiMethod.getParameterList().getParametersCount() > 0 || !psiMethod.hasModifierProperty(PsiModifier.PRIVATE)) { setUtilityClass(false); } addConstructor(refMethod); if (psiMethod.getParameterList().getParametersCount() == 0) { setDefaultConstructor((RefMethodImpl) refMethod); } } else { if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) { setUtilityClass(false); } } } } if (getConstructors().size() == 0 && !isInterface() && !isAnonymous()) { RefImplicitConstructorImpl refImplicitConstructor = new RefImplicitConstructorImpl(this); setDefaultConstructor(refImplicitConstructor); addConstructor(refImplicitConstructor); } if (isInterface()) { for (int i = 0; i < psiFields.length && isUtilityClass(); i++) { PsiField psiField = psiFields[i]; if (!psiField.hasModifierProperty(PsiModifier.STATIC)) { setUtilityClass(false); } } } final PsiClass applet = getRefJavaManager().getApplet(); setApplet(applet != null && psiClass.isInheritor(applet, true)); getRefManager().fireNodeInitialized(this); }
@NotNull private static Set<String> findSingleImports( @NotNull final PsiJavaFile file, @NotNull String[] names, @NotNull final Set<String> onDemandImports, @NotNull Set<String> namesToImportStaticly) { final GlobalSearchScope resolveScope = file.getResolveScope(); Set<String> namesToUseSingle = new THashSet<String>(); final String thisPackageName = file.getPackageName(); final Set<String> implicitlyImportedPackages = new THashSet<String>(Arrays.asList(file.getImplicitlyImportedPackages())); final PsiManager manager = file.getManager(); for (String name : names) { String prefix = getPackageOrClassName(name); if (prefix.length() == 0) continue; final boolean isImplicitlyImported = implicitlyImportedPackages.contains(prefix); if (!onDemandImports.contains(prefix) && !isImplicitlyImported) continue; String shortName = PsiNameHelper.getShortClassName(name); String thisPackageClass = thisPackageName.length() > 0 ? thisPackageName + "." + shortName : shortName; if (JavaPsiFacade.getInstance(manager.getProject()).findClass(thisPackageClass, resolveScope) != null) { namesToUseSingle.add(name); continue; } if (!isImplicitlyImported) { String langPackageClass = JAVA_LANG_PACKAGE + "." + shortName; // TODO : JSP! if (JavaPsiFacade.getInstance(manager.getProject()) .findClass(langPackageClass, resolveScope) != null) { namesToUseSingle.add(name); continue; } } for (String onDemandName : onDemandImports) { if (prefix.equals(onDemandName)) continue; if (namesToImportStaticly.contains(name)) { PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(onDemandName, resolveScope); if (aClass != null) { PsiField field = aClass.findFieldByName(shortName, true); if (field != null && field.hasModifierProperty(PsiModifier.STATIC)) { namesToUseSingle.add(name); } else { PsiClass inner = aClass.findInnerClassByName(shortName, true); if (inner != null && inner.hasModifierProperty(PsiModifier.STATIC)) { namesToUseSingle.add(name); } else { PsiMethod[] methods = aClass.findMethodsByName(shortName, true); for (PsiMethod method : methods) { if (method.hasModifierProperty(PsiModifier.STATIC)) { namesToUseSingle.add(name); } } } } } } else { PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()) .findClass(onDemandName + "." + shortName, resolveScope); if (aClass != null) { namesToUseSingle.add(name); } } } } return namesToUseSingle; }