private static JetType createErrorTypeWithCustomDebugName( JetScope memberScope, String debugName) { return new ErrorTypeImpl( new TypeConstructorImpl( ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false, debugName, Collections.<TypeParameterDescriptorImpl>emptyList(), Collections.singleton(KotlinBuiltIns.getInstance().getAnyType())), memberScope); }
private void createTypeConstructors(@NotNull TopDownAnalysisContext c) { for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getClasses().entrySet()) { JetClassOrObject classOrObject = entry.getKey(); MutableClassDescriptor descriptor = (MutableClassDescriptor) entry.getValue(); if (classOrObject instanceof JetClass) { descriptorResolver.resolveMutableClassDescriptor( (JetClass) classOrObject, descriptor, trace); } else if (classOrObject instanceof JetObjectDeclaration) { descriptor.setModality(Modality.FINAL); descriptor.setVisibility( resolveVisibilityFromModifiers(classOrObject, getDefaultClassVisibility(descriptor))); descriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList()); } descriptor.createTypeConstructor(); ClassKind kind = descriptor.getKind(); if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT || kind == ClassKind.ENUM_CLASS) { MutableClassDescriptorLite classObject = descriptor.getClassObjectDescriptor(); assert classObject != null : "Enum entries and named objects should have class objects: " + classOrObject.getText(); JetType supertype; if (kind == ClassKind.ENUM_CLASS) { supertype = KotlinBuiltIns.getInstance().getAnyType(); } else { // This is a clever hack: each enum entry and object declaration (i.e. singleton) has a // synthetic class object. // We make this class object inherit from the singleton here, thus allowing to use the // singleton's class object where // the instance of the singleton is applicable. Effectively all members of the singleton // would be present in its class // object as fake overrides, so you can access them via standard class object notation: // ObjectName.memberName() supertype = descriptor.getDefaultType(); } classObject.setSupertypes(Collections.singleton(supertype)); classObject.createTypeConstructor(); } } }
@NotNull @Override public Set<? extends Class> getArgListStopSearchClasses() { return Collections.singleton(JetFunction.class); }
@NotNull @Override public Set<Class> getArgumentListAllowedParentClasses() { return Collections.singleton((Class) JetCallElement.class); }
@NotNull @Override public Set<FunctionDescriptor> getFunctions(@NotNull Name name) { return Collections.<FunctionDescriptor>singleton(createErrorFunction(this)); }
public class ErrorUtils { private static final ModuleDescriptor ERROR_MODULE = new ModuleDescriptor(Name.special("<ERROR MODULE>")); public static class ErrorScope implements JetScope { private final String debugMessage; private ErrorScope(String debugMessage) { this.debugMessage = debugMessage; } @Override public ClassifierDescriptor getClassifier(@NotNull Name name) { return ERROR_CLASS; } @Override public ClassDescriptor getObjectDescriptor(@NotNull Name name) { return ERROR_CLASS; } @NotNull @Override public Set<ClassDescriptor> getObjectDescriptors() { return Collections.emptySet(); } @NotNull @Override public Set<VariableDescriptor> getProperties(@NotNull Name name) { return ERROR_PROPERTY_GROUP; } @Override public VariableDescriptor getLocalVariable(@NotNull Name name) { return ERROR_PROPERTY; } @Override public NamespaceDescriptor getNamespace(@NotNull Name name) { return null; // TODO : review } @NotNull @Override public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() { return Collections.emptyList(); } @NotNull @Override public Set<FunctionDescriptor> getFunctions(@NotNull Name name) { return Collections.<FunctionDescriptor>singleton(createErrorFunction(this)); } @NotNull @Override public DeclarationDescriptor getContainingDeclaration() { return ERROR_MODULE; } @NotNull @Override public Collection<DeclarationDescriptor> getDeclarationsByLabel(LabelName labelName) { return Collections.emptyList(); } @Override public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) { return null; // TODO : review } @NotNull @Override public Collection<DeclarationDescriptor> getAllDescriptors() { return Collections.emptyList(); } @NotNull @Override public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() { return Collections.emptyList(); } } private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl( ERROR_MODULE, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Name.special("<ERROR CLASS>")) { @NotNull @Override public Collection<ConstructorDescriptor> getConstructors() { return ERROR_CONSTRUCTOR_GROUP; } @NotNull @Override public Modality getModality() { return Modality.OPEN; } @NotNull @Override public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) { return ERROR_CLASS; } }; private static final Set<ConstructorDescriptor> ERROR_CONSTRUCTOR_GROUP = Collections.singleton(createErrorConstructor(0, Collections.<JetType>emptyList())); private static final ConstructorDescriptor ERROR_CONSTRUCTOR = new ConstructorDescriptorImpl( ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), true); static { ERROR_CLASS.initialize( true, Collections.<TypeParameterDescriptor>emptyList(), Collections.<JetType>emptyList(), createErrorScope("ERROR_CLASS"), ERROR_CONSTRUCTOR_GROUP, ERROR_CONSTRUCTOR, false); } public static JetScope createErrorScope(String debugMessage) { return new ErrorScope(debugMessage); } private static final JetType ERROR_PROPERTY_TYPE = createErrorType("<ERROR PROPERTY TYPE>"); private static final VariableDescriptor ERROR_PROPERTY = new PropertyDescriptorImpl( ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibilities.INTERNAL, true, null, ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER, Name.special("<ERROR PROPERTY>"), ERROR_PROPERTY_TYPE, CallableMemberDescriptor.Kind.DECLARATION); private static final Set<VariableDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY); private static SimpleFunctionDescriptor createErrorFunction(ErrorScope ownerScope) { ErrorSimpleFunctionDescriptorImpl function = new ErrorSimpleFunctionDescriptorImpl(ownerScope); function.initialize( null, ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER, Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO Collections.<ValueParameterDescriptor>emptyList(), // TODO createErrorType("<ERROR FUNCTION RETURN TYPE>"), Modality.OPEN, Visibilities.INTERNAL, /*isInline = */ false); return function; } public static ConstructorDescriptor createErrorConstructor( int typeParameterCount, List<JetType> positionedValueParameterTypes) { ConstructorDescriptorImpl r = new ConstructorDescriptorImpl( ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false); r.initialize( Collections.<TypeParameterDescriptor>emptyList(), // TODO Collections.<ValueParameterDescriptor>emptyList(), // TODO Visibilities.INTERNAL); r.setReturnType(createErrorType("<ERROR RETURN TYPE>")); return r; } private static final JetType ERROR_PARAMETER_TYPE = createErrorType("<ERROR VALUE_PARAMETER TYPE>"); private static List<ValueParameterDescriptor> getValueParameters( FunctionDescriptor functionDescriptor, List<JetType> argumentTypes) { List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(); for (int i = 0, argumentTypesSize = argumentTypes.size(); i < argumentTypesSize; i++) { result.add( new ValueParameterDescriptorImpl( functionDescriptor, i, Collections.<AnnotationDescriptor>emptyList(), Name.special("<ERROR VALUE_PARAMETER>"), ERROR_PARAMETER_TYPE, false, null)); } return result; } @NotNull public static JetType createErrorType(String debugMessage) { return createErrorType(debugMessage, createErrorScope(debugMessage)); } private static JetType createErrorType(String debugMessage, JetScope memberScope) { return createErrorTypeWithCustomDebugName(memberScope, "[ERROR : " + debugMessage + "]"); } @NotNull public static JetType createErrorTypeWithCustomDebugName(String debugName) { return createErrorTypeWithCustomDebugName(createErrorScope(debugName), debugName); } private static JetType createErrorTypeWithCustomDebugName( JetScope memberScope, String debugName) { return new ErrorTypeImpl( new TypeConstructorImpl( ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false, debugName, Collections.<TypeParameterDescriptorImpl>emptyList(), Collections.singleton(KotlinBuiltIns.getInstance().getAnyType())), memberScope); } public static JetType createWrongVarianceErrorType(TypeProjection value) { return createErrorType(value + " is not allowed here", value.getType().getMemberScope()); } public static ClassifierDescriptor getErrorClass() { return ERROR_CLASS; } public static boolean isError(@NotNull TypeConstructor typeConstructor) { return typeConstructor == ERROR_CLASS.getTypeConstructor(); } public static boolean isErrorType(@NotNull JetType type) { return type != TypeUtils.NO_EXPECTED_TYPE && !(type instanceof NamespaceType) && ((type instanceof DeferredType && (((DeferredType) type).getActualType() == null || isErrorType(((DeferredType) type).getActualType()))) || type instanceof ErrorTypeImpl || isError(type.getConstructor())); } public static boolean containsErrorType(@Nullable JetType type) { if (type == null) return false; if (type instanceof NamespaceType) return false; if (isErrorType(type)) return true; for (TypeProjection projection : type.getArguments()) { if (containsErrorType(projection.getType())) return true; } return false; } public static boolean isError(@NotNull DeclarationDescriptor candidate) { return candidate == getErrorClass() || candidate.getContainingDeclaration() == getErrorClass() || candidate == ERROR_MODULE; } private static class ErrorTypeImpl implements JetType { private final TypeConstructor constructor; private final JetScope memberScope; private ErrorTypeImpl(TypeConstructor constructor, JetScope memberScope) { this.constructor = constructor; this.memberScope = memberScope; } @NotNull @Override public TypeConstructor getConstructor() { return constructor; } @NotNull @Override public List<TypeProjection> getArguments() { return Collections.emptyList(); } @Override public boolean isNullable() { return false; } @NotNull @Override public JetScope getMemberScope() { return memberScope; } @Override public List<AnnotationDescriptor> getAnnotations() { return Collections.emptyList(); } @Override public String toString() { return constructor.toString(); } } private ErrorUtils() {} }
private void resolveDelegationSpecifierList( final JetClassOrObject jetClass, final MutableClassDescriptor descriptor) { if (!context.completeAnalysisNeeded(jetClass)) return; final ConstructorDescriptor primaryConstructor = descriptor.getUnsubstitutedPrimaryConstructor(); final JetScope scopeForConstructor = primaryConstructor == null ? null : FunctionDescriptorUtil.getFunctionInnerScope( descriptor.getScopeForSupertypeResolution(), primaryConstructor, trace); final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow final Map<JetTypeReference, JetType> supertypes = Maps.newLinkedHashMap(); JetVisitorVoid visitor = new JetVisitorVoid() { private void recordSupertype(JetTypeReference typeReference, JetType supertype) { if (supertype == null) return; supertypes.put(typeReference, supertype); } @Override public void visitDelegationByExpressionSpecifier( JetDelegatorByExpressionSpecifier specifier) { if (descriptor.getKind() == ClassKind.TRAIT) { trace.report(DELEGATION_IN_TRAIT.on(specifier)); } JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); recordSupertype(specifier.getTypeReference(), supertype); if (supertype != null) { DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; if (classDescriptor.getKind() != ClassKind.TRAIT) { trace.report(DELEGATION_NOT_TO_TRAIT.on(specifier.getTypeReference())); } } } JetExpression delegateExpression = specifier.getDelegateExpression(); if (delegateExpression != null) { JetScope scope = scopeForConstructor == null ? descriptor.getScopeForMemberResolution() : scopeForConstructor; JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE, trace); if (type != null && supertype != null && !JetTypeChecker.INSTANCE.isSubtypeOf(type, supertype)) { trace.report(TYPE_MISMATCH.on(delegateExpression, supertype, type)); } } } @Override public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) { JetValueArgumentList valueArgumentList = call.getValueArgumentList(); PsiElement elementToMark = valueArgumentList == null ? call : valueArgumentList; if (descriptor.getKind() == ClassKind.TRAIT) { trace.report(SUPERTYPE_INITIALIZED_IN_TRAIT.on(elementToMark)); } JetTypeReference typeReference = call.getTypeReference(); if (typeReference == null) return; if (descriptor.getUnsubstitutedPrimaryConstructor() == null) { assert descriptor.getKind() == ClassKind.TRAIT; return; } OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall( trace, scopeForConstructor, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE, DataFlowInfo.EMPTY); if (results.isSuccess()) { JetType supertype = results.getResultingDescriptor().getReturnType(); recordSupertype(typeReference, supertype); ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { if (classDescriptor.getKind() == ClassKind.TRAIT) { trace.report(CONSTRUCTOR_IN_TRAIT.on(elementToMark)); } } } else { recordSupertype( typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference)); } } @Override public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) { JetTypeReference typeReference = specifier.getTypeReference(); JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference); recordSupertype(typeReference, supertype); if (supertype == null) return; ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor == null) return; if (descriptor.getKind() != ClassKind.TRAIT && classDescriptor.hasConstructors() && !ErrorUtils.isError(classDescriptor.getTypeConstructor()) && classDescriptor.getKind() != ClassKind.TRAIT) { boolean hasConstructorWithoutParams = false; for (ConstructorDescriptor constructor : classDescriptor.getConstructors()) { if (constructor.getValueParameters().isEmpty()) { hasConstructorWithoutParams = true; } } if (!hasConstructorWithoutParams) { trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier)); } else { trace.report(SUPERTYPE_NOT_INITIALIZED_DEFAULT.on(specifier)); } } } @Override public void visitDelegationToThisCall(JetDelegatorToThisCall thisCall) { throw new IllegalStateException("This-calls should be prohibited by the parser"); } @Override public void visitJetElement(JetElement element) { throw new UnsupportedOperationException(element.getText() + " : " + element); } }; for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) { delegationSpecifier.accept(visitor); } Set<TypeConstructor> parentEnum = Collections.emptySet(); if (jetClass instanceof JetEnumEntry) { parentEnum = Collections.singleton( ((ClassDescriptor) descriptor.getContainingDeclaration().getContainingDeclaration()) .getTypeConstructor()); } checkSupertypeList(descriptor, supertypes, parentEnum); }