public SrcClass makeSrcClass( String fqn, PsiClass psiClass, ManModule module ) { SrcClass srcClass = new SrcClass( fqn, getKind( psiClass ) ) .modifiers( getModifiers( psiClass.getModifierList() ) ); for( PsiTypeParameter typeVar : psiClass.getTypeParameters() ) { srcClass.addTypeVar( new SrcType( makeTypeVar( typeVar ) ) ); } setSuperTypes( srcClass, psiClass ); for( PsiMethod psiMethod : psiClass.getMethods() ) { addMethod( srcClass, psiMethod ); } for( PsiField psiField : psiClass.getFields() ) { addField( srcClass, psiField ); } for( PsiClass psiInnerClass : psiClass.getInnerClasses() ) { addInnerClass( srcClass, psiInnerClass, module ); } return srcClass; }
public static String makeTypeVar( PsiTypeParameter typeVar ) { StringBuilder sb = new StringBuilder(); sb.append( typeVar.getName() ); PsiJavaCodeReferenceElement[] bounds = typeVar.getExtendsList().getReferenceElements(); if( bounds.length > 0 ) { sb.append( " extends " ); for( int i = 0; i < bounds.length; i++ ) { if( i > 0 ) { sb.append( " & " ); } sb.append( bounds[i].getCanonicalText() ); } } return sb.toString(); }
public static PsiType makeDefaultParameterizedType( PsiType type ) { if( type != null && !isStructuralInterface( type ) && !isParameterizedType( type ) && isGenericType( type ) ) { PsiTypeParameter[] typeVars = type( type ).getTypeParameters(); PsiType[] boundingTypes = new PsiType[typeVars.length]; for( int i = 0; i < boundingTypes.length; i++ ) { PsiTypeParameter typeVar = typeVars[i]; boundingTypes[i] = type( getBoundingType( typeVar ) ); if( isRecursiveType( (PsiClassType)type( typeVar ), boundingTypes[i] ) ) { return type; } } if( boundingTypes.length == 0 ) { return type; } type = parameterizeType( (PsiClassType)type, boundingTypes ); } return type; }
private static TypeVarToTypeMap mapActualTypeByVarName( PsiType ownersType ) { TypeVarToTypeMap actualParamByVarName = new TypeVarToTypeMap(); PsiTypeParameter[] vars = type( ownersType ).getTypeParameters(); if( vars != null ) { PsiType[] paramArgs = ((PsiClassType)ownersType).getParameters(); for( int i = 0; i < vars.length; i++ ) { PsiClassType typeVar = (PsiClassType)type( vars[i] ); if( paramArgs.length > i ) { actualParamByVarName.put( typeVar, paramArgs[i] ); } } } return actualParamByVarName; }
@Override public void visitClass(@NotNull PsiClass aClass) { if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) { return; } if (aClass instanceof PsiTypeParameter) { return; } if (!aClass.hasModifierProperty(PsiModifier.ABSTRACT)) { return; } if (!InheritanceUtil.hasOneInheritor(aClass)) { return; } registerClassError(aClass); }
@Override public void visitClass(@NotNull PsiClass aClass) { if (aClass.isInterface() || aClass.isAnnotationType() || aClass instanceof PsiTypeParameter) { return; } if (!CloneUtils.isCloneable(aClass)) { return; } final PsiMethod[] methods = aClass.getMethods(); for (final PsiMethod method : methods) { if (CloneUtils.isClone(method)) { if (ControlFlowUtils.methodAlwaysThrowsException(method)) { return; } } } registerClassError(aClass); }
@Override public void visitClass(@NotNull PsiClass aClass) { if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) { return; } if (aClass instanceof PsiTypeParameter || !SerializationUtils.isSerializable(aClass)) { return; } final PsiMethod[] methods = aClass.getMethods(); for (final PsiMethod method : methods) { if (!SerializationUtils.isReadObject(method)) { continue; } if (ControlFlowUtils.methodAlwaysThrowsException(method)) { return; } else { break; } } if (ignoreThrowable && InheritanceUtil.isInheritor(aClass, false, "java.lang.Throwable")) { return; } registerClassError(aClass); }
@Override public void visitClass(@NotNull PsiClass aClass) { if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) { return; } if (aClass instanceof PsiTypeParameter || !SerializationUtils.isSerializable(aClass)) { return; } final PsiMethod[] methods = aClass.findMethodsByName("writeObject", true); for (final PsiMethod method : methods) { if (!SerializationUtils.isWriteObject(method)) { continue; } if (ControlFlowUtils.methodAlwaysThrowsException((PsiMethod)method.getNavigationElement())) { return; } else { break; } } if (ignoreThrowable && InheritanceUtil.isInheritor(aClass, false, "java.lang.Throwable")) { return; } registerClassError(aClass); }
@Override public void visitClass(@NotNull PsiClass aClass) { // no call to super, so it doesn't drill down into inner classes if (aClass instanceof PsiTypeParameter) { return; } final String className = aClass.getName(); if (className == null) { return; } @NonNls final String exception = "Exception"; if (className.endsWith(exception)) { return; } if (!InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_EXCEPTION)) { return; } registerClassError(aClass); }
@Override public void visitClass(@NotNull PsiClass aClass) { if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) { return; } if (aClass instanceof PsiTypeParameter) { return; } if (aClass.hasModifierProperty(PsiModifier.ABSTRACT) && isInspectionEnabled("AbstractClassNamingConvention", aClass)) { return; } final String name = aClass.getName(); if (name == null || isValid(name)) { return; } registerClassError(aClass, name); }
@Override public void visitTypeParameter(PsiTypeParameter parameter) { super.visitTypeParameter(parameter); final String name = parameter.getName(); if (name == null) { return; } if (isValid(name)) { return; } final PsiIdentifier nameIdentifier = parameter.getNameIdentifier(); if (nameIdentifier == null) { return; } registerError(nameIdentifier, name); }
@Override public void visitClass(@NotNull PsiClass aClass) { // no call to super, so it doesn't drill down if (aClass.isInterface() || aClass.isEnum() || aClass.isAnnotationType()) { return; } if (aClass instanceof PsiTypeParameter) { return; } if (m_ignoreClassesWithNoConstructors && !classHasConstructor(aClass)) { return; } if (classHasNoArgConstructor(aClass)) { return; } registerClassError(aClass); }
@Override public void visitClass(@NotNull PsiClass aClass) { // note: no call to super if (aClass.isEnum()) { return; } if (aClass instanceof PsiTypeParameter) { return; } final int inheritanceDepth = getInheritanceDepth(aClass, new HashSet<PsiClass>()); if (inheritanceDepth <= getLimit()) { return; } registerClassError(aClass, Integer.valueOf(inheritanceDepth)); }
@Nullable @Override public PsiClass findClass(@NotNull PsiElement place) { if (place.getLanguage() == GroovyLanguage.INSTANCE) { PsiClass containingClass = PsiTreeUtil.getParentOfType(place, PsiClass.class, false); while (containingClass instanceof PsiTypeParameter) { containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class); } if (containingClass != null) return containingClass; PsiFile file = place.getContainingFile(); if (file instanceof GroovyFile && ((GroovyFile)file).isScript()) { return ((GroovyFile)file).getScriptClass(); } } return null; }
@Nullable @Override public GrTypeArgumentList findElementForParameterInfo(@NotNull CreateParameterInfoContext context) { final GrTypeArgumentList parameterList = ParameterInfoUtils.findParentOfType(context.getFile(), context.getOffset(), GrTypeArgumentList.class); if (parameterList != null) { if (!(parameterList.getParent() instanceof GrCodeReferenceElement)) return null; final GrCodeReferenceElement ref = ((GrCodeReferenceElement)parameterList.getParent()); final PsiElement resolved = ref.resolve(); if (!(resolved instanceof PsiTypeParameterListOwner)) return null; final PsiTypeParameter[] typeParams = ((PsiTypeParameterListOwner)resolved).getTypeParameters(); if (typeParams.length == 0) return null; context.setItemsToShow(typeParams); return parameterList; } return null; }
@Override public void visitClass(@NotNull PsiClass aClass) { if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) { return; } if (aClass instanceof PsiTypeParameter) { return; } final String name = aClass.getName(); if (name == null) { return; } if (isValid(name)) { return; } registerClassError(aClass, name); }
@Nullable @Override public GrTypeArgumentList findElementForParameterInfo(CreateParameterInfoContext context) { final GrTypeArgumentList parameterList = ParameterInfoUtils.findParentOfType(context.getFile(), context.getOffset(), GrTypeArgumentList.class); if (parameterList != null) { if (!(parameterList.getParent() instanceof GrCodeReferenceElement)) return null; final GrCodeReferenceElement ref = ((GrCodeReferenceElement)parameterList.getParent()); final PsiElement resolved = ref.resolve(); if (!(resolved instanceof PsiTypeParameterListOwner)) return null; final PsiTypeParameter[] typeParams = ((PsiTypeParameterListOwner)resolved).getTypeParameters(); if (typeParams.length == 0) return null; context.setItemsToShow(typeParams); return parameterList; } return null; }
@NotNull private String calculateCallExpressionForMethod(@NotNull PsiMethod psiMethod, @NotNull PsiClass builderClass) { final PsiClass containingClass = psiMethod.getContainingClass(); StringBuilder className = new StringBuilder(); if (null != containingClass) { className.append(containingClass.getName()).append("."); if (!psiMethod.isConstructor() && !psiMethod.hasModifierProperty(PsiModifier.STATIC)) { className.append("this."); } if (builderClass.hasTypeParameters()) { className.append('<'); for (PsiTypeParameter typeParameter : builderClass.getTypeParameters()) { className.append(typeParameter.getName()).append(','); } className.setCharAt(className.length() - 1, '>'); } } return className + psiMethod.getName(); }
/** * Creates a PsiType for a PsiClass enriched with generic substitution information if available */ @NotNull private static PsiType getTypeWithGenerics(@NotNull PsiClass psiClass, @NotNull PsiTypeParameter... classTypeParameters) { PsiType result; final PsiElementFactory factory = JavaPsiFacade.getElementFactory(psiClass.getProject()); if (classTypeParameters.length > 0) { Map<PsiTypeParameter, PsiType> substitutionMap = new HashMap<PsiTypeParameter, PsiType>(); for (PsiTypeParameter typeParameter : classTypeParameters) { substitutionMap.put(typeParameter, factory.createType(typeParameter)); } result = factory.createType(psiClass, factory.createSubstitutor(substitutionMap)); } else { result = factory.createType(psiClass); } return result; }
@NotNull public static PsiType[] extractTypeParameters(@NotNull PsiType psiType, @NotNull PsiManager psiManager) { if (!(psiType instanceof PsiClassType)) { return PsiType.EMPTY_ARRAY; } final PsiClassType classType = (PsiClassType) psiType; final PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics(); final PsiClass psiClass = classResolveResult.getElement(); if (psiClass == null) { return PsiType.EMPTY_ARRAY; } final PsiSubstitutor psiSubstitutor = classResolveResult.getSubstitutor(); final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters(); final PsiType[] psiTypes = PsiType.createArray(typeParameters.length); for (int i = 0; i < typeParameters.length; i++) { PsiType psiSubstituteKeyType = psiSubstitutor.substitute(typeParameters[i]); if (null == psiSubstituteKeyType) { psiSubstituteKeyType = PsiType.getJavaLangObject(psiManager, GlobalSearchScope.allScope(psiManager.getProject())); } psiTypes[i] = psiSubstituteKeyType; } return psiTypes; }
@NotNull private static PsiSubstitutor mirrorSubstitutor(@NotNull PsiClass from, @NotNull final PsiClass to, @NotNull PsiSubstitutor substitutor) { Iterator<PsiTypeParameter> baseParams = PsiUtil.typeParametersIterator(to); Iterator<PsiTypeParameter> candidateParams = PsiUtil.typeParametersIterator(from); PsiSubstitutor answer = PsiSubstitutor.EMPTY; while(baseParams.hasNext()) { // if equivalent classes "from" and "to" have different number of type parameters, then treat "to" as a raw type if(!candidateParams.hasNext()) { return JavaClassSupersImpl.createRawSubstitutor(to); } answer = answer.put(baseParams.next(), substitutor.substitute(candidateParams.next())); } return answer; }
private static String getName(final PsiClass psiClass, final LookupElement item, boolean diamond, @NotNull PsiSubstitutor substitutor) { String forced = item instanceof JavaPsiClassReferenceElement ? ((JavaPsiClassReferenceElement) item).getForcedPresentableName() : item instanceof PsiTypeLookupItem ? ((PsiTypeLookupItem) item).getForcedPresentableName() : null; if(forced != null) { return forced; } String name = PsiUtilCore.getName(psiClass); if(diamond) { return name + "<>"; } if(substitutor != PsiSubstitutor.EMPTY) { final PsiTypeParameter[] params = psiClass.getTypeParameters(); if(params.length > 0) { return name + formatTypeParameters(substitutor, params); } } return StringUtil.notNullize(name); }
@Override public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException { if(!(psiElement instanceof PsiClass) || psiElement instanceof PsiTypeParameter) { return; } PsiClass psiClass = (PsiClass) psiElement; if(psiClass.getLBrace() == null) { int offset = psiClass.getTextRange().getEndOffset(); editor.getDocument().insertString(offset, "{\n}"); editor.getCaretModel().moveToOffset(offset); } }
@Override public void visitClass(@NotNull PsiClass aClass) { if (aClass.isInterface() || aClass.isEnum() || aClass.isAnnotationType() || aClass instanceof PsiTypeParameter) { return; } if (aClass.hasModifierProperty(PsiModifier.ABSTRACT)) { return; } if (!isExternalizable(aClass)) { return; } final PsiMethod constructor = getNoArgConstructor(aClass); if (constructor == null) { if (aClass.hasModifierProperty(PsiModifier.PUBLIC)) { return; } } else { if (constructor.hasModifierProperty(PsiModifier.PUBLIC)) { return; } } registerClassError(aClass, aClass, constructor); }