@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { if (!super.isAvailable(project, editor, file) || !(file instanceof JetFile)) { return false; } // When running single test 'isAvailable()' is invoked multiple times, so we need to clear // lists. overriddenNonOverridableMembers.clear(); containingDeclarationsNames.clear(); DeclarationDescriptor descriptor = ResolvePackage.resolveToDescriptor(element); if (!(descriptor instanceof CallableMemberDescriptor)) return false; for (CallableMemberDescriptor overriddenDescriptor : getAllDeclaredNonOverridableOverriddenDescriptors((CallableMemberDescriptor) descriptor)) { assert overriddenDescriptor.getKind() == DECLARATION : "Can only be applied to declarations."; PsiElement overriddenMember = descriptorToDeclaration(overriddenDescriptor); if (overriddenMember == null || !QuickFixUtil.canModifyElement(overriddenMember) || !(overriddenMember instanceof JetCallableDeclaration)) { return false; } String containingDeclarationName = overriddenDescriptor.getContainingDeclaration().getName().asString(); overriddenNonOverridableMembers.add((JetCallableDeclaration) overriddenMember); containingDeclarationsNames.add(containingDeclarationName); } return overriddenNonOverridableMembers.size() > 0; }
@Override protected void generateBody() { List<KtObjectDeclaration> companions = new ArrayList<KtObjectDeclaration>(); if (kind != OwnerKind.DEFAULT_IMPLS) { // generate nested classes first and only then generate class body. It necessary to access to // nested CodegenContexts for (KtDeclaration declaration : myClass.getDeclarations()) { if (shouldProcessFirst(declaration)) { // Generate companions after class body generation (need to record all synthetic // accessors) if (declaration instanceof KtObjectDeclaration && ((KtObjectDeclaration) declaration).isCompanion()) { companions.add((KtObjectDeclaration) declaration); CodegenUtilKt.populateCompanionBackingFieldNamesToOuterContextIfNeeded( (KtObjectDeclaration) declaration, context, state); } else { generateDeclaration(declaration); } } } } for (KtDeclaration declaration : myClass.getDeclarations()) { if (!shouldProcessFirst(declaration)) { generateDeclaration(declaration); } } generatePrimaryConstructorProperties(); generateConstructors(); generateDefaultImplsIfNeeded(); for (KtObjectDeclaration companion : companions) { generateDeclaration(companion); } if (!DescriptorUtils.isInterface(descriptor)) { for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) { if (memberDescriptor instanceof CallableMemberDescriptor) { CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor; if (!member.getKind().isReal() && ImplKt.findInterfaceImplementation(member) == null) { if (member instanceof FunctionDescriptor) { functionCodegen.generateBridges((FunctionDescriptor) member); } else if (member instanceof PropertyDescriptor) { PropertyGetterDescriptor getter = ((PropertyDescriptor) member).getGetter(); if (getter != null) { functionCodegen.generateBridges(getter); } PropertySetterDescriptor setter = ((PropertyDescriptor) member).getSetter(); if (setter != null) { functionCodegen.generateBridges(setter); } } } } } } }
private void checkOpenMembers(ClassDescriptorWithResolutionScopes classDescriptor) { if (classCanHaveOpenMembers(classDescriptor)) return; for (CallableMemberDescriptor memberDescriptor : classDescriptor.getDeclaredCallableMembers()) { if (memberDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) continue; JetNamedDeclaration member = (JetNamedDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(memberDescriptor); if (member != null && member.hasModifier(JetTokens.OPEN_KEYWORD)) { trace.report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member)); } } }
private static void collectOverriddenDeclarations( @NotNull CallableMemberDescriptor descriptor, @NotNull Set<CallableMemberDescriptor> result) { if (descriptor.getKind().isReal()) { result.add(descriptor); } else { if (descriptor.getOverriddenDescriptors().isEmpty()) { throw new IllegalStateException( "No overridden descriptors found for (fake override) " + descriptor); } for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) { collectOverriddenDeclarations(overridden, result); } } }
@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; }
@NotNull private static Collection<CallableMemberDescriptor> getAllDeclaredNonOverridableOverriddenDescriptors( @NotNull CallableMemberDescriptor callableMemberDescriptor) { Set<CallableMemberDescriptor> result = Sets.newHashSet(); Collection<CallableMemberDescriptor> nonOverridableOverriddenDescriptors = retainNonOverridableMembers(callableMemberDescriptor.getOverriddenDescriptors()); for (CallableMemberDescriptor overriddenDescriptor : nonOverridableOverriddenDescriptors) { CallableMemberDescriptor.Kind kind = overriddenDescriptor.getKind(); if (kind == DECLARATION) { result.add(overriddenDescriptor); } else if (kind == FAKE_OVERRIDE || kind == DELEGATION) { result.addAll(getAllDeclaredNonOverridableOverriddenDescriptors(overriddenDescriptor)); } else if (kind == SYNTHESIZED) { // do nothing, final synthesized members can't be made open } else { throw new UnsupportedOperationException("Unexpected callable kind " + kind); } } return result; }
@Nullable private static Visibility computeVisibilityToInherit( @NotNull CallableMemberDescriptor memberDescriptor) { Collection<? extends CallableMemberDescriptor> overriddenDescriptors = memberDescriptor.getOverriddenDescriptors(); Visibility maxVisibility = findMaxVisibility(overriddenDescriptors); if (maxVisibility == null) { return null; } if (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { for (CallableMemberDescriptor overridden : overriddenDescriptors) { // An implementation (a non-abstract overridden member) of a fake override should have the // maximum possible visibility if (overridden.getModality() != Modality.ABSTRACT && !overridden.getVisibility().equals(maxVisibility)) { return null; } } return maxVisibility; } return maxVisibility.normalize(); }