Skip to content

Commit 2f05fda

Browse files
authored
Merge pull request swiftlang#1283 from apple/es-drv-pr
Add -package-name to driver Add name validation and diagnostics Resolves rdar://105119573.
2 parents ab39e87 + 50806b8 commit 2f05fda

File tree

6 files changed

+66
-4
lines changed

6 files changed

+66
-4
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,12 @@ public struct Driver {
243243
/// The debug information to produce.
244244
@_spi(Testing) public let debugInfo: DebugInfo
245245

246-
// The information about the module to produce.
246+
/// The information about the module to produce.
247247
@_spi(Testing) public let moduleOutputInfo: ModuleOutputInfo
248248

249+
/// Name of the package containing a target module or file.
250+
@_spi(Testing) public let packageName: String?
251+
249252
/// Info needed to write and maybe read the build record.
250253
/// Only present when the driver will be writing the record.
251254
/// Only used for reading when compiling incrementally.
@@ -637,6 +640,13 @@ public struct Driver {
637640
// Compute debug information output.
638641
self.debugInfo = Self.computeDebugInfo(&parsedOptions, diagnosticsEngine: diagnosticEngine)
639642

643+
// Validate package name; if package name is nil, it will be checked
644+
// in the frontend during type check on `package` symbols
645+
self.packageName = parsedOptions.getLastArgument(.packageName)?.asSingle
646+
if let packageName = packageName, !packageName.sd_isSwiftIdentifier {
647+
diagnosticsEngine.emit(.error_bad_package_name(packageName))
648+
}
649+
640650
// Determine the module we're building and whether/how the module file itself will be emitted.
641651
self.moduleOutputInfo = try Self.computeModuleInfo(
642652
&parsedOptions, compilerOutputType: compilerOutputType, compilerMode: compilerMode, linkerOutputType: linkerOutputType,

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

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

314+
if let packageName = packageName {
315+
commandLine.appendFlags("-package-name", packageName)
316+
}
317+
314318
// Enable frontend Parseable-output, if needed.
315319
if parsedOptions.contains(.useFrontendParseableOutput) {
316320
commandLine.appendFlag("-frontend-parseable-output")

Sources/SwiftDriver/Utilities/Diagnostics.swift

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

118+
static func error_bad_package_name(_ packageName: String) -> Diagnostic.Message {
119+
if packageName.isEmpty {
120+
return .error("package name is empty; pass a non-empty string or remove \'-package-name\'")
121+
}
122+
return .error("package name \"\(packageName)\" is not a valid identifier")
123+
}
124+
118125
static var error_hermetic_seal_cannot_have_library_evolution: Diagnostic.Message {
119126
.error("Cannot use -experimental-hermetic-seal-at-link with -enable-library-evolution")
120127
}

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: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,29 @@ final class SwiftDriverTests: XCTestCase {
689689
try assertNoDriverDiagnostics(args: "swiftc", "foo-bar.swift")
690690
}
691691

692+
func testPackageNameFlag() throws {
693+
// -package-name mypkg (valid string)
694+
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
695+
XCTAssertEqual(driver.packageName, "mypkg")
696+
XCTAssertEqual(driver.moduleOutputInfo.output, .topLevel(try VirtualPath.intern(path: "../../path/to/MyModule.swiftmodule")))
697+
}
698+
699+
// -package-name is not passed
700+
try assertNoDriverDiagnostics(args: "swiftc", "file.swift") { driver in
701+
XCTAssertNil(driver.packageName)
702+
XCTAssertEqual(driver.moduleOutputInfo.name, "file")
703+
}
704+
}
705+
706+
func testPackageNameDiags() throws {
707+
try assertDriverDiagnostics(args: ["swiftc", "file.swift", "-package-name", ""]) {
708+
$1.expect(.error("package name is empty; pass a non-empty string or remove \'-package-name\'"))
709+
}
710+
try assertDriverDiagnostics(args: ["swiftc", "file.swift", "-module-name", "Foo", "-package-name", "123a!@#$"]) {
711+
$1.expect(.error("package name \"123a!@#$\" is not a valid identifier"))
712+
}
713+
}
714+
692715
func testStandardCompileJobs() throws {
693716
var driver1 = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "-module-name", "Test"])
694717
let plannedJobs = try driver1.planBuild().removingAutolinkExtractJobs()

Tests/SwiftOptionsTests/OptionParsingTests.swift

Lines changed: 11 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

@@ -64,6 +64,14 @@ final class SwiftDriverTests: XCTestCase {
6464
XCTAssertEqual(error as? OptionParseError, .missingArgument(index: 0, argument: "-module-name"))
6565
}
6666

67+
XCTAssertThrowsError(try options.parse(["-package-name"], for: .batch)) { error in
68+
XCTAssertEqual(error as? OptionParseError, .missingArgument(index: 0, argument: "-package-name"))
69+
}
70+
71+
XCTAssertThrowsError(try options.parse(["-package-name"], for: .interactive)) { error in
72+
XCTAssertEqual(error as? OptionParseError, .missingArgument(index: 0, argument: "-package-name"))
73+
}
74+
6775
XCTAssertThrowsError(try options.parse(["-o"], for: .interactive)) { error in
6876
XCTAssertEqual(error as? OptionParseError, .unsupportedOption(index: 0, argument: "-o", option: .o, currentDriverKind: .interactive))
6977
}

0 commit comments

Comments
 (0)