コード例 #1
1
  private List<TypeProjection> substituteTypeArguments(
      List<TypeParameterDescriptor> typeParameters,
      List<TypeProjection> typeArguments,
      int recursionDepth)
      throws SubstitutionException {
    List<TypeProjection> substitutedArguments =
        new ArrayList<TypeProjection>(typeParameters.size());
    for (int i = 0; i < typeParameters.size(); i++) {
      TypeParameterDescriptor typeParameter = typeParameters.get(i);
      TypeProjection typeArgument = typeArguments.get(i);

      TypeProjection substitutedTypeArgument = unsafeSubstitute(typeArgument, recursionDepth + 1);

      switch (conflictType(
          typeParameter.getVariance(), substitutedTypeArgument.getProjectionKind())) {
        case NO_CONFLICT:
          // if the corresponding type parameter is already co/contra-variant, there's not need for
          // an explicit projection
          if (typeParameter.getVariance() != Variance.INVARIANT
              && !substitutedTypeArgument.isStarProjection()) {
            substitutedTypeArgument =
                new TypeProjectionImpl(Variance.INVARIANT, substitutedTypeArgument.getType());
          }
          break;
        case OUT_IN_IN_POSITION:
        case IN_IN_OUT_POSITION:
          substitutedTypeArgument = TypeUtils.makeStarProjection(typeParameter);
          break;
      }

      substitutedArguments.add(substitutedTypeArgument);
    }
    return substitutedArguments;
  }
コード例 #2
0
ファイル: JavaResolverUtils.java プロジェクト: rlugojr/kotlin
 public static Map<TypeParameterDescriptor, TypeParameterDescriptorImpl>
     recreateTypeParametersAndReturnMapping(
         @NotNull List<TypeParameterDescriptor> originalParameters,
         @Nullable DeclarationDescriptor newOwner) {
   // LinkedHashMap to save the order of type parameters
   Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> result =
       new LinkedHashMap<TypeParameterDescriptor, TypeParameterDescriptorImpl>();
   for (TypeParameterDescriptor typeParameter : originalParameters) {
     result.put(
         typeParameter,
         TypeParameterDescriptorImpl.createForFurtherModification(
             newOwner == null ? typeParameter.getContainingDeclaration() : newOwner,
             typeParameter.getAnnotations(),
             typeParameter.isReified(),
             typeParameter.getVariance(),
             typeParameter.getName(),
             typeParameter.getIndex(),
             SourceElement.NO_SOURCE));
   }
   return result;
 }
コード例 #3
0
ファイル: TypeUtils.java プロジェクト: alien11689/kotlin
  public static boolean canHaveSubtypes(KotlinTypeChecker typeChecker, @NotNull KotlinType type) {
    if (type.isMarkedNullable()) {
      return true;
    }
    if (!type.getConstructor().isFinal()) {
      return true;
    }

    List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
    List<TypeProjection> arguments = type.getArguments();
    for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
      TypeParameterDescriptor parameterDescriptor = parameters.get(i);
      TypeProjection typeProjection = arguments.get(i);
      if (typeProjection.isStarProjection()) return true;

      Variance projectionKind = typeProjection.getProjectionKind();
      KotlinType argument = typeProjection.getType();

      switch (parameterDescriptor.getVariance()) {
        case INVARIANT:
          switch (projectionKind) {
            case INVARIANT:
              if (lowerThanBound(typeChecker, argument, parameterDescriptor)
                  || canHaveSubtypes(typeChecker, argument)) {
                return true;
              }
              break;
            case IN_VARIANCE:
              if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
                return true;
              }
              break;
            case OUT_VARIANCE:
              if (canHaveSubtypes(typeChecker, argument)) {
                return true;
              }
              break;
          }
          break;
        case IN_VARIANCE:
          if (projectionKind != Variance.OUT_VARIANCE) {
            if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
              return true;
            }
          } else {
            if (canHaveSubtypes(typeChecker, argument)) {
              return true;
            }
          }
          break;
        case OUT_VARIANCE:
          if (projectionKind != Variance.IN_VARIANCE) {
            if (canHaveSubtypes(typeChecker, argument)) {
              return true;
            }
          } else {
            if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
              return true;
            }
          }
          break;
      }
    }
    return false;
  }