[IDE] Avoid printing some Swift extensions twice in mixed source frameworks

`printModuleInterfaceDecl` printes extensions right after the type
they are associated with is printed. Extensions associated with a
type that appears in the "target" module shouldn't be added to
`SwiftDecls` because that would lead to double printing them.
This commit is contained in:
Pavel Yaskevich
2025-11-13 10:26:09 -08:00
parent 62a917800d
commit 700d9fd669
5 changed files with 50 additions and 11 deletions

View File

@@ -145,17 +145,6 @@ static bool printModuleInterfaceDecl(Decl *D,
Printer.callAvoidPrintDeclPost(D);
return false;
}
if (auto Ext = dyn_cast<ExtensionDecl>(D)) {
// Clang extensions (categories) are always printed in source order.
// Swift extensions are printed with their associated type unless it's
// a cross-module extension.
if (!extensionHasClangNode(Ext)) {
auto ExtendedNominal = Ext->getExtendedNominal();
if (!ExtendedNominal ||
Ext->getModuleContext() == ExtendedNominal->getModuleContext())
return false;
}
}
// It'd be nice to avoid cloning the options here, but that would require
// SynthesizedExtensionAnalyzer to promise to stay within the lifetime of
@@ -677,6 +666,14 @@ void swift::ide::printModuleInterface(
addToClangDecls(Ext, extensionGetClangNode(Ext));
continue;
}
// Swift extensions are printed with their associated type unless it's
// a cross-module extension.
if (auto extendedTy = Ext->getExtendedNominal()) {
if (TargetMod->isSameModuleLookingThroughOverlays(
extendedTy->getModuleContext()))
continue;
}
}
if (!IsSubmodule) {

View File

@@ -0,0 +1,2 @@
@interface MyType
@end

View File

@@ -0,0 +1,16 @@
// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 6.2
// swift-module-flags: -target arm64-apple-macos10.13 -enable-library-evolution -swift-version 5 -module-name TestExt
@_exported import TestExt
extension MyType {
public struct MyInnerType {
public func test() {}
}
}
extension Int {
public struct OtherInnerType {
}
}

View File

@@ -0,0 +1,4 @@
framework module TestExt {
header "MyType.h"
export *
}

View File

@@ -0,0 +1,20 @@
// RUN: %target-swift-synthesize-interface -module-name TestExt -F %S/Inputs/Frameworks -o - | %FileCheck %s
// REQUIRES: OS=macosx && CPU=arm64
// CHECK: open class MyType
// CHECK: extension MyType {
// CHECK: public struct MyInnerType {
// CHECK: public func test()
// CHECK: }
// CHECK: }
// CHECK-NOT: public struct MyInnerType
// CHECK: extension Int {
// CHECK: public struct OtherInnerType {
// CHECK: }
// CHECK: }
// CHECK-NOT: public struct MyInnerType