コード例 #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
  // Note: headers of member classes' members are not resolved
  public void resolveMemberHeaders() {
    ForceResolveUtil.forceResolveAllContents(getAnnotations());
    ForceResolveUtil.forceResolveAllContents(getDanglingAnnotations());

    getCompanionObjectDescriptor();

    getDescriptorsForExtraCompanionObjects();

    getConstructors();
    getContainingDeclaration();
    getThisAsReceiverParameter();
    getKind();
    getModality();
    getName();
    getOriginal();
    getScopeForClassHeaderResolution();
    getScopeForMemberDeclarationResolution();
    DescriptorUtils.getAllDescriptors(getUnsubstitutedMemberScope());
    getScopeForInitializerResolution();
    getUnsubstitutedInnerClassesScope();
    getTypeConstructor().getSupertypes();
    for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
      typeParameterDescriptor.getUpperBounds();
    }
    getUnsubstitutedPrimaryConstructor();
    getVisibility();
  }
コード例 #3
0
ファイル: CastDiagnosticsUtil.java プロジェクト: nanck/kotlin
  /**
   * Remember that we are trying to cast something of type {@code supertype} to {@code subtype}.
   *
   * <p>Since at runtime we can only check the class (type constructor), the rest of the subtype
   * should be known statically, from supertype. This method reconstructs all static information
   * that can be obtained from supertype.
   *
   * <p>Example 1: supertype = Collection<String> subtype = List<...> result = List<String>, all
   * arguments are inferred
   *
   * <p>Example 2: supertype = Any subtype = List<...> result = List<*>, some arguments were not
   * inferred, replaced with '*'
   */
  public static TypeReconstructionResult findStaticallyKnownSubtype(
      @NotNull KotlinType supertype, @NotNull TypeConstructor subtypeConstructor) {
    assert !supertype.isMarkedNullable() : "This method only makes sense for non-nullable types";

    // Assume we are casting an expression of type Collection<Foo> to List<Bar>
    // First, let's make List<T>, where T is a type variable
    ClassifierDescriptor descriptor = subtypeConstructor.getDeclarationDescriptor();
    assert descriptor != null : "Can't create default type for " + subtypeConstructor;
    KotlinType subtypeWithVariables = descriptor.getDefaultType();

    // Now, let's find a supertype of List<T> that is a Collection of something,
    // in this case it will be Collection<T>
    KotlinType supertypeWithVariables =
        TypeCheckingProcedure.findCorrespondingSupertype(subtypeWithVariables, supertype);

    final List<TypeParameterDescriptor> variables =
        subtypeWithVariables.getConstructor().getParameters();

    Map<TypeConstructor, TypeProjection> substitution;
    if (supertypeWithVariables != null) {
      // Now, let's try to unify Collection<T> and Collection<Foo> solution is a map from T to Foo
      TypeUnifier.UnificationResult solution =
          TypeUnifier.unify(
              new TypeProjectionImpl(supertype),
              new TypeProjectionImpl(supertypeWithVariables),
              new Predicate<TypeConstructor>() {
                @Override
                public boolean apply(TypeConstructor typeConstructor) {
                  ClassifierDescriptor descriptor = typeConstructor.getDeclarationDescriptor();
                  return descriptor instanceof TypeParameterDescriptor
                      && variables.contains(descriptor);
                }
              });
      substitution = Maps.newHashMap(solution.getSubstitution());
    } else {
      // If there's no corresponding supertype, no variables are determined
      // This may be OK, e.g. in case 'Any as List<*>'
      substitution = Maps.newHashMapWithExpectedSize(variables.size());
    }

    // If some of the parameters are not determined by unification, it means that these parameters
    // are lost,
    // let's put stars instead, so that we can only cast to something like List<*>, e.g. (a: Any) as
    // List<*>
    boolean allArgumentsInferred = true;
    for (TypeParameterDescriptor variable : variables) {
      TypeProjection value = substitution.get(variable.getTypeConstructor());
      if (value == null) {
        substitution.put(variable.getTypeConstructor(), TypeUtils.makeStarProjection(variable));
        allArgumentsInferred = false;
      }
    }

    // At this point we have values for all type parameters of List
    // Let's make a type by substituting them: List<T> -> List<Foo>
    KotlinType substituted =
        TypeSubstitutor.create(substitution).substitute(subtypeWithVariables, Variance.INVARIANT);

    return new TypeReconstructionResult(substituted, allArgumentsInferred);
  }
コード例 #4
0
ファイル: TypeUtils.java プロジェクト: alien11689/kotlin
 @NotNull
 public static List<TypeProjection> getDefaultTypeProjections(
     @NotNull List<TypeParameterDescriptor> parameters) {
   List<TypeProjection> result = new ArrayList<TypeProjection>(parameters.size());
   for (TypeParameterDescriptor parameterDescriptor : parameters) {
     result.add(new TypeProjectionImpl(parameterDescriptor.getDefaultType()));
   }
   return org.jetbrains.kotlin.utils.CollectionsKt.toReadOnlyList(result);
 }
