Skip to content

Commit 14e0e9d

Browse files
committed
Add -package-name to driver
Add packageName to ModuleOutputInfo Add package name validation and diagnostics
1 parent 65e0b28 commit 14e0e9d

File tree

7 files changed

+81
-6
lines changed

7 files changed

+81
-6
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,9 +2427,30 @@ extension Driver {
24272427
// Retrieve and validate module aliases if passed in
24282428
let moduleAliases = moduleAliasesFromInput(parsedOptions.arguments(for: [.moduleAlias]), with: moduleName, onError: diagnosticsEngine)
24292429

2430+
// Validate package name and fall back to module name or module alias if it exists
2431+
var fallback = true
2432+
var validPackageName = ""
2433+
if let packageName = parsedOptions.getLastArgument(.packageName)?.asSingle {
2434+
if !packageName.sd_isSwiftIdentifier {
2435+
diagnosticsEngine.emit(.warning_bad_package_name(packageName, moduleName: moduleName))
2436+
} else if packageName == "Swift" {
2437+
diagnosticsEngine.emit(.warning_bad_package_name(packageName, isReserved: true, moduleName: moduleName))
2438+
} else {
2439+
// valid
2440+
fallback = false
2441+
validPackageName = packageName
2442+
}
2443+
} else {
2444+
diagnosticsEngine.emit(.warning_bad_package_name(nil, moduleName: moduleName))
2445+
}
2446+
2447+
if fallback {
2448+
validPackageName = moduleName
2449+
}
2450+
24302451
// If we're not emitting a module, we're done.
24312452
if moduleOutputKind == nil {
2432-
return ModuleOutputInfo(output: nil, name: moduleName, nameIsFallback: moduleNameIsFallback, aliases: moduleAliases)
2453+
return ModuleOutputInfo(output: nil, name: moduleName, nameIsFallback: moduleNameIsFallback, aliases: moduleAliases, packageName: validPackageName)
24332454
}
24342455

24352456
// Determine the module file to output.
@@ -2463,9 +2484,9 @@ extension Driver {
24632484

24642485
switch moduleOutputKind! {
24652486
case .topLevel:
2466-
return ModuleOutputInfo(output: .topLevel(moduleOutputPath.intern()), name: moduleName, nameIsFallback: moduleNameIsFallback, aliases: moduleAliases)
2487+
return ModuleOutputInfo(output: .topLevel(moduleOutputPath.intern()), name: moduleName, nameIsFallback: moduleNameIsFallback, aliases: moduleAliases, packageName: validPackageName)
24672488
case .auxiliary:
2468-
return ModuleOutputInfo(output: .auxiliary(moduleOutputPath.intern()), name: moduleName, nameIsFallback: moduleNameIsFallback, aliases: moduleAliases)
2489+
return ModuleOutputInfo(output: .auxiliary(moduleOutputPath.intern()), name: moduleName, nameIsFallback: moduleNameIsFallback, aliases: moduleAliases, packageName: validPackageName)
24692490
}
24702491
}
24712492

Sources/SwiftDriver/Driver/ModuleOutputInfo.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,7 @@
5151

5252
/// Map of aliases and real names of modules referenced by source files in the current module
5353
public let aliases: [String: String]?
54+
55+
/// The identity of the package this module belongs to
56+
public let packageName: String
5457
}

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ extension Driver {
311311
commandLine.appendFlags("-module-name", moduleOutputInfo.name)
312312
}
313313

