@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); }
@Override public void visitNewExpression(PsiNewExpression expression) { PsiAnonymousClass anonymousClass = expression.getAnonymousClass(); if (anonymousClass == null) { return; } JavaElementArrangementEntry entry = createNewEntry( anonymousClass, anonymousClass.getTextRange(), CLASS, anonymousClass.getName(), false); processEntry(entry, null, anonymousClass); }
@NotNull private static PsiClass[] getSupersInner(@NotNull PsiClass psiClass) { PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes(); PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes(); if (psiClass.isInterface()) { return resolveClassReferenceList( extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), true); } if (psiClass instanceof PsiAnonymousClass) { PsiAnonymousClass psiAnonymousClass = (PsiAnonymousClass) psiClass; PsiClassType baseClassReference = psiAnonymousClass.getBaseClassType(); PsiClass baseClass = baseClassReference.resolve(); if (baseClass != null) { if (baseClass.isInterface()) { PsiClass objectClass = JavaPsiFacade.getInstance(psiClass.getProject()) .findClass(CommonClassNames.JAVA_LANG_OBJECT, psiClass.getResolveScope()); return objectClass != null ? new PsiClass[] {objectClass, baseClass} : new PsiClass[] {baseClass}; } return new PsiClass[] {baseClass}; } PsiClass objectClass = JavaPsiFacade.getInstance(psiClass.getProject()) .findClass(CommonClassNames.JAVA_LANG_OBJECT, psiClass.getResolveScope()); return objectClass != null ? new PsiClass[] {objectClass} : PsiClass.EMPTY_ARRAY; } if (psiClass instanceof PsiTypeParameter) { if (extendsListTypes.length == 0) { final PsiClass objectClass = JavaPsiFacade.getInstance(psiClass.getProject()) .findClass(CommonClassNames.JAVA_LANG_OBJECT, psiClass.getResolveScope()); return objectClass != null ? new PsiClass[] {objectClass} : PsiClass.EMPTY_ARRAY; } return resolveClassReferenceList( extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false); } PsiClass[] interfaces = resolveClassReferenceList( implementsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false); PsiClass superClass = getSuperClass(psiClass); if (superClass == null) return interfaces; PsiClass[] types = new PsiClass[interfaces.length + 1]; types[0] = superClass; System.arraycopy(interfaces, 0, types, 1, interfaces.length); return types; }
@Nullable private static PsiClass getContainingContextClass(PsiElement element) { final PsiClass aClass = ClassUtils.getContainingClass(element); if (aClass instanceof PsiAnonymousClass) { final PsiAnonymousClass anonymousClass = (PsiAnonymousClass) aClass; final PsiExpressionList args = anonymousClass.getArgumentList(); if (args != null && PsiTreeUtil.isAncestor(args, element, true)) { return ClassUtils.getContainingClass(aClass); } } return aClass; }
public static DiamondInferenceResult resolveInferredTypes( PsiNewExpression newExpression, PsiElement context) { final PsiAnonymousClass anonymousClass = newExpression.getAnonymousClass(); if (anonymousClass != null) { final PsiElement resolve = anonymousClass.getBaseClassReference().resolve(); if (resolve instanceof PsiClass) { return PsiDiamondTypeImpl.DiamondInferenceResult.ANONYMOUS_INNER_RESULT; } } final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getChildOfType(newExpression, PsiReferenceParameterList.class); if (referenceParameterList != null && referenceParameterList.getTypeParameterElements().length > 0) { return DiamondInferenceResult.EXPLICIT_CONSTRUCTOR_TYPE_ARGS; } return resolveInferredTypesNoCheck(newExpression, context); }
protected final void registerClassError(@NotNull PsiClass aClass, Object... infos) { final PsiElement nameIdentifier; if (aClass instanceof PsiEnumConstantInitializer) { final PsiEnumConstantInitializer enumConstantInitializer = (PsiEnumConstantInitializer) aClass; final PsiEnumConstant enumConstant = enumConstantInitializer.getEnumConstant(); nameIdentifier = enumConstant.getNameIdentifier(); } else if (aClass instanceof PsiAnonymousClass) { final PsiAnonymousClass anonymousClass = (PsiAnonymousClass) aClass; nameIdentifier = anonymousClass.getBaseClassReference(); } else { nameIdentifier = aClass.getNameIdentifier(); } if (nameIdentifier == null) { registerError(aClass.getContainingFile(), infos); } else { registerError(nameIdentifier, infos); } }
public void testEnumWithInitializedConstants() throws Exception { setupLoadingFilter(); final GlobalSearchScope moduleScope = GlobalSearchScope.moduleScope(myModule); PsiClass enumClass = myJavaFacade.findClass("enums.OurEnumWithInitializedConstants", moduleScope); assertNotNull(enumClass); assertTrue(enumClass.isEnum()); PsiField[] fields = enumClass.getFields(); assertEquals(3, fields.length); assertTrue(fields[0] instanceof PsiEnumConstant); assertTrue(fields[1] instanceof PsiEnumConstant); assertTrue(fields[2] instanceof PsiEnumConstant); PsiAnonymousClass initializingClass0 = ((PsiEnumConstant) fields[0]).getInitializingClass(); PsiClass baseClass0 = initializingClass0.getBaseClassType().resolve(); assertTrue(baseClass0 == enumClass); PsiAnonymousClass initializingClass1 = ((PsiEnumConstant) fields[1]).getInitializingClass(); PsiClass baseClass1 = initializingClass1.getBaseClassType().resolve(); assertTrue(baseClass1 == enumClass); PsiAnonymousClass initializingClass2 = ((PsiEnumConstant) fields[1]).getInitializingClass(); PsiClass baseClass2 = initializingClass2.getBaseClassType().resolve(); assertTrue(baseClass2 == enumClass); assertTrue(initializingClass0.isInheritor(enumClass, false)); assertTrue(initializingClass1.isInheritor(enumClass, false)); assertTrue(initializingClass2.isInheritor(enumClass, false)); final PsiClass[] enumInheritors = ClassInheritorsSearch.search(enumClass, moduleScope, false).toArray(PsiClass.EMPTY_ARRAY); assertEquals(3, enumInheritors.length); assertTrue(Arrays.asList(enumInheritors).contains(initializingClass0)); assertTrue(Arrays.asList(enumInheritors).contains(initializingClass1)); assertTrue(Arrays.asList(enumInheritors).contains(initializingClass2)); PsiMethod[] methods1 = initializingClass2.getMethods(); assertEquals(1, methods1.length); assertEquals("foo", methods1[0].getName()); final PsiClass baseInterfaceClass = myJavaFacade.findClass( "enums.OurBaseInterface", GlobalSearchScope.moduleWithLibrariesScope(myModule)); assertNotNull(baseInterfaceClass); final PsiClass[] inheritors = ClassInheritorsSearch.search(baseInterfaceClass, moduleScope, false) .toArray(PsiClass.EMPTY_ARRAY); assertEquals(1, inheritors.length); assertTrue(inheritors[0] instanceof PsiAnonymousClass); teardownLoadingFilter(); assertTrue(inheritors[0].getParent().getParent() instanceof PsiExpressionList); assertTrue(inheritors[0].getParent().getParent().getParent() == fields[2]); final PsiExpression[] expressions2 = ((PsiEnumConstant) fields[2]).getArgumentList().getExpressions(); assertEquals(1, expressions2.length); assertTrue(expressions2[0] instanceof PsiNewExpression); final PsiAnonymousClass anonymousClass2 = ((PsiNewExpression) expressions2[0]).getAnonymousClass(); assertTrue(anonymousClass2 != null); assertTrue(anonymousClass2.isInheritor(baseInterfaceClass, false)); }
@Override public void visitAnonymousClass(PsiAnonymousClass aClass) { JavaElementArrangementEntry entry = createNewEntry(aClass, aClass.getTextRange(), ANONYMOUS_CLASS, aClass.getName(), false); processEntry(entry, null, aClass); }
private static void changeNewOperatorType( PsiNewExpression originalExpression, PsiType toType, final Editor editor) throws IncorrectOperationException { PsiNewExpression newExpression; PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory(); int caretOffset; TextRange selection; if (toType instanceof PsiArrayType) { final PsiExpression[] originalExpressionArrayDimensions = originalExpression.getArrayDimensions(); caretOffset = 0; @NonNls String text = "new " + toType.getDeepComponentType().getCanonicalText() + "["; if (originalExpressionArrayDimensions.length > 0) { text += originalExpressionArrayDimensions[0].getText(); } else { text += "0"; caretOffset = -2; } text += "]"; for (int i = 1; i < toType.getArrayDimensions(); i++) { text += "["; String arrayDimension = ""; if (originalExpressionArrayDimensions.length > i) { arrayDimension = originalExpressionArrayDimensions[i].getText(); text += arrayDimension; } text += "]"; if (caretOffset < 0) { caretOffset -= arrayDimension.length() + 2; } } newExpression = (PsiNewExpression) factory.createExpressionFromText(text, originalExpression); if (caretOffset < 0) { selection = new TextRange(caretOffset, caretOffset + 1); } else { selection = null; } } else { final PsiAnonymousClass anonymousClass = originalExpression.getAnonymousClass(); newExpression = (PsiNewExpression) factory.createExpressionFromText( "new " + toType.getCanonicalText() + "()" + (anonymousClass != null ? "{}" : ""), originalExpression); PsiExpressionList argumentList = originalExpression.getArgumentList(); if (argumentList == null) return; newExpression.getArgumentList().replace(argumentList); if (anonymousClass == null) { // just to prevent useless inference if (PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, originalExpression, toType)) { final PsiElement paramList = PsiDiamondTypeUtil.replaceExplicitWithDiamond( newExpression.getClassOrAnonymousClassReference().getParameterList()); newExpression = PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class); } } if (anonymousClass != null) { final PsiAnonymousClass newAnonymousClass = (PsiAnonymousClass) newExpression.getAnonymousClass().replace(anonymousClass); final PsiClass aClass = PsiUtil.resolveClassInType(toType); assert aClass != null; newAnonymousClass .getBaseClassReference() .replace(factory.createClassReferenceElement(aClass)); } selection = null; caretOffset = -1; } PsiElement element = originalExpression.replace(newExpression); editor.getCaretModel().moveToOffset(element.getTextRange().getEndOffset() + caretOffset); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); if (selection != null) { selection = selection.shiftRight(element.getTextRange().getEndOffset()); editor.getSelectionModel().setSelection(selection.getStartOffset(), selection.getEndOffset()); } }
private static boolean hasReferenceToLocalClass(PsiAnonymousClass anonymousClass) { final LocalClassReferenceVisitor visitor = new LocalClassReferenceVisitor(); anonymousClass.accept(visitor); return visitor.hasReferenceToLocalClass(); }