public static boolean haveConstructorsGenericsParameters(@NotNull final PsiClass psiClass) {
    for (PsiMethod method : psiClass.getConstructors()) {
      for (PsiParameter parameter : method.getParameterList().getParameters()) {
        final PsiType type = parameter.getType();
        final Boolean accept =
            type.accept(
                new PsiTypeVisitor<Boolean>() {
                  @Override
                  public Boolean visitArrayType(PsiArrayType arrayType) {
                    return arrayType.getComponentType().accept(this);
                  }

                  @Override
                  public Boolean visitClassType(PsiClassType classType) {
                    for (PsiType psiType : classType.getParameters()) {
                      if (psiType != null) {
                        final Boolean typaParamFound = psiType.accept(this);
                        if (typaParamFound != null && typaParamFound) return true;
                      }
                    }
                    return PsiUtil.resolveClassInType(classType) instanceof PsiTypeParameter;
                  }

                  @Override
                  public Boolean visitWildcardType(PsiWildcardType wildcardType) {
                    final PsiType bound = wildcardType.getBound();
                    if (bound == null) return false;
                    return bound.accept(this);
                  }
                });
        if (accept != null && accept.booleanValue()) return true;
      }
    }
    return false;
  }
예제 #2
0
 @NotNull
 public Type typeToType(@Nullable PsiType type) {
   if (type == null) return Type.EMPTY_TYPE;
   TypeVisitor typeVisitor = new TypeVisitor(this);
   type.accept(typeVisitor);
   return typeVisitor.getResult();
 }
예제 #3
0
 @Nullable
 @Override
 public Boolean visitWildcardType(PsiWildcardType wildcardType) {
   final PsiType bound = wildcardType.getBound();
   if (bound != null) return bound.accept(this);
   return false;
 }
 @Override
 public PsiType visitArrayType(PsiArrayType arrayType) {
   final PsiType componentType = arrayType.getComponentType();
   final PsiType substitutedComponentType = componentType.accept(this);
   if (substitutedComponentType == null) return null;
   if (substitutedComponentType == componentType) return arrayType; // optimization
   return new PsiArrayType(substitutedComponentType);
 }
 @Override
 public PsiType visitEllipsisType(PsiEllipsisType ellipsisType) {
   final PsiType componentType = ellipsisType.getComponentType();
   final PsiType substitutedComponentType = componentType.accept(this);
   if (substitutedComponentType == null) return null;
   if (substitutedComponentType == componentType) return ellipsisType; // optimization
   return new PsiEllipsisType(substitutedComponentType);
 }
예제 #6
0
 static boolean depends(PsiType type, TypeParamsChecker visitor, PsiTypeParameter... param2Check) {
   if (!visitor.startedInference()) return false;
   final Boolean accept = type.accept(visitor);
   if (param2Check.length > 0) {
     return visitor.used(param2Check);
   }
   return accept != null && accept.booleanValue();
 }
 @Override
 public PsiType substitute(PsiType type) {
   if (type == null) {
     //noinspection ConstantConditions
     return null;
   }
   PsiUtil.ensureValidType(type);
   PsiType substituted = type.accept(mySimpleSubstitutionVisitor);
   return correctExternalSubstitution(substituted, type);
 }
    public Boolean visitClassType(final PsiClassType classType) {
      final PsiClass aClass = classType.resolve();
      if (aClass instanceof PsiTypeParameter && myTypeParams.contains((PsiTypeParameter) aClass))
        return true;

      final PsiType[] types = classType.getParameters();
      for (final PsiType psiType : types) {
        if (psiType.accept(this).booleanValue()) return true;
      }
      return false;
    }
 @Nullable
 public static HighlightInfo checkValidAnnotationType(final PsiTypeElement typeElement) {
   PsiType type = typeElement.getType();
   if (type.accept(AnnotationReturnTypeVisitor.INSTANCE).booleanValue()) {
     return null;
   }
   String description = JavaErrorMessages.message("annotation.invalid.annotation.member.type");
   return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
       .range(typeElement)
       .descriptionAndTooltip(description)
       .create();
 }
