/** * 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; }
@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; }
@NotNull public static PsiElement[] findSuperElements(@NotNull PsiElement element) { if (element instanceof PsiClass) { PsiClass aClass = (PsiClass) element; List<PsiClass> allSupers = new ArrayList<>(Arrays.asList(aClass.getSupers())); for (Iterator<PsiClass> iterator = allSupers.iterator(); iterator.hasNext(); ) { PsiClass superClass = iterator.next(); if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) iterator.remove(); } return allSupers.toArray(new PsiClass[allSupers.size()]); } if (element instanceof PsiMethod) { PsiMethod method = (PsiMethod) element; if (method.isConstructor()) { PsiMethod constructorInSuper = PsiSuperMethodUtil.findConstructorInSuper(method); if (constructorInSuper != null) { return new PsiMethod[] {constructorInSuper}; } } else { PsiMethod[] superMethods = method.findSuperMethods(false); if (superMethods.length == 0) { PsiMethod superMethod = getSiblingInheritedViaSubClass(method); if (superMethod != null) { superMethods = new PsiMethod[] {superMethod}; } } return superMethods; } } return PsiElement.EMPTY_ARRAY; }
public static boolean isAssignableFrom( final String baseQualifiedName, ReferenceType checkedType) { if (CommonClassNames.JAVA_LANG_OBJECT.equals(baseQualifiedName)) { return true; } return getSuperClass(baseQualifiedName, checkedType) != null; }
private static boolean canHaveSuperMethod( PsiMethod method, boolean checkAccess, boolean allowStaticMethod) { if (method.isConstructor()) return false; if (!allowStaticMethod && method.hasModifierProperty(PsiModifier.STATIC)) return false; if (checkAccess && method.hasModifierProperty(PsiModifier.PRIVATE)) return false; PsiClass parentClass = method.getContainingClass(); return parentClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(parentClass.getQualifiedName()); }
private int substituteToTypeParameters( PsiTypeElement typeElement, PsiTypeElement inplaceTypeElement, PsiType[] paramVals, PsiTypeParameter[] params, TemplateBuilder builder, PsiSubstitutor rawingSubstitutor, boolean toplevel) { PsiType type = inplaceTypeElement.getType(); List<PsiType> types = new ArrayList<>(); for (int i = 0; i < paramVals.length; i++) { PsiType val = paramVals[i]; if (val == null) return SUBSTITUTED_NONE; if (type.equals(val)) { types.add(myFactory.createType(params[i])); } } if (!types.isEmpty()) { Project project = typeElement.getProject(); PsiType substituted = rawingSubstitutor.substitute(type); if (!CommonClassNames.JAVA_LANG_OBJECT.equals(substituted.getCanonicalText()) && (toplevel || substituted.equals(type))) { types.add(substituted); } builder.replaceElement( typeElement, new TypeExpression(project, types.toArray(PsiType.createArray(types.size())))); return toplevel ? SUBSTITUTED_IN_REF : SUBSTITUTED_IN_PARAMETERS; } boolean substituted = false; PsiJavaCodeReferenceElement ref = typeElement.getInnermostComponentReferenceElement(); PsiJavaCodeReferenceElement inplaceRef = inplaceTypeElement.getInnermostComponentReferenceElement(); if (ref != null) { LOG.assertTrue(inplaceRef != null); PsiTypeElement[] innerTypeElements = ref.getParameterList().getTypeParameterElements(); PsiTypeElement[] inplaceInnerTypeElements = inplaceRef.getParameterList().getTypeParameterElements(); for (int i = 0; i < innerTypeElements.length; i++) { substituted |= substituteToTypeParameters( innerTypeElements[i], inplaceInnerTypeElements[i], paramVals, params, builder, rawingSubstitutor, false) != SUBSTITUTED_NONE; } } return substituted ? SUBSTITUTED_IN_PARAMETERS : SUBSTITUTED_NONE; }
private static boolean canHaveSiblingSuper(PsiMethod method, PsiClass containingClass) { return containingClass != null && PsiUtil.canBeOverriden(method) && !method.hasModifierProperty(PsiModifier.ABSTRACT) && !method.hasModifierProperty(PsiModifier.NATIVE) && method.hasModifierProperty(PsiModifier.PUBLIC) && !containingClass.isInterface() && !CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()); }
private static boolean overridesPublicObjectMethod(PsiMethod psiMethod) { boolean overrideObject = false; for (PsiMethod superMethod : psiMethod.findDeepestSuperMethods()) { final PsiClass containingClass = superMethod.getContainingClass(); if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { if (superMethod.hasModifierProperty(PsiModifier.PUBLIC)) { overrideObject = true; break; } } } return overrideObject; }
private static boolean overridesObjectOrGroovyObject(PsiMethod method) { final String name = method.getName(); if (!OBJECT_METHODS.contains(name) && !GROOVY_OBJECT_METHODS.contains(name)) return false; final PsiMethod superMethod = PsiSuperMethodImplUtil.findDeepestSuperMethod(method); if (superMethod == null) return false; final PsiClass superClass = superMethod.getContainingClass(); if (superClass == null) return false; final String qname = superClass.getQualifiedName(); return CommonClassNames.JAVA_LANG_OBJECT.equals(qname) || GroovyCommonClassNames.GROOVY_OBJECT.equals(qname); }
private static void processClassInner( PsiClassType type, PsiSubstitutor superClassSubstitutor, boolean shouldProcessDeprecated, List<PsiMethod> result, GrTypeDefinition classToDelegateTo, Set<PsiClass> processedWithoutDeprecated, Set<PsiClass> processedAll, boolean keepParameterAnnotationsNew) { final PsiClassType.ClassResolveResult resolveResult = type.resolveGenerics(); final PsiClass psiClass = resolveResult.getElement(); if (psiClass == null) return; final String qname = psiClass.getQualifiedName(); if (CommonClassNames.JAVA_LANG_OBJECT.equals(qname)) return; if (GroovyCommonClassNames.GROOVY_OBJECT.equals(qname)) return; if (GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT.equals(qname)) return; final PsiSubstitutor substitutor = TypesUtil.composeSubstitutors(resolveResult.getSubstitutor(), superClassSubstitutor); if (processedAll.contains(psiClass)) return; if (!shouldProcessDeprecated && processedWithoutDeprecated.contains(psiClass)) return; if (shouldProcessDeprecated) { processedAll.add(psiClass); } else { processedWithoutDeprecated.add(psiClass); } collectMethods( psiClass, substitutor, shouldProcessDeprecated, classToDelegateTo, result, keepParameterAnnotationsNew); process( psiClass, substitutor, shouldProcessDeprecated, processedWithoutDeprecated, processedAll, result, classToDelegateTo, keepParameterAnnotationsNew); }
private boolean hasGoodToString(PsiClass aClass) { final PsiMethod[] methods = aClass.findMethodsByName(HardcodedMethodConstants.TO_STRING, true); for (PsiMethod method : methods) { final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) { continue; } final String name = containingClass.getQualifiedName(); if (CommonClassNames.JAVA_LANG_OBJECT.equals(name)) { continue; } final PsiParameterList parameterList = method.getParameterList(); if (parameterList.getParametersCount() == 0) { return true; } } return false; }
private static boolean isSuperMethod( PsiClass aClass, HierarchicalMethodSignature hierarchicalMethodSignature, HierarchicalMethodSignature superSignatureHierarchical) { PsiMethod superMethod = superSignatureHierarchical.getMethod(); PsiClass superClass = superMethod.getContainingClass(); PsiClass containingClass = hierarchicalMethodSignature.getMethod().getContainingClass(); if (!superMethod.isConstructor()) { if (!aClass.equals(superClass)) { if (PsiUtil.isAccessible(aClass.getProject(), superMethod, aClass, aClass)) { if (MethodSignatureUtil.isSubsignature( superSignatureHierarchical, hierarchicalMethodSignature)) { if (superClass != null) { if (superClass.isInterface() || CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) { if (superMethod.hasModifierProperty(PsiModifier.DEFAULT) || hierarchicalMethodSignature .getMethod() .hasModifierProperty(PsiModifier.DEFAULT)) { return !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true); } return true; } if (containingClass != null) { if (containingClass.isInterface()) { return false; } if (!aClass.isInterface() && !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true)) { return true; } } } } } } } return false; }
@NotNull @Override public PsiClassType createTypeByFQClassName( @NotNull final String qName, @NotNull final GlobalSearchScope resolveScope) { if (CommonClassNames.JAVA_LANG_OBJECT.equals(qName)) { PsiClassType cachedObjectType = myCachedObjectType.get(resolveScope); if (cachedObjectType != null) { return cachedObjectType; } PsiClass aClass = JavaPsiFacade.getInstance(myManager.getProject()) .findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope); if (aClass != null) { cachedObjectType = new PsiImmediateClassType(aClass, PsiSubstitutor.EMPTY); cachedObjectType = myCachedObjectType.cacheOrGet(resolveScope, cachedObjectType); return cachedObjectType; } } return new PsiClassReferenceType( createReferenceElementByFQClassName(qName, resolveScope), null); }
@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]; }
public static HighlightInfo checkClashesWithSuperMethods(@NotNull PsiAnnotationMethod psiMethod) { final PsiIdentifier nameIdentifier = psiMethod.getNameIdentifier(); if (nameIdentifier != null) { final PsiMethod[] methods = psiMethod.findDeepestSuperMethods(); for (PsiMethod method : methods) { final PsiClass containingClass = method.getContainingClass(); if (containingClass != null) { final String qualifiedName = containingClass.getQualifiedName(); if (CommonClassNames.JAVA_LANG_OBJECT.equals(qualifiedName) || CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION.equals(qualifiedName)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(nameIdentifier) .descriptionAndTooltip( "@interface member clashes with '" + JavaHighlightUtil.formatMethod(method) + "' in " + HighlightUtil.formatClass(containingClass)) .create(); } } } } return null; }
private static void addInheritorClassLiterals( final PsiFile context, Condition<String> shortNameCondition, final PsiType classParameter, final Consumer<LookupElement> result, PrefixMatcher matcher) { final String canonicalText = classParameter.getCanonicalText(); if (CommonClassNames.JAVA_LANG_OBJECT.equals(canonicalText) && StringUtil.isEmpty(matcher.getPrefix())) { return; } CodeInsightUtil.processSubTypes( classParameter, context, true, shortNameCondition, new Consumer<PsiType>() { @Override public void consume(PsiType type) { addClassLiteralLookupElement(type, result, context); } }); }
@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; }
@Nullable private PsiType getNominalTypeInner(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); } } if (getParent() instanceof GrReferenceExpression || PsiUtil.isSuperReference(this)) { 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( GrReferenceResolveUtil.getQualifierType(this), getProject(), getResolveScope()); } return PsiUtil.getSmartReturnType(method); } if (resolved instanceof GrReferenceExpression) { PsiElement parent = resolved.getParent(); if (parent instanceof GrAssignmentExpression) { GrAssignmentExpression assignment = (GrAssignmentExpression) parent; if (resolved.equals(assignment.getLValue())) { GrExpression rValue = assignment.getRValue(); if (rValue != null) { PsiType rType = rValue.getType(); if (rType != null) { return rType; } } } } } 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; }
@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(); }
protected void checkSameSignatures(@NotNull List<CandidateInfo> conflicts) { // candidates should go in order of class hierarchy traversal // in order for this to work Map<MethodSignature, CandidateInfo> signatures = new THashMap<MethodSignature, CandidateInfo>(conflicts.size()); Set<PsiMethod> superMethods = new HashSet<PsiMethod>(); for (CandidateInfo conflict : conflicts) { final PsiMethod method = ((MethodCandidateInfo) conflict).getElement(); for (HierarchicalMethodSignature methodSignature : method.getHierarchicalMethodSignature().getSuperSignatures()) { final PsiMethod superMethod = methodSignature.getMethod(); final PsiClass aClass = superMethod.getContainingClass(); if (aClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) { superMethods.add(superMethod); } } } nextConflict: for (int i = 0; i < conflicts.size(); i++) { ProgressManager.checkCanceled(); CandidateInfo info = conflicts.get(i); PsiMethod method = (PsiMethod) info.getElement(); if (!method.hasModifierProperty(PsiModifier.STATIC) && superMethods.contains(method)) { conflicts.remove(i); i--; continue; } PsiClass class1 = method.getContainingClass(); PsiSubstitutor infoSubstitutor = ((MethodCandidateInfo) info).getSubstitutor(false); MethodSignature signature = method.getSignature(infoSubstitutor); CandidateInfo existing = signatures.get(signature); if (existing == null) { signatures.put(signature, info); continue; } PsiMethod existingMethod = (PsiMethod) existing.getElement(); PsiClass existingClass = existingMethod.getContainingClass(); if (class1 != null && existingClass != null) { // prefer interface methods to methods from Object if (class1.isInterface() && CommonClassNames.JAVA_LANG_OBJECT.equals(existingClass.getQualifiedName())) { signatures.put(signature, info); continue; } else if (existingClass.isInterface() && CommonClassNames.JAVA_LANG_OBJECT.equals(class1.getQualifiedName())) { conflicts.remove(info); i--; continue; } } if (method == existingMethod) { PsiElement scope1 = info.getCurrentFileResolveScope(); PsiElement scope2 = existing.getCurrentFileResolveScope(); if (scope1 instanceof PsiClass && scope2 instanceof PsiClass && PsiTreeUtil.isAncestor(scope1, scope2, true) && !existing .isAccessible()) { // prefer methods from outer class to inaccessible base class // methods signatures.put(signature, info); continue; } } // filter out methods with incorrect inferred bounds (for unrelated methods only) boolean existingTypeParamAgree = areTypeParametersAgree(existing); boolean infoTypeParamAgree = areTypeParametersAgree(info); if (existingTypeParamAgree && !infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(method, existingMethod)) { conflicts.remove(i); i--; continue; } if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) { signatures.put(signature, info); int index = conflicts.indexOf(existing); conflicts.remove(index); i--; continue; } if (InheritanceUtil.isInheritorOrSelf(class1, existingClass, true) || InheritanceUtil.isInheritorOrSelf(existingClass, class1, true)) { PsiParameter[] parameters = method.getParameterList().getParameters(); final PsiParameter[] existingParameters = existingMethod.getParameterList().getParameters(); for (int i1 = 0, parametersLength = parameters.length; i1 < parametersLength; i1++) { if (parameters[i1].getType() instanceof PsiArrayType && !(existingParameters[i1].getType() instanceof PsiArrayType)) { // prefer more specific type signatures.put(signature, info); continue nextConflict; } } PsiType returnType1 = method.getReturnType(); PsiType returnType2 = existingMethod.getReturnType(); if (returnType1 != null && returnType2 != null) { returnType1 = infoSubstitutor.substitute(returnType1); returnType2 = ((MethodCandidateInfo) existing).getSubstitutor(false).substitute(returnType2); if (!returnType1.equals(returnType2) && returnType1.isAssignableFrom(returnType2)) { conflicts.remove(i); i--; continue; } } // prefer derived class signatures.put(signature, info); } else { final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(myArgumentsList, PsiMethodCallExpression.class); if (methodCallExpression != null) { final PsiReferenceExpression expression = methodCallExpression.getMethodExpression(); final PsiExpression qualifierExpression = expression.getQualifierExpression(); PsiClass currentClass; if (qualifierExpression != null) { currentClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()); } else { currentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); } if (currentClass != null && existingClass != null && class1 != null) { final PsiSubstitutor eSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor( existingClass, currentClass, PsiSubstitutor.EMPTY, null); final PsiSubstitutor cSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor( class1, currentClass, PsiSubstitutor.EMPTY, null); if (eSubstitutor != null && cSubstitutor != null && MethodSignatureUtil.areSignaturesEqual( existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) { final PsiType returnType = eSubstitutor.substitute(existingMethod.getReturnType()); final PsiType returnType1 = cSubstitutor.substitute(method.getReturnType()); if (returnType != null && returnType1 != null && !returnType1.equals(returnType)) { if (TypeConversionUtil.isAssignable(returnType, returnType1, false)) { if (class1.isInterface() && !existingClass.isInterface()) continue; conflicts.remove(existing); } else { if (!TypeConversionUtil.isAssignable(returnType1, returnType, false)) continue; conflicts.remove(i); } i--; break; } } } } } } }
@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; }