@Nullable public static PsiClass getSuperClass(@NotNull PsiClass psiClass) { PsiManager manager = psiClass.getManager(); GlobalSearchScope resolveScope = psiClass.getResolveScope(); final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); if (psiClass.isInterface()) { return facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope); } if (psiClass.isEnum()) { return facade.findClass(CommonClassNames.JAVA_LANG_ENUM, resolveScope); } if (psiClass instanceof PsiAnonymousClass) { PsiClassType baseClassReference = ((PsiAnonymousClass) psiClass).getBaseClassType(); PsiClass baseClass = baseClassReference.resolve(); if (baseClass == null || baseClass.isInterface()) return facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope); return baseClass; } if (CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass.getQualifiedName())) return null; final PsiClassType[] referenceElements = psiClass.getExtendsListTypes(); if (referenceElements.length == 0) return facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope); PsiClass psiResoved = referenceElements[0].resolve(); return psiResoved == null ? facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope) : psiResoved; }
public void testEnum() throws Exception { setupLoadingFilter(); final PsiClass enumClass = myJavaFacade.findClass("enums.OurEnum", GlobalSearchScope.moduleScope(myModule)); assertNotNull(enumClass); assertTrue(enumClass.isEnum()); final PsiClass superClass = enumClass.getSuperClass(); assertNotNull(superClass); assertEquals("java.lang.Enum", superClass.getQualifiedName()); assertTrue(enumClass.isInheritor(superClass, false)); final PsiClassType[] superTypes = enumClass.getSuperTypes(); assertEquals(1, superTypes.length); assertEquals("java.lang.Enum<enums.OurEnum>", superTypes[0].getCanonicalText()); final PsiClass[] supers = enumClass.getSupers(); assertEquals(1, supers.length); assertEquals("java.lang.Enum", supers[0].getQualifiedName()); final PsiClassType[] extendsListTypes = enumClass.getExtendsListTypes(); assertEquals(1, extendsListTypes.length); assertEquals("java.lang.Enum<enums.OurEnum>", extendsListTypes[0].getCanonicalText()); final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, enumClass, PsiSubstitutor.EMPTY); assertEquals( "java.lang.Enum<enums.OurEnum>", myJavaFacade .getElementFactory() .createType(superClass, superClassSubstitutor) .getCanonicalText()); teardownLoadingFilter(); }
@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; }
@NotNull public static PsiClass[] getInterfaces(@NotNull PsiClass psiClass) { if (psiClass.isInterface()) { final PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes(); return resolveClassReferenceList( extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false); } if (psiClass instanceof PsiAnonymousClass) { PsiClassType baseClassReference = ((PsiAnonymousClass) psiClass).getBaseClassType(); PsiClass baseClass = baseClassReference.resolve(); return baseClass != null && baseClass.isInterface() ? new PsiClass[] {baseClass} : PsiClass.EMPTY_ARRAY; } final PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes(); return resolveClassReferenceList( implementsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false); }
@Nullable private PsiType getSuperType(PsiClass aClass) { if (aClass.isInterface()) { return PsiType.getJavaLangObject(getManager(), getResolveScope()); } if (aClass instanceof GrAnonymousClassDefinition) { final PsiClassType baseClassType = ((GrAnonymousClassDefinition) aClass).getBaseClassType(); final PsiClass psiClass = baseClassType.resolve(); if (psiClass != null && !psiClass.isInterface()) { return baseClassType; } return PsiType.getJavaLangObject(getManager(), getResolveScope()); } if (CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) return null; PsiClassType[] superTypes = aClass.getExtendsListTypes(); if (superTypes.length == 0) { return PsiType.getJavaLangObject(getManager(), getResolveScope()); } return superTypes[0]; }
private static String generateClassInfo(PsiClass aClass) { StringBuilder buffer = new StringBuilder(); GroovyFile file = (GroovyFile) aClass.getContainingFile(); String packageName = file.getPackageName(); if (!packageName.isEmpty()) { buffer.append(packageName).append("\n"); } final String classString = aClass.isInterface() ? "interface" : aClass instanceof PsiTypeParameter ? "type parameter" : aClass.isEnum() ? "enum" : "class"; buffer.append(classString).append(" ").append(aClass.getName()); JavaDocumentationProvider.generateTypeParameters(aClass, buffer); JavaDocumentationProvider.writeExtends(aClass, buffer, aClass.getExtendsListTypes()); JavaDocumentationProvider.writeImplements(aClass, buffer, aClass.getImplementsListTypes()); return buffer.toString(); }
@NotNull public static PsiClassType[] getSuperTypes(@NotNull PsiClass psiClass) { if (psiClass instanceof PsiAnonymousClass) { PsiClassType baseClassType = ((PsiAnonymousClass) psiClass).getBaseClassType(); PsiClass baseClass = baseClassType.resolve(); if (baseClass == null || !baseClass.isInterface()) { return new PsiClassType[] {baseClassType}; } else { PsiClassType objectType = PsiType.getJavaLangObject(psiClass.getManager(), psiClass.getResolveScope()); return new PsiClassType[] {objectType, baseClassType}; } } PsiClassType[] extendsTypes = psiClass.getExtendsListTypes(); PsiClassType[] implementsTypes = psiClass.getImplementsListTypes(); boolean hasExtends = extendsTypes.length != 0; int extendsListLength = extendsTypes.length + (hasExtends ? 0 : 1); PsiClassType[] result = new PsiClassType[extendsListLength + implementsTypes.length]; System.arraycopy(extendsTypes, 0, result, 0, extendsTypes.length); if (!hasExtends) { if (CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass.getQualifiedName())) { return PsiClassType.EMPTY_ARRAY; } PsiManager manager = psiClass.getManager(); PsiClassType objectType = PsiType.getJavaLangObject(manager, psiClass.getResolveScope()); result[0] = objectType; } System.arraycopy(implementsTypes, 0, result, extendsListLength, implementsTypes.length); for (int i = 0; i < result.length; i++) { PsiClassType type = result[i]; result[i] = (PsiClassType) PsiUtil.captureToplevelWildcards(type, psiClass); } return result; }
public static boolean try2ProveTypeParameterDistinct(PsiType type, PsiClass typeParameter) { final PsiClassType[] types = typeParameter.getExtendsListTypes(); if (types.length == 0) return false; return provablyDistinct( PsiWildcardType.createExtends(typeParameter.getManager(), types[0]), type); }
@Nullable private PsiType getNominalTypeInner(@Nullable PsiElement resolved) { if (resolved == null && !"class".equals(getReferenceName())) { resolved = resolve(); } if (resolved instanceof PsiClass) { final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); if (PsiUtil.isInstanceThisRef(this)) { final PsiClassType categoryType = GdkMethodUtil.getCategoryType((PsiClass) resolved); if (categoryType != null) { return categoryType; } else { return factory.createType((PsiClass) resolved); } } else if (PsiUtil.isSuperReference(this)) { PsiClass contextClass = PsiUtil.getContextClass(this); if (GrTraitUtil.isTrait(contextClass)) { PsiClassType[] extendsTypes = contextClass.getExtendsListTypes(); PsiClassType[] implementsTypes = contextClass.getImplementsListTypes(); PsiClassType[] superTypes = ArrayUtil.mergeArrays(implementsTypes, extendsTypes, PsiClassType.ARRAY_FACTORY); return PsiIntersectionType.createIntersection(ArrayUtil.reverseArray(superTypes)); } return factory.createType((PsiClass) resolved); } if (getParent() instanceof GrReferenceExpression) { return factory.createType((PsiClass) resolved); } else { return TypesUtil.createJavaLangClassType( factory.createType((PsiClass) resolved), getProject(), getResolveScope()); } } if (resolved instanceof GrVariable) { return ((GrVariable) resolved).getDeclaredType(); } if (resolved instanceof PsiVariable) { return ((PsiVariable) resolved).getType(); } if (resolved instanceof PsiMethod) { PsiMethod method = (PsiMethod) resolved; if (PropertyUtil.isSimplePropertySetter(method) && !method.getName().equals(getReferenceName())) { return method.getParameterList().getParameters()[0].getType(); } // 'class' property with explicit generic PsiClass containingClass = method.getContainingClass(); if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) && "getClass".equals(method.getName())) { return TypesUtil.createJavaLangClassType( PsiImplUtil.getQualifierType(this), getProject(), getResolveScope()); } return PsiUtil.getSmartReturnType(method); } if (resolved == null) { final PsiType fromClassRef = getTypeFromClassRef(this); if (fromClassRef != null) { return fromClassRef; } final PsiType fromMapAccess = getTypeFromMapAccess(this); if (fromMapAccess != null) { return fromMapAccess; } final PsiType fromSpreadOperator = getTypeFromSpreadOperator(this); if (fromSpreadOperator != null) { return fromSpreadOperator; } } return null; }
@NotNull public Class classToClass(@NotNull PsiClass psiClass) { Set<String> modifiers = modifiersListToModifiersSet(psiClass.getModifierList()); List<Field> fields = fieldsToFieldList(psiClass.getFields(), psiClass); List<Element> typeParameters = elementsToElementList(psiClass.getTypeParameters()); List<Type> implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes()); List<Type> extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes()); IdentifierImpl name = new IdentifierImpl(psiClass.getName()); List<Expression> baseClassParams = new LinkedList<Expression>(); List<Member> members = getMembers(psiClass); // we try to find super() call and generate class declaration like that: class A(name: String, i // : Int) : Base(name) SuperVisitor visitor = new SuperVisitor(); psiClass.accept(visitor); Collection<PsiExpressionList> resolvedSuperCallParameters = visitor.getResolvedSuperCallParameters(); if (resolvedSuperCallParameters.size() == 1) { baseClassParams.addAll( expressionsToExpressionList( resolvedSuperCallParameters.toArray(new PsiExpressionList[1])[0].getExpressions())); } // we create primary constructor from all non final fields and fields without initializers if (!psiClass.isEnum() && !psiClass.isInterface() && psiClass.getConstructors().length > 1 && getPrimaryConstructorForThisCase(psiClass) == null) { List<Field> finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields); Map<String, String> initializers = new HashMap<String, String>(); for (Member m : members) { // and modify secondaries if (m.getKind() == INode.Kind.CONSTRUCTOR) { Function f = (Function) m; if (!((Constructor) f).isPrimary()) { for (Field fo : finalOrWithEmptyInitializer) { String init = getDefaultInitializer(fo); initializers.put(fo.getIdentifier().toKotlin(), init); } List<Statement> newStatements = new LinkedList<Statement>(); for (Statement s : f.getBlock().getStatements()) { boolean isRemoved = false; if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) { AssignmentExpression assignmentExpression = (AssignmentExpression) s; if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) { for (Field fo : finalOrWithEmptyInitializer) { String id = fo.getIdentifier().toKotlin(); if (((CallChainExpression) assignmentExpression.getLeft()) .getIdentifier() .toKotlin() .endsWith("." + id)) { initializers.put(id, assignmentExpression.getRight().toKotlin()); isRemoved = true; } } } } if (!isRemoved) { newStatements.add(s); } } newStatements.add( 0, new DummyStringExpression( "val __ = " + createPrimaryConstructorInvocation( name.toKotlin(), finalOrWithEmptyInitializer, initializers))); f.setBlock(new Block(newStatements)); } } } members.add( new Constructor( Identifier.EMPTY_IDENTIFIER, Collections.<String>emptySet(), new ClassType(name), Collections.<Element>emptyList(), new ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)), new Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)), true)); } if (psiClass.isInterface()) { return new Trait( this, name, modifiers, typeParameters, extendsTypes, Collections.<Expression>emptyList(), implementsTypes, members); } if (psiClass.isEnum()) { return new Enum( this, name, modifiers, typeParameters, Collections.<Type>emptyList(), Collections.<Expression>emptyList(), implementsTypes, members); } return new Class( this, name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members); }
@SuppressWarnings({"HardCodedStringLiteral"}) private static String generateClassInfo(PsiClass aClass) { StringBuilder buffer = new StringBuilder(); GroovyFile file = (GroovyFile) aClass.getContainingFile(); String packageName = file.getPackageName(); if (packageName.length() > 0) { buffer.append(packageName).append("\n"); } final String classString = aClass.isInterface() ? "interface" : aClass instanceof PsiTypeParameter ? "type parameter" : aClass.isEnum() ? "enum" : "class"; buffer.append(classString).append(" ").append(aClass.getName()); if (aClass.hasTypeParameters()) { PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); buffer.append("<"); for (int i = 0; i < typeParameters.length; i++) { if (i > 0) buffer.append(", "); PsiTypeParameter tp = typeParameters[i]; buffer.append(tp.getName()); PsiClassType[] refs = tp.getExtendsListTypes(); if (refs.length > 0) { buffer.append(" extends "); for (int j = 0; j < refs.length; j++) { if (j > 0) buffer.append(" & "); appendTypeString(buffer, refs[j], aClass); } } } buffer.append(">"); } PsiClassType[] refs = aClass.getExtendsListTypes(); if (refs.length > 0 || !aClass.isInterface() && !CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) { buffer.append(" extends "); if (refs.length == 0) { buffer.append("Object"); } else { for (int i = 0; i < refs.length; i++) { if (i > 0) buffer.append(", "); appendTypeString(buffer, refs[i], aClass); } } } refs = aClass.getImplementsListTypes(); if (refs.length > 0) { buffer.append("\nimplements "); for (int i = 0; i < refs.length; i++) { if (i > 0) buffer.append(", "); appendTypeString(buffer, refs[i], aClass); } } return buffer.toString(); }