예제 #10
0
  @Nullable
  public static PsiType rawSecondGeneric(PsiType type, Project project) {
    if (!(type instanceof PsiClassType)) return null;

    final PsiClassType.ClassResolveResult result = ((PsiClassType) type).resolveGenerics();
    final PsiClass element = result.getElement();
    if (element == null) return null;

    final PsiType[] parameters = ((PsiClassType) type).getParameters();

    boolean changed = false;
    for (int i = 0; i < parameters.length; i++) {
      PsiType parameter = parameters[i];
      if (parameter == null) continue;

      final Ref<PsiType> newParam = new Ref<PsiType>();
      parameter.accept(
          new PsiTypeVisitorEx<Object>() {
            @Nullable
            @Override
            public Object visitClassType(PsiClassType classType) {
              if (classType.getParameterCount() > 0) {
                newParam.set(classType.rawType());
              }
              return null;
            }

            @Nullable
            @Override
            public Object visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) {
              newParam.set(capturedWildcardType.getWildcard().getBound());
              return null;
            }

            @Nullable
            @Override
            public Object visitWildcardType(PsiWildcardType wildcardType) {
              newParam.set(wildcardType.getBound());
              return null;
            }
          });

      if (!newParam.isNull()) {
        changed = true;
        parameters[i] = newParam.get();
      }
    }
    if (!changed) return null;
    return JavaPsiFacade.getElementFactory(project).createType(element, parameters);
  }
예제 #11
0
    public Binding reduceRecursive() {
      final BindingImpl binding = (BindingImpl) create();

      for (final PsiTypeVariable var : myBoundVariables) {
        final int index = var.getIndex();
        final PsiType type = myBindings.get(index);

        if (type != null) {
          class Verifier extends PsiExtendedTypeVisitor<Void> {
            boolean myFlag = false;

            @Override
            public Void visitTypeVariable(final PsiTypeVariable var) {
              if (var.getIndex() == index) {
                myFlag = true;
              }

              return null;
            }
          }

          final Verifier verifier = new Verifier();

          type.accept(verifier);

          if (verifier.myFlag) {
            myBindings.put(index, Bottom.BOTTOM);
            binding.myBindings.put(index, Bottom.BOTTOM);
          } else {
            binding.myBindings.put(index, type);
          }
        } else {
          binding.myBindings.put(index, type);
        }
      }

      for (final PsiTypeVariable var : myBoundVariables) {
        final int index = var.getIndex();
        final PsiType type = myBindings.get(index);

        if (type != null) {
          myBindings.put(index, binding.apply(type));
        }
      }

      return this;
    }
예제 #12
0
 @Override
 public Boolean visitClassType(PsiClassType classType) {
   boolean used = false;
   for (PsiType paramType : classType.getParameters()) {
     final Boolean paramAccepted = paramType.accept(this);
     used |= paramAccepted != null && paramAccepted.booleanValue();
   }
   final PsiClass resolve = classType.resolve();
   if (resolve instanceof PsiTypeParameter) {
     final PsiTypeParameter typeParameter = (PsiTypeParameter) resolve;
     if (check(typeParameter)) {
       myUsedTypeParams.add(typeParameter);
       return true;
     }
   }
   return used;
 }
  private PsiType addBounds(PsiType substituted, final PsiTypeParameter typeParameter) {
    PsiElement captureContext = null;
    if (substituted instanceof PsiCapturedWildcardType) {
      final PsiCapturedWildcardType captured = (PsiCapturedWildcardType) substituted;
      substituted = captured.getWildcard();
      captureContext = captured.getContext();
    }
    if (substituted instanceof PsiWildcardType && !((PsiWildcardType) substituted).isSuper()) {
      PsiType originalBound = ((PsiWildcardType) substituted).getBound();
      PsiManager manager = typeParameter.getManager();
      final PsiType[] boundTypes = typeParameter.getExtendsListTypes();
      for (PsiType boundType : boundTypes) {
        PsiType substitutedBoundType = boundType.accept(mySimpleSubstitutionVisitor);
        PsiWildcardType wildcardType = (PsiWildcardType) substituted;
        if (substitutedBoundType != null
            && !(substitutedBoundType instanceof PsiWildcardType)
            && !substitutedBoundType.equalsToText("java.lang.Object")) {
          if (originalBound == null
              || (!TypeConversionUtil.erasure(substitutedBoundType)
                      .isAssignableFrom(TypeConversionUtil.erasure(originalBound))
                  && !TypeConversionUtil.erasure(substitutedBoundType)
                      .isAssignableFrom(
                          originalBound))) { // erasure is essential to avoid infinite recursion
            if (wildcardType.isExtends()) {
              final PsiType glb =
                  GenericsUtil.getGreatestLowerBound(wildcardType.getBound(), substitutedBoundType);
              if (glb != null) {
                substituted = PsiWildcardType.createExtends(manager, glb);
              }
            } else {
              // unbounded
              substituted = PsiWildcardType.createExtends(manager, substitutedBoundType);
            }
          }
        }
      }
    }

    if (captureContext != null) {
      LOG.assertTrue(substituted instanceof PsiWildcardType);
      substituted = PsiCapturedWildcardType.create((PsiWildcardType) substituted, captureContext);
    }
    return substituted;
  }
  private PsiType correctExternalSubstitution(PsiType substituted, final PsiType original) {
    if (original == null) return null;

    if (substituted == null) {
      return original.accept(
          new PsiTypeVisitor<PsiType>() {
            @Override
            public PsiType visitArrayType(PsiArrayType arrayType) {
              return new PsiArrayType(arrayType.getComponentType().accept(this));
            }

            @Override
            public PsiType visitEllipsisType(PsiEllipsisType ellipsisType) {
              return new PsiEllipsisType(ellipsisType.getComponentType().accept(this));
            }

            @Override
            public PsiType visitClassType(PsiClassType classType) {
              PsiClass aClass = classType.resolve();
              if (aClass != null) {
                if (aClass instanceof PsiTypeParameter) {
                  return rawTypeForTypeParameter((PsiTypeParameter) aClass);
                } else {
                  return JavaPsiFacade.getInstance(aClass.getProject())
                      .getElementFactory()
                      .createType(aClass);
                }
              } else {
                return classType;
              }
            }

            @Override
            public PsiType visitType(PsiType type) {
              LOG.error(type.getInternalCanonicalText());
              return null;
            }
          });
    }
    return substituted;
  }
    @Override
    public PsiType visitWildcardType(PsiWildcardType wildcardType) {
      final PsiType bound = wildcardType.getBound();
      if (bound == null) {
        return wildcardType;
      } else {
        final PsiType newBound = bound.accept(this);
        if (newBound == null) {
          return null;
        }
        assert newBound.isValid() : newBound.getClass() + "; " + bound.isValid();
        if (newBound instanceof PsiWildcardType) {
          final PsiType newBoundBound = ((PsiWildcardType) newBound).getBound();
          return !((PsiWildcardType) newBound).isBounded()
              ? PsiWildcardType.createUnbounded(wildcardType.getManager())
              : rebound(wildcardType, newBoundBound);
        }

        return newBound == PsiType.NULL ? newBound : rebound(wildcardType, newBound);
      }
    }
