@Nullable
 private static PsiType getTypeFromMapAccess(@NotNull GrReferenceExpressionImpl ref) {
   // map access
   GrExpression qualifier = ref.getQualifierExpression();
   if (qualifier != null) {
     PsiType qType = qualifier.getNominalType();
     if (qType instanceof PsiClassType) {
       PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
       PsiClass clazz = qResult.getElement();
       if (clazz != null) {
         PsiClass mapClass =
             JavaPsiFacade.getInstance(ref.getProject())
                 .findClass(CommonClassNames.JAVA_UTIL_MAP, ref.getResolveScope());
         if (mapClass != null && mapClass.getTypeParameters().length == 2) {
           PsiSubstitutor substitutor =
               TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
           if (substitutor != null) {
             return TypeConversionUtil.erasure(
                 substitutor.substitute(mapClass.getTypeParameters()[1]));
           }
         }
       }
     }
   }
   return null;
 }
 @Nullable
 private static PsiType getInferredTypes(
     GrReferenceExpressionImpl refExpr, @Nullable PsiElement resolved) {
   final GrExpression qualifier = refExpr.getQualifier();
   if (qualifier == null && !(resolved instanceof PsiClass)) {
     return TypeInferenceHelper.getCurrentContext().getVariableType(refExpr);
   } else if (qualifier != null) {
     // map access
     PsiType qType = qualifier.getType();
     if (qType instanceof PsiClassType && !(qType instanceof GrMapType)) {
       PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
       PsiClass clazz = qResult.getElement();
       if (clazz != null) {
         PsiClass mapClass =
             JavaPsiFacade.getInstance(refExpr.getProject())
                 .findClass(CommonClassNames.JAVA_UTIL_MAP, refExpr.getResolveScope());
         if (mapClass != null && mapClass.getTypeParameters().length == 2) {
           PsiSubstitutor substitutor =
               TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
           if (substitutor != null) {
             return TypeConversionUtil.erasure(
                 substitutor.substitute(mapClass.getTypeParameters()[1]));
           }
         }
       }
     }
   }
   return null;
 }
  public String calcGenerics(@NotNull PsiElement context, InsertionContext insertionContext) {
    if (insertionContext.getCompletionChar() == '<') {
      return "";
    }

    assert context.isValid();
    if (myDiamond) {
      return "<>";
    }

    if (getObject() instanceof PsiClass) {
      PsiClass psiClass = (PsiClass) getObject();
      PsiResolveHelper resolveHelper =
          JavaPsiFacade.getInstance(psiClass.getProject()).getResolveHelper();
      PsiSubstitutor substitutor = getSubstitutor();
      StringBuilder builder = new StringBuilder();
      for (PsiTypeParameter parameter : psiClass.getTypeParameters()) {
        PsiType substitute = substitutor.substitute(parameter);
        if (substitute == null
            || (PsiUtil.resolveClassInType(substitute) == parameter
                && resolveHelper.resolveReferencedClass(parameter.getName(), context)
                    != CompletionUtil.getOriginalOrSelf(parameter))) {
          return "";
        }
        if (builder.length() > 0) {
          builder.append(", ");
        }
        builder.append(substitute.getCanonicalText());
      }
      if (builder.length() > 0) {
        return "<" + builder + ">";
      }
    }
    return "";
  }
  @Nullable
  static Pair<PsiClass, Integer> getTypeParameterInfo(PsiElement context) {
    final PsiReferenceParameterList parameterList =
        PsiTreeUtil.getContextOfType(context, PsiReferenceParameterList.class, true);
    if (parameterList == null) return null;

    PsiElement parent = parameterList.getParent();
    if (!(parent instanceof PsiJavaCodeReferenceElement)) return null;

    final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement) parent;
    final int parameterIndex;

    int index = 0;
    final PsiTypeElement typeElement =
        PsiTreeUtil.getContextOfType(context, PsiTypeElement.class, true);
    if (typeElement != null) {
      final PsiTypeElement[] elements =
          referenceElement.getParameterList().getTypeParameterElements();
      while (index < elements.length) {
        final PsiTypeElement element = elements[index++];
        if (element == typeElement) break;
      }
    }
    parameterIndex = index - 1;

    if (parameterIndex < 0) return null;
    final PsiElement target = referenceElement.resolve();
    if (!(target instanceof PsiClass)) return null;

    final PsiClass referencedClass = (PsiClass) target;
    final PsiTypeParameter[] typeParameters = referencedClass.getTypeParameters();
    if (typeParameters.length <= parameterIndex) return null;

    return Pair.create(referencedClass, parameterIndex);
  }
  private static void addInheritors(
      CompletionParameters parameters,
      final CompletionResultSet resultSet,
      final PsiClass referencedClass,
      final int parameterIndex) {
    final List<PsiClassType> typeList =
        Collections.singletonList(
            (PsiClassType)
                TypeConversionUtil.typeParameterErasure(
                    referencedClass.getTypeParameters()[parameterIndex]));
    JavaInheritorsGetter.processInheritors(
        parameters,
        typeList,
        resultSet.getPrefixMatcher(),
        new Consumer<PsiType>() {
          @Override
          public void consume(final PsiType type) {
            final PsiClass psiClass = PsiUtil.resolveClassInType(type);
            if (psiClass == null) return;

            resultSet.addElement(
                TailTypeDecorator.withTail(
                    new JavaPsiClassReferenceElement(psiClass),
                    getTail(parameterIndex == referencedClass.getTypeParameters().length - 1)));
          }
        });
  }
  /**
   * 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;
  }
  public static PsiType eliminateWildcards(PsiType type, final boolean eliminateInTypeArguments) {
    if (eliminateInTypeArguments && type instanceof PsiClassType) {
      PsiClassType classType = (PsiClassType) type;
      JavaResolveResult resolveResult = classType.resolveGenerics();
      PsiClass aClass = (PsiClass) resolveResult.getElement();
      if (aClass != null) {
        PsiManager manager = aClass.getManager();
        PsiTypeParameter[] typeParams = aClass.getTypeParameters();
        Map<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
        for (PsiTypeParameter typeParam : typeParams) {
          PsiType substituted = resolveResult.getSubstitutor().substitute(typeParam);
          if (substituted instanceof PsiWildcardType) {
            substituted = ((PsiWildcardType) substituted).getBound();
            if (substituted == null)
              substituted = TypeConversionUtil.typeParameterErasure(typeParam);
          }
          map.put(typeParam, substituted);
        }

        PsiElementFactory factory =
            JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
        PsiSubstitutor substitutor = factory.createSubstitutor(map);
        type = factory.createType(aClass, substitutor);
      }
    } else if (type instanceof PsiArrayType) {
      return eliminateWildcards(((PsiArrayType) type).getComponentType(), false).createArrayType();
    } else if (type instanceof PsiWildcardType) {
      final PsiType bound = ((PsiWildcardType) type).getBound();
      return bound != null ? bound : ((PsiWildcardType) type).getExtendsBound(); // object
    } else if (type instanceof PsiCapturedWildcardType && !eliminateInTypeArguments) {
      return eliminateWildcards(
          ((PsiCapturedWildcardType) type).getWildcard(), eliminateInTypeArguments);
    }
    return type;
  }
  public static PsiType getType(@NotNull PsiClassObjectAccessExpression classAccessExpression) {
    GlobalSearchScope resolveScope = classAccessExpression.getResolveScope();
    PsiManager manager = classAccessExpression.getManager();
    final PsiClass classClass =
        JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", resolveScope);
    if (classClass == null) {
      return new PsiClassReferenceType(
          new LightClassReference(manager, "Class", "java.lang.Class", resolveScope), null);
    }
    if (!PsiUtil.isLanguageLevel5OrHigher(classAccessExpression)) {
      // Raw java.lang.Class
      return JavaPsiFacade.getInstance(manager.getProject())
          .getElementFactory()
          .createType(classClass);
    }

    PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
    PsiType operandType = classAccessExpression.getOperand().getType();
    if (operandType instanceof PsiPrimitiveType && !PsiType.NULL.equals(operandType)) {
      if (PsiType.VOID.equals(operandType)) {
        operandType =
            JavaPsiFacade.getInstance(manager.getProject())
                .getElementFactory()
                .createTypeByFQClassName("java.lang.Void", classAccessExpression.getResolveScope());
      } else {
        operandType = ((PsiPrimitiveType) operandType).getBoxedType(classAccessExpression);
      }
    }
    final PsiTypeParameter[] typeParameters = classClass.getTypeParameters();
    if (typeParameters.length == 1) {
      substitutor = substitutor.put(typeParameters[0], operandType);
    }

    return new PsiImmediateClassType(classClass, substitutor);
  }
  private static String getName(
      final PsiClass psiClass, final LookupItem<?> item, boolean diamond) {
    if (item instanceof JavaPsiClassReferenceElement) {
      String forced = ((JavaPsiClassReferenceElement) item).getForcedPresentableName();
      if (forced != null) {
        return forced;
      }
    }

    String name = PsiUtilCore.getName(psiClass);

    if (item.getAttribute(LookupItem.FORCE_QUALIFY) != null) {
      if (psiClass.getContainingClass() != null) {
        name = psiClass.getContainingClass().getName() + "." + name;
      }
    }

    if (diamond) {
      return name + "<>";
    }

    PsiSubstitutor substitutor = (PsiSubstitutor) item.getAttribute(LookupItem.SUBSTITUTOR);
    if (substitutor != null) {
      final PsiTypeParameter[] params = psiClass.getTypeParameters();
      if (params.length > 0) {
        return name + formatTypeParameters(substitutor, params);
      }
    }

    return StringUtil.notNullize(name);
  }
  @Nullable
  public static PsiType getExpectedClosureReturnType(GrClosableBlock closure) {
    final Set<PsiType> expectedTypes = getDefaultExpectedTypes(closure);

    List<PsiType> expectedReturnTypes = new ArrayList<PsiType>();
    for (PsiType expectedType : expectedTypes) {
      if (!(expectedType instanceof PsiClassType)) return null;

      final PsiClassType.ClassResolveResult resolveResult =
          ((PsiClassType) expectedType).resolveGenerics();
      final PsiClass resolved = resolveResult.getElement();
      if (resolved == null
          || !(GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(resolved.getQualifiedName())))
        return null;

      final PsiTypeParameter[] typeParameters = resolved.getTypeParameters();
      if (typeParameters.length != 1) return null;

      final PsiTypeParameter expected = typeParameters[0];
      final PsiType expectedReturnType = resolveResult.getSubstitutor().substitute(expected);
      if (expectedReturnType == PsiType.VOID || expectedReturnType == null) return null;

      expectedReturnTypes.add(expectedReturnType);
    }

    return TypesUtil.getLeastUpperBoundNullable(expectedReturnTypes, closure.getManager());
  }
  @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;
  }
  @NotNull
  @Override
  public PsiClassType createType(@NotNull final PsiClass aClass, final PsiType parameter) {
    final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
    assert typeParameters.length == 1 : aClass;

    return createType(aClass, PsiSubstitutor.EMPTY.put(typeParameters[0], parameter));
  }
  private void markTypeParameterUsages(
      final PsiClass psiClass,
      PsiClassType migrationType,
      PsiReferenceParameterList referenceParameterList,
      final Map<PsiElement, Pair<PsiReference[], PsiType>> roots) {

    final PsiSubstitutor[] fullHierarchySubstitutor = {
      migrationType.resolveGenerics().getSubstitutor()
    };
    RefactoringHierarchyUtil.processSuperTypes(
        migrationType,
        new RefactoringHierarchyUtil.SuperTypeVisitor() {
          @Override
          public void visitType(PsiType aType) {
            fullHierarchySubstitutor[0] =
                fullHierarchySubstitutor[0].putAll(
                    ((PsiClassType) aType).resolveGenerics().getSubstitutor());
          }

          @Override
          public void visitClass(PsiClass aClass) {
            // do nothing
          }
        });

    final PsiClass resolvedClass =
        (PsiClass) ((PsiJavaCodeReferenceElement) referenceParameterList.getParent()).resolve();
    ;
    LOG.assertTrue(resolvedClass != null);
    final Set<PsiClass> superClasses = new HashSet<PsiClass>();
    superClasses.add(resolvedClass);
    InheritanceUtil.getSuperClasses(resolvedClass, superClasses, true);
    for (PsiClass superSuperClass : superClasses) {
      final TypeParameterSearcher parameterSearcher =
          new TypeParameterSearcher(superSuperClass.getTypeParameters());
      superSuperClass.accept(
          new JavaRecursiveElementVisitor() {
            @Override
            public void visitMethod(final PsiMethod method) {
              super.visitMethod(method);
              processMemberType(
                  method, parameterSearcher, psiClass, fullHierarchySubstitutor[0], roots);
              for (PsiParameter parameter : method.getParameterList().getParameters()) {
                processMemberType(
                    parameter, parameterSearcher, psiClass, fullHierarchySubstitutor[0], roots);
              }
            }

            @Override
            public void visitField(final PsiField field) {
              super.visitField(field);
              processMemberType(
                  field, parameterSearcher, psiClass, fullHierarchySubstitutor[0], roots);
            }
          });
    }
  }
  @Nullable
  private static PsiType getCollectionComponentType(PsiType type, Project project) {
    if (!(type instanceof PsiClassType)) return null;
    PsiClassType classType = (PsiClassType) type;
    PsiClassType.ClassResolveResult result = classType.resolveGenerics();
    PsiClass clazz = result.getElement();
    if (clazz == null) return null;
    JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
    @SuppressWarnings({"ConstantConditions"})
    PsiClass collectionClass = facade.findClass("java.util.Collection", type.getResolveScope());
    if (collectionClass == null || collectionClass.getTypeParameters().length != 1) return null;
    PsiSubstitutor substitutor =
        TypeConversionUtil.getClassSubstitutor(collectionClass, clazz, result.getSubstitutor());

    if (substitutor == null) return null;
    PsiType componentType = substitutor.substitute(collectionClass.getTypeParameters()[0]);
    return componentType instanceof PsiIntersectionType ? null : componentType;
  }
 private static PsiTypeParameter[] getAllTypeParams(
     PsiTypeParameterListOwner listOwner, PsiClass containingClass) {
   Set<PsiTypeParameter> params = new LinkedHashSet<PsiTypeParameter>();
   if (listOwner != null) {
     Collections.addAll(params, listOwner.getTypeParameters());
   }
   Collections.addAll(params, containingClass.getTypeParameters());
   return params.toArray(new PsiTypeParameter[params.size()]);
 }
Example #16
0
  private static boolean changeClassTypeArgument(
      PsiMethod myMethod,
      Project project,
      PsiType superReturnType,
      PsiClass superClass,
      Editor editor,
      PsiType returnType) {
    if (superClass == null || !superClass.hasTypeParameters()) return true;
    final PsiClass superReturnTypeClass = PsiUtil.resolveClassInType(superReturnType);
    if (superReturnTypeClass == null
        || !(superReturnTypeClass instanceof PsiTypeParameter
            || superReturnTypeClass.hasTypeParameters())) return true;

    final PsiClass derivedClass = myMethod.getContainingClass();
    if (derivedClass == null) return true;

    final PsiReferenceParameterList referenceParameterList =
        findTypeArgumentsList(superClass, derivedClass);
    if (referenceParameterList == null) return true;

    final PsiElement resolve =
        ((PsiJavaCodeReferenceElement) referenceParameterList.getParent()).resolve();
    if (!(resolve instanceof PsiClass)) return true;
    final PsiClass baseClass = (PsiClass) resolve;

    if (returnType instanceof PsiPrimitiveType) {
      returnType = ((PsiPrimitiveType) returnType).getBoxedType(derivedClass);
    }

    final PsiSubstitutor superClassSubstitutor =
        TypeConversionUtil.getSuperClassSubstitutor(superClass, baseClass, PsiSubstitutor.EMPTY);
    final PsiType superReturnTypeInBaseClassType =
        superClassSubstitutor.substitute(superReturnType);
    final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(project).getResolveHelper();
    final PsiSubstitutor psiSubstitutor =
        resolveHelper.inferTypeArguments(
            PsiTypesUtil.filterUnusedTypeParameters(
                superReturnTypeInBaseClassType, baseClass.getTypeParameters()),
            new PsiType[] {superReturnTypeInBaseClassType},
            new PsiType[] {returnType},
            PsiUtil.getLanguageLevel(superClass));

    final TypeMigrationRules rules = new TypeMigrationRules();
    final PsiSubstitutor compoundSubstitutor =
        TypeConversionUtil.getSuperClassSubstitutor(superClass, derivedClass, PsiSubstitutor.EMPTY)
            .putAll(psiSubstitutor);
    rules.setBoundScope(new LocalSearchScope(derivedClass));
    TypeMigrationProcessor.runHighlightingTypeMigration(
        project,
        editor,
        rules,
        referenceParameterList,
        JavaPsiFacade.getElementFactory(project).createType(baseClass, compoundSubstitutor));

    return false;
  }
  private static boolean isPartiallySubstituted(PsiType type) {
    if (!(type instanceof PsiClassType)) return false;
    PsiType[] parameters = ((PsiClassType) type).getParameters();

    PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType) type).resolveGenerics();
    PsiClass clazz = classResolveResult.getElement();
    if (clazz == null) return false;

    return clazz.getTypeParameters().length != parameters.length;
  }
 public ExtractClassProcessor(
     PsiClass sourceClass,
     List<PsiField> fields,
     List<PsiMethod> methods,
     List<PsiClass> classes,
     String packageName,
     MoveDestination moveDestination,
     String newClassName,
     String newVisibility,
     boolean generateAccessors,
     List<MemberInfo> enumConstants) {
   super(sourceClass.getProject());
   this.sourceClass = sourceClass;
   this.newPackageName = packageName;
   myMoveDestination = moveDestination;
   myNewVisibility = newVisibility;
   myGenerateAccessors = generateAccessors;
   this.enumConstants = new ArrayList<PsiField>();
   for (MemberInfo constant : enumConstants) {
     if (constant.isChecked()) {
       this.enumConstants.add((PsiField) constant.getMember());
     }
   }
   this.fields = new ArrayList<PsiField>(fields);
   this.methods = new ArrayList<PsiMethod>(methods);
   this.innerClasses = new ArrayList<PsiClass>(classes);
   this.newClassName = newClassName;
   delegateFieldName = calculateDelegateFieldName();
   requiresBackpointer =
       new BackpointerUsageVisitor(fields, innerClasses, methods, sourceClass)
           .backpointerRequired();
   if (requiresBackpointer) {
     ContainerUtil.addAll(typeParams, sourceClass.getTypeParameters());
   } else {
     final Set<PsiTypeParameter> typeParamSet = new HashSet<PsiTypeParameter>();
     final TypeParametersVisitor visitor = new TypeParametersVisitor(typeParamSet);
     for (PsiField field : fields) {
       field.accept(visitor);
     }
     for (PsiMethod method : methods) {
       method.accept(visitor);
       // do not include method's type parameters in class signature
       typeParamSet.removeAll(Arrays.asList(method.getTypeParameters()));
     }
     typeParams.addAll(typeParamSet);
   }
   myClass =
       new WriteCommandAction<PsiClass>(myProject, getCommandName()) {
         @Override
         protected void run(@NotNull Result<PsiClass> result) throws Throwable {
           result.setResult(buildClass());
         }
       }.execute().getResultObject();
   myExtractEnumProcessor = new ExtractEnumProcessor(myProject, this.enumConstants, myClass);
 }
  public static DiamondInferenceResult resolveInferredTypesNoCheck(
      final PsiNewExpression newExpression, final PsiElement context) {
    final PsiClass psiClass = findClass(newExpression);
    if (psiClass == null) return DiamondInferenceResult.NULL_RESULT;
    final PsiExpressionList argumentList = newExpression.getArgumentList();
    if (argumentList == null) return DiamondInferenceResult.NULL_RESULT;
    final Ref<PsiMethod> staticFactoryRef = new Ref<PsiMethod>();
    final PsiSubstitutor inferredSubstitutor =
        ourDiamondGuard.doPreventingRecursion(
            context,
            false,
            new Computable<PsiSubstitutor>() {
              @Override
              public PsiSubstitutor compute() {
                final PsiMethod constructor = findConstructor(psiClass, newExpression);
                PsiTypeParameter[] params = getAllTypeParams(constructor, psiClass);

                final PsiMethod staticFactory =
                    generateStaticFactory(
                        constructor, psiClass, params, newExpression.getClassReference());
                if (staticFactory == null) {
                  return null;
                }
                staticFactoryRef.set(staticFactory);

                return inferTypeParametersForStaticFactory(
                    staticFactory, newExpression, context, false);
              }
            });
    if (inferredSubstitutor == null) {
      return DiamondInferenceResult.NULL_RESULT;
    }
    final PsiMethod staticFactory = staticFactoryRef.get();
    if (staticFactory == null) {
      LOG.error(inferredSubstitutor);
      return DiamondInferenceResult.NULL_RESULT;
    }
    final PsiTypeParameter[] parameters = staticFactory.getTypeParameters();
    final PsiTypeParameter[] classParameters = psiClass.getTypeParameters();
    final PsiJavaCodeReferenceElement classOrAnonymousClassReference =
        newExpression.getClassOrAnonymousClassReference();
    LOG.assertTrue(classOrAnonymousClassReference != null);
    final DiamondInferenceResult result =
        new DiamondInferenceResult(classOrAnonymousClassReference.getReferenceName() + "<>");
    for (PsiTypeParameter parameter : parameters) {
      for (PsiTypeParameter classParameter : classParameters) {
        if (Comparing.strEqual(classParameter.getName(), parameter.getName())) {
          result.addInferredType(inferredSubstitutor.substitute(parameter));
          break;
        }
      }
    }
    return result;
  }
Example #20
0
  @NotNull
  public static PsiType createSetType(@NotNull PsiElement context, @NotNull PsiType type) {
    JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject());
    GlobalSearchScope resolveScope = context.getResolveScope();

    PsiClass setClass = facade.findClass(JAVA_UTIL_SET, resolveScope);
    if (setClass != null && setClass.getTypeParameters().length == 1) {
      return facade.getElementFactory().createType(setClass, type);
    }

    return facade.getElementFactory().createTypeByFQClassName(JAVA_UTIL_SET, resolveScope);
  }
Example #21
0
 private void getVariantsFromQualifier(@NotNull GrExpression qualifier) {
   Project project = qualifier.getProject();
   PsiType qualifierType = qualifier.getType();
   final ResolveState state = ResolveState.initial();
   if (qualifierType == null || qualifierType == PsiType.VOID) {
     if (qualifier instanceof GrReferenceExpression) {
       PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
       if (resolved instanceof PsiPackage || resolved instanceof PsiVariable) {
         resolved.processDeclarations(myProcessor, state, null, myRefExpr);
         return;
       }
     }
     getVariantsFromQualifierType(TypesUtil.getJavaLangObject(qualifier), project);
   } else if (qualifierType instanceof PsiIntersectionType) {
     for (PsiType conjunct : ((PsiIntersectionType) qualifierType).getConjuncts()) {
       getVariantsFromQualifierType(conjunct, project);
     }
   } else if (qualifierType instanceof GrTraitType) {
     GrTypeDefinition definition = ((GrTraitType) qualifierType).getMockTypeDefinition();
     if (definition != null) {
       PsiClassType classType = JavaPsiFacade.getElementFactory(project).createType(definition);
       getVariantsFromQualifierType(classType, project);
     } else {
       getVariantsFromQualifierType(((GrTraitType) qualifierType).getExprType(), project);
       for (PsiClassType traitType : ((GrTraitType) qualifierType).getTraitTypes()) {
         getVariantsFromQualifierType(traitType, project);
       }
     }
   } else {
     getVariantsFromQualifierType(qualifierType, project);
     if (qualifier instanceof GrReferenceExpression
         && !PsiUtil.isSuperReference(qualifier)
         && !PsiUtil.isInstanceThisRef(qualifier)) {
       PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
       if (resolved instanceof PsiClass) { // //omitted .class
         GlobalSearchScope scope = myRefExpr.getResolveScope();
         PsiClass javaLangClass = PsiUtil.getJavaLangClass(resolved, scope);
         if (javaLangClass != null) {
           PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
           PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
           if (typeParameters.length == 1) {
             substitutor = substitutor.put(typeParameters[0], qualifierType);
           }
           PsiType javaLangClassType =
               JavaPsiFacade.getElementFactory(myRefExpr.getProject())
                   .createType(javaLangClass, substitutor);
           ResolveUtil.processAllDeclarations(javaLangClassType, myProcessor, state, myRefExpr);
         }
       }
     }
   }
 }
  private void putAllInternal(@NotNull PsiClass parentClass, PsiType[] mappings) {
    final PsiTypeParameter[] params = parentClass.getTypeParameters();

    for (int i = 0; i < params.length; i++) {
      PsiTypeParameter param = params[i];
      assert param != null;
      if (mappings != null && mappings.length > i) {
        mySubstitutionMap.put(param, mappings[i]);
      } else {
        mySubstitutionMap.put(param, null);
      }
    }
  }
 @Nullable
 private PsiType extractListTypeFromContainingClass(
   PsiElement element) {
   PsiClass listClass = PsiTreeUtil.getParentOfType(element,
                                                    PsiClass.class);
   if (listClass == null) {
     return null;
   }
   final PsiMethod[] getMethods =
     listClass.findMethodsByName("get", true);
   if (getMethods.length == 0) {
     return null;
   }
   final PsiType type = getMethods[0].getReturnType();
   if (!(type instanceof PsiClassType)) {
     return null;
   }
   final PsiClassType classType = (PsiClassType)type;
   final PsiClass parameterClass = classType.resolve();
   if (parameterClass == null) {
     return null;
   }
   PsiClass subClass = null;
   while (listClass != null && !listClass.hasTypeParameters()) {
     subClass = listClass;
     listClass = listClass.getSuperClass();
   }
   if (listClass == null || subClass == null) {
     return TypeUtils.getObjectType(element);
   }
   final PsiTypeParameter[] typeParameters =
     listClass.getTypeParameters();
   if (!parameterClass.equals(typeParameters[0])) {
     return TypeUtils.getObjectType(element);
   }
   final PsiReferenceList extendsList = subClass.getExtendsList();
   if (extendsList == null) {
     return null;
   }
   final PsiJavaCodeReferenceElement[] referenceElements =
     extendsList.getReferenceElements();
   if (referenceElements.length == 0) {
     return null;
   }
   final PsiType[] types =
     referenceElements[0].getTypeParameters();
   if (types.length == 0) {
     return TypeUtils.getObjectType(element);
   }
   return types[0];
 }
Example #24
0
  @Nullable
  private static PsiClassType createCollection(
      Project project, String collectionName, PsiType... item) {
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
    PsiClass collection =
        JavaPsiFacade.getInstance(project)
            .findClass(collectionName, GlobalSearchScope.allScope(project));
    if (collection == null) return null;

    PsiTypeParameter[] parameters = collection.getTypeParameters();
    if (parameters.length != 1) return null;

    return factory.createType(collection, item);
  }
  @NotNull
  @Override
  public PsiClassType getArrayClassType(
      @NotNull final PsiType componentType, @NotNull final LanguageLevel languageLevel) {
    final PsiClass arrayClass = getArrayClass(languageLevel);
    final PsiTypeParameter[] typeParameters = arrayClass.getTypeParameters();

    PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
    if (typeParameters.length == 1) {
      substitutor = substitutor.put(typeParameters[0], componentType);
    }

    return createType(arrayClass, substitutor);
  }
  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);
  }
  private PsiClassType createEnumType() {
    JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
    PsiClass enumClass = facade.findClass(JAVA_LANG_ENUM, getResolveScope());
    PsiElementFactory factory = facade.getElementFactory();
    if (enumClass != null) {
      PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
      PsiTypeParameter[] typeParameters = enumClass.getTypeParameters();
      if (typeParameters.length == 1) {
        substitutor = substitutor.put(typeParameters[0], factory.createType(this));
      }

      return factory.createType(enumClass, substitutor);
    }
    return TypesUtil.createTypeByFQClassName(JAVA_LANG_ENUM, this);
  }
  @Override
  public Result calculateResult(@NotNull Expression[] params, ExpressionContext context) {
    if (params.length != 1) return null;
    final Result result = params[0].calculateResult(context);
    if (result == null) return null;

    Project project = context.getProject();

    PsiExpression expr = MacroUtil.resultToPsiExpression(result, context);
    if (expr == null) return null;
    PsiType type = expr.getType();

    if (type instanceof PsiArrayType) {
      return new PsiTypeResult(((PsiArrayType) type).getComponentType(), project);
    }

    if (type instanceof PsiClassType) {
      PsiClassType.ClassResolveResult resolveResult = ((PsiClassType) type).resolveGenerics();
      PsiClass aClass = resolveResult.getElement();

      if (aClass != null) {
        PsiClass iterableClass =
            JavaPsiFacade.getInstance(project)
                .findClass("java.lang.Iterable", aClass.getResolveScope());
        if (iterableClass != null) {
          PsiSubstitutor substitutor =
              TypeConversionUtil.getClassSubstitutor(
                  iterableClass, aClass, resolveResult.getSubstitutor());
          if (substitutor != null) {
            PsiType parameterType = substitutor.substitute(iterableClass.getTypeParameters()[0]);
            if (parameterType instanceof PsiCapturedWildcardType) {
              parameterType = ((PsiCapturedWildcardType) parameterType).getWildcard();
            }
            if (parameterType != null) {
              if (parameterType instanceof PsiWildcardType) {
                if (((PsiWildcardType) parameterType).isExtends()) {
                  return new PsiTypeResult(((PsiWildcardType) parameterType).getBound(), project);
                } else return null;
              }
              return new PsiTypeResult(parameterType, project);
            }
          }
        }
      }
    }

    return null;
  }
Example #29
0
 @Nullable
 public static PsiType createJavaLangClassType(
     @Nullable PsiType type, Project project, GlobalSearchScope resolveScope) {
   final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
   PsiType result = null;
   PsiClass javaLangClass = facade.findClass(JAVA_LANG_CLASS, resolveScope);
   if (javaLangClass != null) {
     PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
     final PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
     if (typeParameters.length == 1) {
       substitutor = substitutor.put(typeParameters[0], type);
     }
     result = facade.getElementFactory().createType(javaLangClass, substitutor);
   }
   return result;
 }
Example #30
0
  private void specialCase(
      InferenceSession session,
      List<ConstraintFormula> constraints,
      PsiSubstitutor substitutor,
      PsiParameter[] targetParameters,
      boolean ignoreRaw) {
    final PsiElement qualifier = myExpression.getQualifier();
    PsiType qualifierType = null;
    if (qualifier instanceof PsiTypeElement) {
      qualifierType = ((PsiTypeElement) qualifier).getType();
      final PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType);
      if (qualifierClass != null) {
        qualifierType =
            JavaPsiFacade.getElementFactory(myExpression.getProject())
                .createType(qualifierClass, PsiSubstitutor.EMPTY);
      }
    } else if (qualifier instanceof PsiExpression) {
      qualifierType = ((PsiExpression) qualifier).getType();
      if (qualifierType == null && qualifier instanceof PsiReferenceExpression) {
        final JavaResolveResult resolveResult =
            ((PsiReferenceExpression) qualifier).advancedResolve(false);
        final PsiElement res = resolveResult.getElement();
        if (res instanceof PsiClass) {
          PsiClass containingClass = (PsiClass) res;
          final boolean isRawSubst =
              !ignoreRaw
                  && !myExpression.isConstructor()
                  && PsiUtil.isRawSubstitutor(containingClass, resolveResult.getSubstitutor());
          qualifierType =
              JavaPsiFacade.getElementFactory(res.getProject())
                  .createType(
                      containingClass,
                      isRawSubst ? PsiSubstitutor.EMPTY : resolveResult.getSubstitutor());
        }
      }
    }

    final PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType);
    if (qualifierClass != null) {
      session.initBounds(myExpression, qualifierClass.getTypeParameters());
      constraints.add(
          new StrictSubtypingConstraint(
              session.substituteWithInferenceVariables(qualifierType),
              session.substituteWithInferenceVariables(
                  substitutor.substitute(targetParameters[0].getType()))));
    }
  }