314+
commandLine.appendFlags("-package-name", moduleOutputInfo.packageName)
315+
314316
// Enable frontend Parseable-output, if needed.
315317
if parsedOptions.contains(.useFrontendParseableOutput) {
316318
commandLine.appendFlag("-frontend-parseable-output")

Sources/SwiftDriver/Utilities/Diagnostics.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,23 @@ extension Diagnostic.Message {
115115
return .error("bad module alias \"\(arg)\"")
116116
}
117117

118+
static func warning_bad_package_name(_ packageName: String?,
119+
isReserved: Bool = false,
120+
moduleName: String) -> Diagnostic.Message {
121+
122+
guard let packageName = packageName else {
123+
return .remark("package name is nil; will fall back to module name \"\(moduleName)\"")
124+
}
125+
126+
if packageName.isEmpty {
127+
return .warning("package name is empty; will fall back to module name \"\(moduleName)\"")
128+
}
129+
if isReserved {
130+
return .warning("package name \"\(packageName)\" is reserved for the standard library; will fall back to module name \"\(moduleName)\"")
131+
}
132+
return .warning("package name \"\(packageName)\" is not a valid identifier; will fall back to module name \"\(moduleName)\"")
133+
}
134+
118135
static var error_hermetic_seal_cannot_have_library_evolution: Diagnostic.Message {
119136
.error("Cannot use -experimental-hermetic-seal-at-link with -enable-library-evolution")
120137
}

Sources/SwiftOptions/Options.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ extension Option {
134134
public static let disableCrossImportOverlays: Option = Option("-disable-cross-import-overlays", .flag, attributes: [.frontend, .noDriver], helpText: "Do not automatically import declared cross-import overlays.")
135135
public static let disableDebuggerShadowCopies: Option = Option("-disable-debugger-shadow-copies", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable debugger shadow copies of local variables.This option is only useful for testing the compiler.")
136136
public static let disableDeserializationRecovery: Option = Option("-disable-deserialization-recovery", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't attempt to recover from missing xrefs (etc) in swiftmodules")
137+
public static let disableDeserializationSafety: Option = Option("-disable-deserialization-safety", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't avoid reading potentially unsafe decls in swiftmodules")
137138
public static let disableDiagnosticPasses: Option = Option("-disable-diagnostic-passes", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't run diagnostic passes")
138139
public static let disableEmitGenericClassRoTList: Option = Option("-disable-emit-generic-class-ro_t-list", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable emission of a section with references to class_ro_t of generic class patterns")
139140
public static let disableExperimentalClangImporterDiagnostics: Option = Option("-disable-experimental-clang-importer-diagnostics", .flag, attributes: [.helpHidden, .frontend, .noDriver, .moduleInterface], helpText: "Disable experimental diagnostics when importing C, C++, and Objective-C libraries")
@@ -174,6 +175,7 @@ extension Option {
174175
public static let disableReadonlyStaticObjects: Option = Option("-disable-readonly-static-objects", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Avoid allocating static objects in a read-only data section")
175176
public static let disableReflectionMetadata: Option = Option("-disable-reflection-metadata", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable emission of reflection metadata for nominal types")
176177
public static let disableReflectionNames: Option = Option("-disable-reflection-names", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable emission of names of stored properties and enum cases inreflection metadata")
178+
public static let disableRelativeProtocolWitnessTables: Option = Option("-disable-relative-protocol-witness-tables", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable relative protocol witness tables")
177179
public static let disableRemoveDeprecatedCheck: Option = Option("-disable-remove-deprecated-check", .flag, attributes: [.noDriver], helpText: "Skip diagnosing removal of deprecated symbols")
178180
public static let disableRemoveDeprecatedCheck_: Option = Option("--disable-remove-deprecated-check", .flag, alias: Option.disableRemoveDeprecatedCheck, attributes: [.noDriver], helpText: "Skip diagnosing removal of deprecated symbols")
179181
public static let disableRequirementMachineConcreteContraction: Option = Option("-disable-requirement-machine-concrete-contraction", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable preprocessing pass to eliminate conformance requirements on generic parameters which are made concrete")
@@ -322,6 +324,7 @@ extension Option {
322324
public static let enableCrossImportOverlays: Option = Option("-enable-cross-import-overlays", .flag, attributes: [.frontend, .noDriver], helpText: "Automatically import declared cross-import overlays.")
323325
public static let EnbaleDefaultCMO: Option = Option("-enable-default-cmo", .flag, attributes: [.helpHidden, .frontend], helpText: "Perform conservative cross-module optimization")
324326
public static let enableDeserializationRecovery: Option = Option("-enable-deserialization-recovery", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Attempt to recover from missing xrefs (etc) in swiftmodules")
327+
public static let enableDeserializationSafety: Option = Option("-enable-deserialization-safety", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Avoid reading potentially unsafe decls in swiftmodules")
325328
public static let enableDestroyHoisting: Option = Option("-enable-destroy-hoisting=", .joined, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "true|false", helpText: "Whether to enable destroy hoisting")
326329
public static let enableDynamicReplacementChaining: Option = Option("-enable-dynamic-replacement-chaining", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable chaining of dynamic replacements")
327330
public static let enableEmitGenericClassRoTList: Option = Option("-enable-emit-generic-class-ro_t-list", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable emission of a section with references to class_ro_t of generic class patterns")
@@ -367,6 +370,7 @@ extension Option {
367370
public static let enableOperatorDesignatedTypes: Option = Option("-enable-operator-designated-types", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable operator designated types")
368371
public static let enableOssaModules: Option = Option("-enable-ossa-modules", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Always serialize SIL in ossa form. If this flag is not passed in, when optimizing ownership will be lowered before serializing SIL")
369372
public static let enablePrivateImports: Option = Option("-enable-private-imports", .flag, attributes: [.helpHidden, .frontend, .noInteractive], helpText: "Allows this module's internal and private API to be accessed")
373+
public static let enableRelativeProtocolWitnessTables: Option = Option("-enable-relative-protocol-witness-tables", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable relative protocol witness tables")
370374
public static let enableRequirementMachineOpaqueArchetypes: Option = Option("-enable-requirement-machine-opaque-archetypes", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable more correct opaque archetype support, which is off by default because it might fail to produce a convergent rewrite system")
371375
public static let enableResilience: Option = Option("-enable-resilience", .flag, attributes: [.helpHidden, .frontend, .noDriver, .moduleInterface], helpText: "Deprecated, use -enable-library-evolution instead")
372376
public static let enableRoundTripDebugTypes: Option = Option("-enable-round-trip-debug-types", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enables verification of debug info mangling")
@@ -541,6 +545,7 @@ extension Option {
541545
public static let O: Option = Option("-O", .flag, attributes: [.frontend, .moduleInterface], helpText: "Compile with optimizations", group: .O)
542546
public static let o: Option = Option("-o", .joinedOrSeparate, attributes: [.frontend, .noInteractive, .autolinkExtract, .moduleWrap, .indent, .argumentIsPath], metaVar: "<file>", helpText: "Write output to <file>")
543547
public static let packageDescriptionVersion: Option = Option("-package-description-version", .separate, attributes: [.helpHidden, .frontend, .moduleInterface], metaVar: "<vers>", helpText: "The version number to be applied on the input for the PackageDescription availability kind")
548+
public static let packageName: Option = Option("-package-name", .separate, attributes: [.frontend], helpText: "Name of the package the module belongs to")
544549
public static let parseAsLibrary: Option = Option("-parse-as-library", .flag, attributes: [.frontend, .noInteractive], helpText: "Parse the input file(s) as libraries, not scripts")
545550
public static let parseSil: Option = Option("-parse-sil", .flag, attributes: [.frontend, .noInteractive], helpText: "Parse the input file as SIL code, not Swift source")
546551
public static let parseStdlib: Option = Option("-parse-stdlib", .flag, attributes: [.helpHidden, .frontend, .moduleInterface], helpText: "Parse the input file(s) as the Swift standard library")
@@ -868,6 +873,7 @@ extension Option {
868873
Option.disableCrossImportOverlays,
869874
Option.disableDebuggerShadowCopies,
870875
Option.disableDeserializationRecovery,
876+
Option.disableDeserializationSafety,
871877
Option.disableDiagnosticPasses,
872878
Option.disableEmitGenericClassRoTList,
873879
Option.disableExperimentalClangImporterDiagnostics,
@@ -908,6 +914,7 @@ extension Option {
908914
Option.disableReadonlyStaticObjects,
909915
Option.disableReflectionMetadata,
910916
Option.disableReflectionNames,
917+
Option.disableRelativeProtocolWitnessTables,
911918
Option.disableRemoveDeprecatedCheck,
912919
Option.disableRemoveDeprecatedCheck_,
913920
Option.disableRequirementMachineConcreteContraction,
@@ -1056,6 +1063,7 @@ extension Option {
10561063
Option.enableCrossImportOverlays,
10571064
Option.EnbaleDefaultCMO,
10581065
Option.enableDeserializationRecovery,
1066+
Option.enableDeserializationSafety,
10591067
Option.enableDestroyHoisting,
10601068
Option.enableDynamicReplacementChaining,
10611069
Option.enableEmitGenericClassRoTList,
@@ -1101,6 +1109,7 @@ extension Option {
11011109
Option.enableOperatorDesignatedTypes,
11021110
Option.enableOssaModules,
11031111
Option.enablePrivateImports,
1112+
Option.enableRelativeProtocolWitnessTables,
11041113
Option.enableRequirementMachineOpaqueArchetypes,
11051114
Option.enableResilience,
11061115
Option.enableRoundTripDebugTypes,
@@ -1275,6 +1284,7 @@ extension Option {
12751284
Option.O,
12761285
Option.o,
12771286
Option.packageDescriptionVersion,
1287+
Option.packageName,
12781288
Option.parseAsLibrary,
12791289
Option.parseSil,
12801290
Option.parseStdlib,

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,28 @@ final class SwiftDriverTests: XCTestCase {
689689
try assertNoDriverDiagnostics(args: "swiftc", "foo-bar.swift")
690690
}
691691

692+
func testPackageNameFlag() throws {
693+
try assertNoDriverDiagnostics(args: "swiftc", "file.swift", "bar.swift", "-module-name", "MyModule", "-package-name", "mypkg", "-emit-module", "-emit-module-path", "../../path/to/MyModule.swiftmodule") { driver in
694+
XCTAssertEqual(driver.moduleOutputInfo.packageName, "mypkg")
695+
XCTAssertEqual(driver.moduleOutputInfo.output, .topLevel(try VirtualPath.intern(path: "../../path/to/MyModule.swiftmodule")))
696+
}
697+
}
698+
699+
func testPackageNameFallbacks() throws {
700+
try assertDriverDiagnostics(args: ["swiftc", "file.swift"]) { // -package-name is nil
701+
$1.expect(.warning("package name is nil; will fall back to module name \"file\""))
702+
}
703+
try assertDriverDiagnostics(args: ["swiftc", "file.swift", "-package-name", ""]) {
704+
$1.expect(.warning("package name is empty; will fall back to module name \"file\""))
705+
}
706+
try assertDriverDiagnostics(args: ["swiftc", "file.swift", "-module-name", "Foo", "-package-name", "Swift"]) {
707+
$1.expect(.warning("package name \"Swift\" is reserved for the standard library; will fall back to module name \"Foo\""))
708+
}
709+
try assertDriverDiagnostics(args: ["swiftc", "file.swift", "-module-name", "Foo", "-package-name", "123a!@#$"]) {
710+
$1.expect(.warning("package name \"123a!@#$\" is not a valid identifier; will fall back to module name \"Foo\""))
711+
}
712+
}
713+
692714
func testStandardCompileJobs() throws {
693715
var driver1 = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "-module-name", "Test"])
694716
let plannedJobs = try driver1.planBuild().removingAutolinkExtractJobs()

Tests/SwiftOptionsTests/OptionParsingTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ final class SwiftDriverTests: XCTestCase {
1919
// Parse each kind of option
2020
let results = try options.parse([
2121
"input1", "-color-diagnostics", "-Ifoo", "-I", "bar spaces",
22-
"-I=wibble", "input2", "-module-name", "main",
22+
"-I=wibble", "input2", "-module-name", "main", "-package-name", "mypkg",
2323
"-sanitize=a,b,c", "--", "-foo", "-bar"], for: .batch)
2424
#if os(Windows)
2525
XCTAssertEqual(results.description,
26-
#"input1 -color-diagnostics -I foo -I "bar spaces" -I=wibble input2 -module-name main -sanitize=a,b,c -- -foo -bar"#)
26+
#"input1 -color-diagnostics -I foo -I "bar spaces" -I=wibble input2 -module-name main -package-name mypkg -sanitize=a,b,c -- -foo -bar"#)
2727
#else
2828
XCTAssertEqual(results.description,
29-
"input1 -color-diagnostics -I foo -I 'bar spaces' -I=wibble input2 -module-name main -sanitize=a,b,c -- -foo -bar")
29+
"input1 -color-diagnostics -I foo -I 'bar spaces' -I=wibble input2 -module-name main -package-name mypkg -sanitize=a,b,c -- -foo -bar")
3030
#endif
3131
}
3232

0 commit comments

Comments
 (0)