@NotNull private JetType modifyTypeAccordingToSuperMethods( @NotNull JetType autoType, @NotNull List<TypeAndVariance> typesFromSuper, @NotNull TypeUsage howThisTypeIsUsed) { if (ErrorUtils.isErrorType(autoType)) { return autoType; } boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, howThisTypeIsUsed); ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper); List<TypeProjection> resultArguments = getTypeArgsOfType(autoType, resultClassifier, typesFromSuper); JetScope resultScope; if (resultClassifier instanceof ClassDescriptor) { resultScope = ((ClassDescriptor) resultClassifier).getMemberScope(resultArguments); } else { resultScope = autoType.getMemberScope(); } JetTypeImpl type = new JetTypeImpl( autoType.getAnnotations(), resultClassifier.getTypeConstructor(), resultNullable, resultArguments, resultScope); PropagationHeuristics.checkArrayInReturnType(this, type, typesFromSuper); return type; }
@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { JetType type = QuickFixUtil.getDeclarationReturnType(element); return super.isAvailable(project, editor, file) && type != null && !ErrorUtils.isErrorType(type); }
private void reportIncompleteHierarchyForErrorTypes( ClassDescriptor classDescriptor, List<JetType> result) { for (JetType supertype : result) { if (ErrorUtils.isErrorType(supertype)) { trace.record(BindingContext.INCOMPLETE_HIERARCHY, classDescriptor); } } }
private String renderType(JetType type, boolean shortNamesOnly) { if (type == null) { return escape("[NULL]"); } else if (ErrorUtils.isErrorType(type)) { return escape(type.toString()); } else if (JetStandardClasses.isUnit(type)) { return escape(JetStandardClasses.UNIT_ALIAS + (type.isNullable() ? "?" : "")); } else if (JetStandardClasses.isTupleType(type)) { return escape(renderTupleType(type, shortNamesOnly)); } else if (JetStandardClasses.isFunctionType(type)) { return escape(renderFunctionType(type, shortNamesOnly)); } else { return escape(renderDefaultType(type, shortNamesOnly)); } }
/** * Add import directive corresponding to a type to file when it is needed. * * @param type type to import * @param file file where import directive should be added */ public static void addImportDirectivesIfNeeded(@NotNull JetType type, @NotNull JetFile file) { if (JetPluginUtil.checkTypeIsStandard(type, file.getProject()) || ErrorUtils.isErrorType(type)) { return; } BindingContext bindingContext = getContextForSingleFile(file); PsiElement element = BindingContextUtils.descriptorToDeclaration( bindingContext, type.getMemberScope().getContainingDeclaration()); if (element != null && element.getContainingFile() == file) { // declaration is in the same file, so no import is needed return; } for (ClassDescriptor clazz : TypeUtils.getAllClassDescriptors(type)) { addImportDirective(DescriptorUtils.getFQName(getTopLevelClass(clazz)).toSafe(), file); } }
private void transformSupertypeList( List<JetType> result, PsiClassType[] extendsListTypes, TypeVariableResolver typeVariableResolver) { for (PsiClassType type : extendsListTypes) { PsiClass resolved = type.resolve(); if (resolved != null) { String qualifiedName = resolved.getQualifiedName(); assert qualifiedName != null; if (JvmStdlibNames.JET_OBJECT.getFqName().equalsTo(qualifiedName)) { continue; } } JetType transform = typeTransformer.transformToType(type, TypeUsage.SUPERTYPE, typeVariableResolver); if (ErrorUtils.isErrorType(transform)) { continue; } result.add(TypeUtils.makeNotNullable(transform)); } }
@Override public boolean apply(JetType type) { return !ErrorUtils.isErrorType(type) && (TypeUtils.getClassDescriptor(type) != null); }
private void addConstraint( @NotNull ConstraintKind constraintKind, @NotNull JetType subjectType, @Nullable JetType constrainingType, @NotNull ConstraintPosition constraintPosition) { if (constrainingType == TypeUtils.NO_EXPECTED_TYPE || constrainingType == DONT_CARE || constrainingType == CANT_INFER) { return; } if (constrainingType == null || (ErrorUtils.isErrorType(constrainingType) && constrainingType != PLACEHOLDER_FUNCTION_TYPE)) { hasErrorInConstrainingTypes = true; return; } assert subjectType != TypeUtils.NO_EXPECTED_TYPE : "Subject type shouldn't be NO_EXPECTED_TYPE (in position " + constraintPosition + " )"; if (ErrorUtils.isErrorType(subjectType)) return; DeclarationDescriptor subjectTypeDescriptor = subjectType.getConstructor().getDeclarationDescriptor(); KotlinBuiltIns kotlinBuiltIns = KotlinBuiltIns.getInstance(); if (constrainingType == PLACEHOLDER_FUNCTION_TYPE) { if (!kotlinBuiltIns.isFunctionOrExtensionFunctionType(subjectType)) { if (subjectTypeDescriptor instanceof TypeParameterDescriptor && typeParameterConstraints.get(subjectTypeDescriptor) != null) { // a constraint binds type parameter and any function type, so there is no new info and no // error return; } errorConstraintPositions.add(constraintPosition); } return; } // todo temporary hack // function literal without declaring receiver type { x -> ... } // can be considered as extension function if one is expected // (special type constructor for function/ extension function should be introduced like // PLACEHOLDER_FUNCTION_TYPE) if (constraintKind == SUB_TYPE && kotlinBuiltIns.isFunctionType(constrainingType) && kotlinBuiltIns.isExtensionFunctionType(subjectType)) { constrainingType = createCorrespondingExtensionFunctionType(constrainingType, DONT_CARE); } DeclarationDescriptor constrainingTypeDescriptor = constrainingType.getConstructor().getDeclarationDescriptor(); if (subjectTypeDescriptor instanceof TypeParameterDescriptor) { TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) subjectTypeDescriptor; TypeConstraintsImpl typeConstraints = typeParameterConstraints.get(typeParameter); if (typeConstraints != null) { if (TypeUtils.dependsOnTypeParameterConstructors( constrainingType, Collections.singleton(DONT_CARE.getConstructor()))) { return; } if (subjectType.isNullable() && constrainingType.isNullable()) { constrainingType = TypeUtils.makeNotNullable(constrainingType); } typeConstraints.addBound(constraintKind, constrainingType); return; } } if (constrainingTypeDescriptor instanceof TypeParameterDescriptor) { assert typeParameterConstraints.get(constrainingTypeDescriptor) == null : "Constraining type contains type variable " + constrainingTypeDescriptor.getName(); } if (constraintKind == SUB_TYPE && kotlinBuiltIns.isNothingOrNullableNothing(constrainingType)) { // following constraints are always true: // 'Nothing' is a subtype of any type if (!constrainingType.isNullable()) return; // 'Nothing?' is a subtype of nullable type if (subjectType.isNullable()) return; } if (!(constrainingTypeDescriptor instanceof ClassDescriptor) || !(subjectTypeDescriptor instanceof ClassDescriptor)) { errorConstraintPositions.add(constraintPosition); return; } switch (constraintKind) { case SUB_TYPE: { if (kotlinBuiltIns.isNothingOrNullableNothing(constrainingType)) break; JetType correspondingSupertype = TypeCheckingProcedure.findCorrespondingSupertype(constrainingType, subjectType); if (correspondingSupertype != null) { constrainingType = correspondingSupertype; } break; } case SUPER_TYPE: { if (kotlinBuiltIns.isNothingOrNullableNothing(subjectType)) break; JetType correspondingSupertype = TypeCheckingProcedure.findCorrespondingSupertype(subjectType, constrainingType); if (correspondingSupertype != null) { subjectType = correspondingSupertype; } } case EQUAL: // nothing } if (constrainingType.getConstructor() != subjectType.getConstructor()) { errorConstraintPositions.add(constraintPosition); return; } TypeConstructor typeConstructor = subjectType.getConstructor(); List<TypeProjection> subjectArguments = subjectType.getArguments(); List<TypeProjection> constrainingArguments = constrainingType.getArguments(); List<TypeParameterDescriptor> parameters = typeConstructor.getParameters(); for (int i = 0; i < subjectArguments.size(); i++) { Variance typeParameterVariance = parameters.get(i).getVariance(); TypeProjection subjectArgument = subjectArguments.get(i); TypeProjection constrainingArgument = constrainingArguments.get(i); ConstraintKind typeParameterConstraintKind = getTypeParameterConstraintKind( typeParameterVariance, subjectArgument, constrainingArgument, constraintKind); addConstraint( typeParameterConstraintKind, subjectArgument.getType(), constrainingArgument.getType(), constraintPosition); } }