예제 #16
0
  @NotNull
  public TypeProjection transformToTypeProjection(
      @NotNull final PsiType javaType,
      @NotNull final TypeParameterDescriptor typeParameterDescriptor,
      @NotNull final TypeVariableResolver typeVariableByPsiResolver) {
    TypeProjection result =
        javaType.accept(
            new PsiTypeVisitor<TypeProjection>() {

              @Override
              public TypeProjection visitCapturedWildcardType(
                  PsiCapturedWildcardType capturedWildcardType) {
                throw new UnsupportedOperationException(); // TODO
              }

              @Override
              public TypeProjection visitWildcardType(PsiWildcardType wildcardType) {
                if (!wildcardType.isBounded()) {
                  return TypeUtils.makeStarProjection(typeParameterDescriptor);
                }
                Variance variance =
                    wildcardType.isExtends() ? Variance.OUT_VARIANCE : Variance.IN_VARIANCE;

                PsiType bound = wildcardType.getBound();
                assert bound != null;
                return new TypeProjection(
                    variance,
                    transformToType(bound, TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
              }

              @Override
              public TypeProjection visitType(PsiType type) {
                return new TypeProjection(
                    transformToType(type, TypeUsage.TYPE_ARGUMENT, typeVariableByPsiResolver));
              }
            });
    return result;
  }
    @Override
    public PsiType visitWildcardType(PsiWildcardType wildcardType) {
      final PsiType bound = wildcardType.getBound();
      if (bound == null) {
        return wildcardType;
      } else {
        final PsiType newBound = bound.accept(this);
        if (newBound == null) {
          return null;
        }
        if (newBound instanceof PsiWildcardType) {
          return handleBoundComposition(wildcardType, (PsiWildcardType) newBound);
        }
        if (newBound instanceof PsiCapturedWildcardType
            && wildcardType.isExtends()
                != ((PsiCapturedWildcardType) newBound).getWildcard().isExtends()) {
          return handleBoundComposition(
              wildcardType, ((PsiCapturedWildcardType) newBound).getWildcard());
        }

        return PsiWildcardType.changeBound(wildcardType, newBound);
      }
    }
  private void processMemberType(
      final PsiElement element,
      final TypeParameterSearcher parameterSearcher,
      final PsiClass psiClass,
      final PsiSubstitutor substitutor,
      final Map<PsiElement, Pair<PsiReference[], PsiType>> roots) {
    final PsiType elementType = TypeMigrationLabeler.getElementType(element);
    if (elementType != null && elementType.accept(parameterSearcher).booleanValue()) {
      final PsiType memberType = substitutor.substitute(elementType);

      prepareMethodsChangeSignature(psiClass, element, memberType);

      final List<PsiReference> refs =
          TypeMigrationLabeler.filterReferences(
              psiClass, ReferencesSearch.search(element, psiClass.getUseScope()));

      roots.put(
          element,
          Pair.create(
              myLabeler.markRootUsages(
                  element, memberType, refs.toArray(new PsiReference[refs.size()])),
              memberType));
    }
  }
예제 #19
0
  @Nullable
  public static PsiType getVariableTypeByExpressionType(
      @Nullable PsiType type, final boolean openCaptured) {
    if (type == null) return null;
    if (type instanceof PsiCapturedWildcardType) {
      type = ((PsiCapturedWildcardType) type).getWildcard();
    }
    PsiType transformed =
        type.accept(
            new PsiTypeVisitor<PsiType>() {
              @Override
              public PsiType visitArrayType(PsiArrayType arrayType) {
                PsiType componentType = arrayType.getComponentType();
                PsiType type = componentType.accept(this);
                if (type == componentType) return arrayType;
                return type.createArrayType();
              }

              @Override
              public PsiType visitType(PsiType type) {
                return type;
              }

              @Override
              public PsiType visitWildcardType(final PsiWildcardType wildcardType) {
                final PsiType bound = wildcardType.getBound();
                PsiManager manager = wildcardType.getManager();
                if (bound != null) {
                  final PsiType acceptedBound = bound.accept(this);
                  if (acceptedBound instanceof PsiWildcardType) {
                    if (((PsiWildcardType) acceptedBound).isExtends() != wildcardType.isExtends())
                      return PsiWildcardType.createUnbounded(manager);
                    return acceptedBound;
                  }
                  if (wildcardType.isExtends()
                      && acceptedBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT))
                    return PsiWildcardType.createUnbounded(manager);
                  if (acceptedBound.equals(bound)) return wildcardType;
                  return wildcardType.isExtends()
                      ? PsiWildcardType.createExtends(manager, acceptedBound)
                      : PsiWildcardType.createSuper(manager, acceptedBound);
                }
                return wildcardType;
              }

              @Override
              public PsiType visitCapturedWildcardType(
                  PsiCapturedWildcardType capturedWildcardType) {
                return openCaptured
                    ? capturedWildcardType.getWildcard().accept(this)
                    : capturedWildcardType;
              }

              @Override
              public PsiType visitClassType(PsiClassType classType) {
                PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics();
                PsiClass aClass = resolveResult.getElement();
                if (aClass == null) return classType;
                boolean toExtend = false;
                PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
                for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(aClass)) {
                  PsiType typeArgument = resolveResult.getSubstitutor().substitute(typeParameter);
                  if (typeArgument instanceof PsiCapturedWildcardType) toExtend = true;
                  if (typeArgument instanceof PsiWildcardType
                      && ((PsiWildcardType) typeArgument).getBound()
                          instanceof PsiIntersectionType) {
                    toExtend = true;
                  }
                  PsiType toPut;
                  if (typeArgument == null) {
                    toPut = null;
                  } else {
                    final PsiType accepted = typeArgument.accept(this);
                    if (typeArgument instanceof PsiIntersectionType) {
                      toPut = PsiWildcardType.createExtends(typeParameter.getManager(), accepted);
                    } else {
                      toPut = accepted;
                    }
                  }
                  LOG.assertTrue(toPut == null || toPut.isValid(), toPut);
                  substitutor = substitutor.put(typeParameter, toPut);
                }
                final PsiAnnotation[] applicableAnnotations = classType.getApplicableAnnotations();
                if (substitutor == PsiSubstitutor.EMPTY
                    && !toExtend
                    && applicableAnnotations.length == 0
                    && !(aClass instanceof PsiTypeParameter)) return classType;
                PsiManager manager = aClass.getManager();
                PsiType result =
                    JavaPsiFacade.getInstance(manager.getProject())
                        .getElementFactory()
                        .createType(
                            aClass,
                            substitutor,
                            PsiUtil.getLanguageLevel(aClass),
                            applicableAnnotations);
                if (toExtend) result = PsiWildcardType.createExtends(manager, result);
                return result;
              }
            });

    PsiType componentType = transformed != null ? transformed.getDeepComponentType() : null;
    if (componentType instanceof PsiWildcardType) {
      componentType = ((PsiWildcardType) componentType).getExtendsBound();
      int dims = transformed.getArrayDimensions();
      for (int i = 0; i < dims; i++) componentType = componentType.createArrayType();
      return componentType;
    }

    return transformed;
  }
 public Boolean visitWildcardType(final PsiWildcardType wildcardType) {
   final PsiType bound = wildcardType.getBound();
   return bound != null && bound.accept(this).booleanValue();
 }
 @Override
 public Boolean visitArrayType(PsiArrayType arrayType) {
   if (arrayType.getArrayDimensions() != 1) return Boolean.FALSE;
   PsiType componentType = arrayType.getComponentType();
   return componentType.accept(this);
 }
 private PsiType substituteInternal(PsiType type) {
   return type.accept(this);
 }