コード例 #5
0
ファイル: TypeUnifierTest.java プロジェクト: homburg/kotlin
  @Override
  public void setUp() throws Exception {
    super.setUp();

    ModuleDescriptorImpl module = JetTestUtils.createEmptyModule();
    builtIns = module.getBuiltIns();
    typeResolver = InjectionKt.createContainerForTests(getProject(), module).getTypeResolver();
    x = createTypeVariable("X");
    y = createTypeVariable("Y");
    variables = Sets.newHashSet(x.getTypeConstructor(), y.getTypeConstructor());
  }
コード例 #6
0
  private void checkSupertypesForConsistency(@NotNull ClassDescriptor classDescriptor) {
    Multimap<TypeConstructor, TypeProjection> multimap =
        SubstitutionUtils.buildDeepSubstitutionMultimap(classDescriptor.getDefaultType());
    for (Map.Entry<TypeConstructor, Collection<TypeProjection>> entry :
        multimap.asMap().entrySet()) {
      Collection<TypeProjection> projections = entry.getValue();
      if (projections.size() > 1) {
        TypeConstructor typeConstructor = entry.getKey();
        DeclarationDescriptor declarationDescriptor = typeConstructor.getDeclarationDescriptor();
        assert declarationDescriptor instanceof TypeParameterDescriptor : declarationDescriptor;
        TypeParameterDescriptor typeParameterDescriptor =
            (TypeParameterDescriptor) declarationDescriptor;

        // Immediate arguments of supertypes cannot be projected
        Set<JetType> conflictingTypes = Sets.newLinkedHashSet();
        for (TypeProjection projection : projections) {
          conflictingTypes.add(projection.getType());
        }
        removeDuplicateTypes(conflictingTypes);
        if (conflictingTypes.size() > 1) {
          DeclarationDescriptor containingDeclaration =
              typeParameterDescriptor.getContainingDeclaration();
          assert containingDeclaration instanceof ClassDescriptor : containingDeclaration;
          JetClassOrObject psiElement =
              (JetClassOrObject) DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor);
          assert psiElement != null;
          JetDelegationSpecifierList delegationSpecifierList =
              psiElement.getDelegationSpecifierList();
          assert delegationSpecifierList != null;
          //
          // trace.getErrorHandler().genericError(delegationSpecifierList.getNode(), "Type parameter
          // " + typeParameterDescriptor.getName() + " of " + containingDeclaration.getName() + "
          // has inconsistent values: " + conflictingTypes);
          trace.report(
              INCONSISTENT_TYPE_PARAMETER_VALUES.on(
                  delegationSpecifierList,
                  typeParameterDescriptor,
                  (ClassDescriptor) containingDeclaration,
                  conflictingTypes));
        }
      }
    }
  }
コード例 #7
0
ファイル: TypeUtils.java プロジェクト: alien11689/kotlin
 private static boolean lowerThanBound(
     KotlinTypeChecker typeChecker,
     KotlinType argument,
     TypeParameterDescriptor parameterDescriptor) {
   for (KotlinType bound : parameterDescriptor.getUpperBounds()) {
     if (typeChecker.isSubtypeOf(argument, bound)) {
       if (!argument.getConstructor().equals(bound.getConstructor())) {
         return true;
       }
     }
   }
   return false;
 }
コード例 #8
0
ファイル: OverridingUtil.java プロジェクト: JiaHaoWen/kotlin
  // See JLS 8, 8.4.4 Generic Methods
  // TODO: use TypeSubstitutor instead
  private static boolean areTypeParametersEquivalent(
      @NotNull TypeParameterDescriptor superTypeParameter,
      @NotNull TypeParameterDescriptor subTypeParameter,
      @NotNull KotlinTypeChecker typeChecker) {
    List<KotlinType> superBounds = superTypeParameter.getUpperBounds();
    List<KotlinType> subBounds = new ArrayList<KotlinType>(subTypeParameter.getUpperBounds());
    if (superBounds.size() != subBounds.size()) return false;

    outer:
    for (KotlinType superBound : superBounds) {
      ListIterator<KotlinType> it = subBounds.listIterator();
      while (it.hasNext()) {
        KotlinType subBound = it.next();
        if (areTypesEquivalent(superBound, subBound, typeChecker)) {
          it.remove();
          continue outer;
        }
      }
      return false;
    }

    return true;
  }
コード例 #9
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;
 }
コード例 #10
0
ファイル: CastDiagnosticsUtil.java プロジェクト: nanck/kotlin
 private static boolean allParametersReified(KotlinType subtype) {
   for (TypeParameterDescriptor parameterDescriptor : subtype.getConstructor().getParameters()) {
     if (!parameterDescriptor.isReified()) return false;
   }
   return true;
 }
