Skip to content

Commit 1186973

Browse files
committed
[Parseable Output] Compute file extensions using full extension strings
Generation of valid JSON output for parseable output depends on being able to determine file types of inputs and outputs of compilation tasks. FileTypes.def defines multiple file kinds with multiple '.' extensions, such as '.abi.json' or '.features.json', but existing code attempted to compute file outputs only using the trailing suffix of the path after the last '.'. This led to some files not being recognized, which led to us not being able to generate valid JSON. Resolves rdar://92961252
1 parent 20043ad commit 1186973

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

lib/FrontendTool/FrontendTool.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,29 @@ mapFrontendInvocationToAction(const CompilerInvocation &Invocation) {
588588
// StaticLinkJob, DynamicLinkJob
589589
}
590590

591+
// TODO: Apply elsewhere in the compiler
592+
static swift::file_types::ID computeFileTypeForPath(const StringRef Path) {
593+
if (!llvm::sys::path::has_extension(Path))
594+
return swift::file_types::ID::TY_INVALID;
595+
596+
auto Extension = llvm::sys::path::extension(Path).str();
597+
auto FileType = file_types::lookupTypeForExtension(Extension);
598+
if (FileType == swift::file_types::ID::TY_INVALID) {
599+
auto PathStem = llvm::sys::path::stem(Path);
600+
// If this path has a multiple '.' extension (e.g. .abi.json),
601+
// then iterate over all preceeding possible extension variants.
602+
while (llvm::sys::path::has_extension(PathStem)) {
603+
auto NextExtension = llvm::sys::path::extension(PathStem);
604+
Extension = NextExtension.str() + Extension;
605+
FileType = file_types::lookupTypeForExtension(Extension);
606+
if (FileType != swift::file_types::ID::TY_INVALID)
607+
break;
608+
}
609+
}
610+
611+
return FileType;
612+
}
613+
591614
static DetailedTaskDescription
592615
constructDetailedTaskDescription(const CompilerInvocation &Invocation,
593616
ArrayRef<InputFile> PrimaryInputs,
@@ -612,20 +635,15 @@ constructDetailedTaskDescription(const CompilerInvocation &Invocation,
612635
for (const auto &input : PrimaryInputs) {
613636
// Main outputs
614637
auto OutputFile = input.outputFilename();
615-
if (!OutputFile.empty()) {
616-
Outputs.push_back(OutputPair(file_types::lookupTypeForExtension(
617-
llvm::sys::path::extension(OutputFile)),
618-
OutputFile));
619-
}
638+
if (!OutputFile.empty())
639+
Outputs.push_back(OutputPair(computeFileTypeForPath(OutputFile), OutputFile));
620640

621641
// Supplementary outputs
622642
const auto &primarySpecificFiles = input.getPrimarySpecificPaths();
623643
const auto &supplementaryOutputPaths =
624644
primarySpecificFiles.SupplementaryOutputs;
625645
supplementaryOutputPaths.forEachSetOutput([&](const std::string &output) {
626-
Outputs.push_back(OutputPair(file_types::lookupTypeForExtension(
627-
llvm::sys::path::extension(output)),
628-
output));
646+
Outputs.push_back(OutputPair(computeFileTypeForPath(output), output));
629647
});
630648
}
631649
return DetailedTaskDescription{Executable, Arguments, CommandLine, Inputs,

test/Frontend/parseable_output.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
// RUN: %target-swift-frontend -primary-file %s %S/Inputs/filelist-other.swift -o %t.out -module-name parseable_output -emit-module -emit-module-path %t.swiftmodule -serialize-diagnostics -serialize-diagnostics-path %t.dia -frontend-parseable-output 2>&1 | %FileCheck %s
1+
// RUN: %target-swift-frontend -primary-file %s %S/Inputs/filelist-other.swift -o %t.out -module-name parseable_output -empty-abi-descriptor -emit-abi-descriptor-path %t.abi.json -emit-module -emit-module-path %t.swiftmodule -serialize-diagnostics -serialize-diagnostics-path %t.dia -frontend-parseable-output 2>&1 | %FileCheck %s
22
// Check without primary files (WMO):
3-
// RUN: %target-swift-frontend %s %S/Inputs/filelist-other.swift -o %t.out -module-name parseable_output -emit-module -emit-module-path %t.swiftmodule -serialize-diagnostics -serialize-diagnostics-path %t.dia -frontend-parseable-output 2>&1 | %FileCheck %s
3+
// RUN: %target-swift-frontend %s %S/Inputs/filelist-other.swift -o %t.out -module-name parseable_output -empty-abi-descriptor -emit-abi-descriptor-path %t.abi.json -emit-module -emit-module-path %t.swiftmodule -serialize-diagnostics -serialize-diagnostics-path %t.dia -frontend-parseable-output 2>&1 | %FileCheck %s
44

55
// CHECK: {{[1-9][0-9]*}}
66
// CHECK-NEXT: {
77
// CHECK-NEXT: "kind": "began",
88
// CHECK-NEXT: "name": "compile",
9-
// CHECK-NEXT: "command": "{{.*[\\/]}}swift-frontend{{(\.exe)?}}{{.*}} {{.*[\\/]}}parseable_output.swift {{.*[\\/]}}filelist-other.swift -o {{.*[\\/]}}parseable_output.swift.tmp.out -module-name parseable_output -emit-module -emit-module-path {{.*[\\/]}}parseable_output.swift.tmp.swiftmodule -serialize-diagnostics -serialize-diagnostics-path {{.*[\\/]}}parseable_output.swift.tmp.dia -frontend-parseable-output",
9+
// CHECK-NEXT: "command": "{{.*[\\/]}}swift-frontend{{(\.exe)?}}{{.*}} {{.*[\\/]}}parseable_output.swift {{.*[\\/]}}filelist-other.swift -o {{.*[\\/]}}parseable_output.swift.tmp.out -module-name parseable_output -empty-abi-descriptor -emit-abi-descriptor-path {{.*[\\/]}}parseable_output.swift.tmp.abi.json -emit-module -emit-module-path {{.*[\\/]}}parseable_output.swift.tmp.swiftmodule -serialize-diagnostics -serialize-diagnostics-path {{.*[\\/]}}parseable_output.swift.tmp.dia -frontend-parseable-output",
1010
// CHECK-NEXT: "command_executable": "{{.*[\\/]}}swift{{(-frontend|c)?(\.exe)?}}",
1111
// CHECK-NEXT: "command_arguments": [
1212
// CHECK: "{{.*[\\/]}}parseable_output.swift",
1313
// CHECK: "-o",
1414
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift.tmp.out",
1515
// CHECK-NEXT: "-module-name",
1616
// CHECK-NEXT: "parseable_output",
17+
// CHECK-NEXT: "-empty-abi-descriptor",
18+
// CHECK-NEXT: "-emit-abi-descriptor-path",
19+
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift.tmp.abi.json",
1720
// CHECK-NEXT: "-emit-module",
1821
// CHECK-NEXT: "-emit-module-path",
1922
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift.tmp.swiftmodule",
@@ -36,6 +39,10 @@
3639
// CHECK-NEXT: {
3740
// CHECK-NEXT: "type": "diagnostics",
3841
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output.swift.tmp.dia"
42+
// CHECK-NEXT: },
43+
// CHECK-NEXT: {
44+
// CHECK-NEXT: "type": "abi-baseline-json",
45+
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output.swift.tmp.abi.json"
3946
// CHECK-NEXT: }
4047
// CHECK-NEXT: ],
4148
// CHECK-NEXT: "pid": [[PID:[0-9]*]]

0 commit comments

Comments
 (0)