private static boolean isMoreSpecific( @NotNull CallableMemberDescriptor a, @NotNull CallableMemberDescriptor b) { if (a instanceof SimpleFunctionDescriptor) { assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass(); JetType aReturnType = a.getReturnType(); assert aReturnType != null; JetType bReturnType = b.getReturnType(); assert bReturnType != null; return JetTypeChecker.DEFAULT.isSubtypeOf(aReturnType, bReturnType); } if (a instanceof PropertyDescriptor) { assert b instanceof PropertyDescriptor : "b is " + b.getClass(); if (((PropertyDescriptor) a).isVar() || ((PropertyDescriptor) b).isVar()) { return ((PropertyDescriptor) a).isVar(); } // both vals return JetTypeChecker.DEFAULT.isSubtypeOf( ((PropertyDescriptor) a).getType(), ((PropertyDescriptor) b).getType()); } throw new IllegalArgumentException("Unexpected callable: " + a.getClass()); }
private void assertSubtypingRelation(String subtype, String supertype, boolean expected) { JetType typeNode1 = makeType(subtype); JetType typeNode2 = makeType(supertype); boolean result = JetTypeChecker.DEFAULT.isSubtypeOf(typeNode1, typeNode2); String modifier = expected ? "not " : ""; assertTrue(typeNode1 + " is " + modifier + "a subtype of " + typeNode2, result == expected); }
public boolean isMain(@NotNull JetNamedFunction function) { if (!"main".equals(function.getName())) return false; FunctionDescriptor functionDescriptor = getFunctionDescriptor.fun(function); List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters(); if (parameters.size() != 1) return false; ValueParameterDescriptor parameter = parameters.get(0); JetType parameterType = parameter.getType(); if (!KotlinBuiltIns.isArray(parameterType)) return false; List<TypeProjection> typeArguments = parameterType.getArguments(); if (typeArguments.size() != 1) return false; JetType typeArgument = typeArguments.get(0).getType(); if (!JetTypeChecker.DEFAULT.equalTypes( typeArgument, getBuiltIns(functionDescriptor).getStringType())) return false; if (DescriptorUtils.isTopLevelDeclaration(functionDescriptor)) return true; DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); return containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind().isSingleton() && AnnotationsPackage.hasPlatformStaticAnnotation(functionDescriptor); }
private static boolean isArgumentTypeValid( BindingContext bindingContext, JetValueArgument argument, ValueParameterDescriptor param) { if (argument.getArgumentExpression() != null) { JetType paramType = getActualParameterType(param); JetType exprType = bindingContext.getType(argument.getArgumentExpression()); return exprType == null || JetTypeChecker.DEFAULT.isSubtypeOf(exprType, paramType); } return false; }
private static void removeDuplicateTypes(Set<JetType> conflictingTypes) { for (Iterator<JetType> iterator = conflictingTypes.iterator(); iterator.hasNext(); ) { JetType type = iterator.next(); for (JetType otherType : conflictingTypes) { boolean subtypeOf = JetTypeChecker.DEFAULT.equalTypes(type, otherType); if (type != otherType && subtypeOf) { iterator.remove(); break; } } } }
public boolean isBooleanOrSubtype(@NotNull JetType type) { return JetTypeChecker.DEFAULT.isSubtypeOf(type, getBooleanType()); }
@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(); }