private void resolvePropertyDeclarationBodies(@NotNull BodiesResolveContext c) { // Member properties Set<JetProperty> processed = Sets.newHashSet(); for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) { if (!(entry.getKey() instanceof JetClass)) continue; JetClass jetClass = (JetClass) entry.getKey(); ClassDescriptorWithResolutionScopes classDescriptor = entry.getValue(); for (JetProperty property : jetClass.getProperties()) { PropertyDescriptor propertyDescriptor = c.getProperties().get(property); assert propertyDescriptor != null; resolveProperty( c, classDescriptor.getScopeForMemberDeclarationResolution(), property, propertyDescriptor); processed.add(property); } } // Top-level properties & properties of objects for (Map.Entry<JetProperty, PropertyDescriptor> entry : c.getProperties().entrySet()) { JetProperty property = entry.getKey(); if (processed.contains(property)) continue; PropertyDescriptor propertyDescriptor = entry.getValue(); resolveProperty(c, null, property, propertyDescriptor); } }
@NotNull private static Set<FqNameUnsafe> computeIndexedFqNames(@NotNull String prefix, int count) { Set<FqNameUnsafe> result = new HashSet<FqNameUnsafe>(); for (int i = 0; i < count; i++) { result.add(fqNameUnsafe(prefix + i)); } return result; }
{ primitiveTypes = new HashSet<FqNameUnsafe>(0); primitiveArrays = new HashSet<FqNameUnsafe>(0); for (PrimitiveType primitiveType : PrimitiveType.values()) { primitiveTypes.add(fqNameUnsafe(primitiveType.getTypeName().asString())); primitiveArrays.add(fqNameUnsafe(primitiveType.getArrayTypeName().asString())); } }
private static <D extends CallableDescriptor> void collectAllOverriddenDescriptors( @NotNull D current, @NotNull Set<D> result) { if (result.contains(current)) return; for (CallableDescriptor callableDescriptor : current.getOriginal().getOverriddenDescriptors()) { @SuppressWarnings("unchecked") D descriptor = (D) callableDescriptor; collectAllOverriddenDescriptors(descriptor, result); result.add(descriptor); } }
private static boolean isTypeConstructorFqNameInSet( @NotNull JetType type, @NotNull Set<FqNameUnsafe> classes) { ClassifierDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor == null) return false; FqNameUnsafe fqName = DescriptorUtils.getFqName(declarationDescriptor); return classes.contains(fqName); }
@NotNull @SuppressWarnings("unchecked") public static <D extends CallableMemberDescriptor> Set<D> getAllOverriddenDeclarations( @NotNull D memberDescriptor) { Set<D> result = new HashSet<D>(); for (CallableMemberDescriptor overriddenDeclaration : memberDescriptor.getOverriddenDescriptors()) { CallableMemberDescriptor.Kind kind = overriddenDeclaration.getKind(); if (kind == DECLARATION) { result.add((D) overriddenDeclaration); } else if (kind == DELEGATION || kind == FAKE_OVERRIDE || kind == SYNTHESIZED) { // do nothing } else { throw new AssertionError("Unexpected callable kind " + kind); } result.addAll(getAllOverriddenDeclarations((D) overriddenDeclaration)); } return result; }
private void checkCyclicConstructorDelegationCall( @NotNull ConstructorDescriptor constructorDescriptor, @NotNull Set<ConstructorDescriptor> visitedConstructors) { if (visitedConstructors.contains(constructorDescriptor)) return; // if visit constructor that is already in current chain // such constructor is on cycle Set<ConstructorDescriptor> visitedInCurrentChain = Sets.newHashSet(); ConstructorDescriptor currentConstructorDescriptor = constructorDescriptor; while (true) { visitedInCurrentChain.add(currentConstructorDescriptor); ConstructorDescriptor delegatedConstructorDescriptor = getDelegatedConstructor(currentConstructorDescriptor); if (delegatedConstructorDescriptor == null) break; // if next delegation call is super or primary constructor or already visited if (!constructorDescriptor .getContainingDeclaration() .equals(delegatedConstructorDescriptor.getContainingDeclaration()) || delegatedConstructorDescriptor.isPrimary() || visitedConstructors.contains(delegatedConstructorDescriptor)) { break; } if (visitedInCurrentChain.contains(delegatedConstructorDescriptor)) { reportEachConstructorOnCycle(delegatedConstructorDescriptor); break; } currentConstructorDescriptor = delegatedConstructorDescriptor; } visitedConstructors.addAll(visitedInCurrentChain); }
// Returns a set of enum or sealed types of which supertypeOwner is an entry or a member @NotNull private static Set<TypeConstructor> getAllowedFinalSupertypes( @NotNull ClassDescriptor descriptor, @NotNull JetClassOrObject jetClass) { Set<TypeConstructor> parentEnumOrSealed; if (jetClass instanceof JetEnumEntry) { parentEnumOrSealed = Collections.singleton( ((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor()); } else { parentEnumOrSealed = Collections.emptySet(); ClassDescriptor currentDescriptor = descriptor; while (currentDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { currentDescriptor = (ClassDescriptor) currentDescriptor.getContainingDeclaration(); if (currentDescriptor.getModality() == Modality.SEALED) { if (parentEnumOrSealed.isEmpty()) { parentEnumOrSealed = new HashSet<TypeConstructor>(); } parentEnumOrSealed.add(currentDescriptor.getTypeConstructor()); } } } return parentEnumOrSealed; }
private void checkSupertypeList( @NotNull ClassDescriptor supertypeOwner, @NotNull Map<JetTypeReference, JetType> supertypes, @NotNull JetClassOrObject jetClass) { Set<TypeConstructor> allowedFinalSupertypes = getAllowedFinalSupertypes(supertypeOwner, jetClass); Set<TypeConstructor> typeConstructors = Sets.newHashSet(); boolean classAppeared = false; for (Map.Entry<JetTypeReference, JetType> entry : supertypes.entrySet()) { JetTypeReference typeReference = entry.getKey(); JetType supertype = entry.getValue(); boolean addSupertype = true; ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { if (ErrorUtils.isError(classDescriptor)) continue; if (classDescriptor.getKind() != ClassKind.INTERFACE) { if (supertypeOwner.getKind() == ClassKind.ENUM_CLASS) { trace.report(CLASS_IN_SUPERTYPE_FOR_ENUM.on(typeReference)); addSupertype = false; } else if (supertypeOwner.getKind() == ClassKind.INTERFACE && !classAppeared && !TypesPackage.isDynamic(supertype) /* avoid duplicate diagnostics */) { trace.report(TRAIT_WITH_SUPERCLASS.on(typeReference)); addSupertype = false; } if (classAppeared) { trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference)); } else { classAppeared = true; } } } else { trace.report(SUPERTYPE_NOT_A_CLASS_OR_TRAIT.on(typeReference)); } TypeConstructor constructor = supertype.getConstructor(); if (addSupertype && !typeConstructors.add(constructor)) { trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference)); } if (DescriptorUtils.isSingleton(classDescriptor)) { trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference)); } else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) { if (classDescriptor.getModality() == Modality.SEALED) { DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration(); while (containingDescriptor != null && containingDescriptor != classDescriptor) { containingDescriptor = containingDescriptor.getContainingDeclaration(); } if (containingDescriptor == null) { trace.report(SEALED_SUPERTYPE.on(typeReference)); } else { trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference)); } } else { trace.report(FINAL_SUPERTYPE.on(typeReference)); } } } }