コード例 #11
0
ファイル: OverridingUtil.java プロジェクト: anujk3/kotlin
  @NotNull
  private OverrideCompatibilityInfo isOverridableBy(
      @NotNull CallableDescriptor superDescriptor,
      @NotNull CallableDescriptor subDescriptor,
      boolean checkReturnType) {
    if (superDescriptor instanceof FunctionDescriptor) {
      if (!(subDescriptor instanceof FunctionDescriptor))
        return OverrideCompatibilityInfo.memberKindMismatch();
    } else if (superDescriptor instanceof PropertyDescriptor) {
      if (!(subDescriptor instanceof PropertyDescriptor))
        return OverrideCompatibilityInfo.memberKindMismatch();
    } else {
      throw new IllegalArgumentException(
          "This type of CallableDescriptor cannot be checked for overridability: "
              + superDescriptor);
    }

    // TODO: check outside of this method
    if (!superDescriptor.getName().equals(subDescriptor.getName())) {
      return OverrideCompatibilityInfo.nameMismatch();
    }

    OverrideCompatibilityInfo receiverAndParameterResult =
        checkReceiverAndParameterCount(superDescriptor, subDescriptor);
    if (receiverAndParameterResult != null) {
      return receiverAndParameterResult;
    }

    List<JetType> superValueParameters = compiledValueParameters(superDescriptor);
    List<JetType> subValueParameters = compiledValueParameters(subDescriptor);

    List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
    List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();

    if (superTypeParameters.size() != subTypeParameters.size()) {
      for (int i = 0; i < superValueParameters.size(); ++i) {
        JetType superValueParameterType = getUpperBound(superValueParameters.get(i));
        JetType subValueParameterType = getUpperBound(subValueParameters.get(i));
        // TODO: compare erasure
        if (!JetTypeChecker.DEFAULT.equalTypes(superValueParameterType, subValueParameterType)) {
          return OverrideCompatibilityInfo.typeParameterNumberMismatch();
        }
      }
      return OverrideCompatibilityInfo.valueParameterTypeMismatch(
          null, null, OverrideCompatibilityInfo.Result.CONFLICT);
    }

    final Map<TypeConstructor, TypeConstructor> matchingTypeConstructors =
        new HashMap<TypeConstructor, TypeConstructor>();
    for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) {
      TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
      TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);
      matchingTypeConstructors.put(
          superTypeParameter.getTypeConstructor(), subTypeParameter.getTypeConstructor());
    }

    JetTypeChecker.TypeConstructorEquality localEqualityAxioms =
        new JetTypeChecker.TypeConstructorEquality() {
          @Override
          public boolean equals(@NotNull TypeConstructor a, @NotNull TypeConstructor b) {
            if (equalityAxioms.equals(a, b)) return true;
            TypeConstructor img1 = matchingTypeConstructors.get(a);
            TypeConstructor img2 = matchingTypeConstructors.get(b);
            if (!(img1 != null && img1.equals(b)) && !(img2 != null && img2.equals(a))) {
              return false;
            }
            return true;
          }
        };

    for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) {
      TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
      TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);

      if (!areTypesEquivalent(
          superTypeParameter.getUpperBoundsAsType(),
          subTypeParameter.getUpperBoundsAsType(),
          localEqualityAxioms)) {
        return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter);
      }
    }

    for (int i = 0, unsubstitutedValueParametersSize = superValueParameters.size();
        i < unsubstitutedValueParametersSize;
        i++) {
      JetType superValueParameter = superValueParameters.get(i);
      JetType subValueParameter = subValueParameters.get(i);

      if (!areTypesEquivalent(superValueParameter, subValueParameter, localEqualityAxioms)) {
        return OverrideCompatibilityInfo.valueParameterTypeMismatch(
            superValueParameter, subValueParameter, INCOMPATIBLE);
      }
    }

    if (checkReturnType) {
      JetType superReturnType = superDescriptor.getReturnType();
      JetType subReturnType = subDescriptor.getReturnType();

      if (superReturnType != null && subReturnType != null) {
        boolean bothErrors = subReturnType.isError() && superReturnType.isError();
        if (!bothErrors
            && !JetTypeChecker.withAxioms(localEqualityAxioms)
                .isSubtypeOf(subReturnType, superReturnType)) {
          return OverrideCompatibilityInfo.returnTypeMismatch(superReturnType, subReturnType);
        }
      }
    }

    for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) {
      if (!externalCondition.isOverridable(superDescriptor, subDescriptor)) {
        return OverrideCompatibilityInfo.externalConditionFailed(externalCondition.getClass());
      }
    }

    return OverrideCompatibilityInfo.success();
  }
コード例 #12
0
ファイル: TypeUtils.java プロジェクト: alien11689/kotlin
 public static boolean isNonReifiedTypeParameter(@NotNull KotlinType type) {
   TypeParameterDescriptor typeParameterDescriptor = getTypeParameterDescriptorOrNull(type);
   return typeParameterDescriptor != null && !typeParameterDescriptor.isReified();
 }
コード例 #13
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;
  }