예제 #23
0
  @NotNull
  public JetType transformToType(
      @NotNull PsiType javaType, @NotNull final TypeVariableResolver typeVariableResolver) {
    return javaType.accept(
        new PsiTypeVisitor<JetType>() {
          @Override
          public JetType visitClassType(PsiClassType classType) {
            PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics();
            PsiClass psiClass = classResolveResult.getElement();
            if (psiClass == null) {
              return ErrorUtils.createErrorType(
                  "Unresolved java class: " + classType.getPresentableText());
            }

            if (psiClass instanceof PsiTypeParameter) {
              PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass;
              TypeParameterDescriptor typeParameterDescriptor =
                  typeVariableResolver.getTypeVariable(typeParameter.getName());
              //                    return
              // TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
              return typeParameterDescriptor.getDefaultType();
            } else {
              JetType jetAnalog = getClassTypesMap().get(psiClass.getQualifiedName());
              if (jetAnalog != null) {
                return jetAnalog;
              }

              final JavaDescriptorResolver.ResolverClassData classData =
                  resolver.resolveClassData(psiClass);
              if (classData == null) {
                return ErrorUtils.createErrorType(
                    "Unresolve java class: " + classType.getPresentableText());
              }

              List<TypeProjection> arguments = Lists.newArrayList();
              if (classType.isRaw()) {
                List<TypeParameterDescriptor> parameters =
                    classData.getClassDescriptor().getTypeConstructor().getParameters();
                for (TypeParameterDescriptor parameter : parameters) {
                  arguments.add(TypeUtils.makeStarProjection(parameter));
                }
              } else {
                List<TypeParameterDescriptor> parameters =
                    classData.getClassDescriptor().getTypeConstructor().getParameters();
                PsiType[] psiArguments = classType.getParameters();

                if (parameters.size() != psiArguments.length) {
                  throw new IllegalStateException();
                }

                for (int i = 0; i < parameters.size(); i++) {
                  PsiType psiArgument = psiArguments[i];
                  TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);

                  arguments.add(
                      transformToTypeProjection(
                          psiArgument, typeParameterDescriptor, typeVariableResolver));
                }
              }
              return new JetTypeImpl(
                  Collections.<AnnotationDescriptor>emptyList(),
                  classData.getClassDescriptor().getTypeConstructor(),
                  true,
                  arguments,
                  classData.getClassDescriptor().getMemberScope(arguments));
            }
          }

          @Override
          public JetType visitPrimitiveType(PsiPrimitiveType primitiveType) {
            String canonicalText = primitiveType.getCanonicalText();
            JetType type = getPrimitiveTypesMap().get(canonicalText);
            assert type != null : canonicalText;
            return type;
          }

          @Override
          public JetType visitArrayType(PsiArrayType arrayType) {
            PsiType componentType = arrayType.getComponentType();
            if (componentType instanceof PsiPrimitiveType) {
              JetType jetType = getPrimitiveTypesMap().get("[" + componentType.getCanonicalText());
              if (jetType != null) return TypeUtils.makeNullable(jetType);
            }

            JetType type = transformToType(componentType, typeVariableResolver);
            return TypeUtils.makeNullable(standardLibrary.getArrayType(type));
          }

          @Override
          public JetType visitType(PsiType type) {
            throw new UnsupportedOperationException(
                "Unsupported type: " + type.getPresentableText()); // TODO
          }
        });
  }
 @Override
 public PsiType substitute(PsiType type) {
   if (type == null) return null;
   PsiType substituted = type.accept(myAddingBoundsSubstitutionVisitor);
   return correctExternalSubstitution(substituted, type);
 }