diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index d6ec2d481c926..ebded4d931589 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -152,7 +152,9 @@ ERROR(error_mode_cannot_emit_module_summary,none, ERROR(error_mode_cannot_emit_symbol_graph,none, "this mode does not support emitting symbol graph files", ()) ERROR(error_mode_cannot_emit_abi_descriptor,none, - "this mode does not support emitting ABI descriptor", ()) + "this mode does not support emitting ABI descriptor files", ()) +ERROR(error_mode_cannot_emit_api_descriptor,none, + "this mode does not support emitting API descriptor files", ()) ERROR(error_mode_cannot_emit_const_values,none, "this mode does not support emitting extracted const values", ()) ERROR(error_mode_cannot_emit_module_semantic_info,none, @@ -313,6 +315,10 @@ ERROR(tbd_not_supported_with_cmo,none, "Test-Based InstallAPI (TBD) is not support with cross-module-optimization", ()) +WARNING(api_descriptor_only_supported_in_whole_module,none, + "API descriptor generation is only supported when the whole module can be seen", + ()) + ERROR(previous_installname_map_missing,none, "cannot open previous install name map from %0", (StringRef)) diff --git a/include/swift/Basic/FileTypes.def b/include/swift/Basic/FileTypes.def index 4a68242e5e1b8..a8245b3cd2408 100644 --- a/include/swift/Basic/FileTypes.def +++ b/include/swift/Basic/FileTypes.def @@ -98,6 +98,7 @@ TYPE("pch", PCH, "pch", "") TYPE("none", Nothing, "", "") TYPE("abi-baseline-json", SwiftABIDescriptor, "abi.json", "") +TYPE("api-json", SwiftAPIDescriptor, "", "") TYPE("fixit", SwiftFixIt, "", "") TYPE("module-semantic-info", ModuleSemanticInfo, "", "") TYPE("cached-diagnostics", CachedDiagnostics, "", "") diff --git a/include/swift/Basic/SupplementaryOutputPaths.def b/include/swift/Basic/SupplementaryOutputPaths.def index c9c8a44a8ab2c..8b566de3fb20b 100644 --- a/include/swift/Basic/SupplementaryOutputPaths.def +++ b/include/swift/Basic/SupplementaryOutputPaths.def @@ -143,6 +143,9 @@ OUTPUT(ModuleSummaryOutputPath, TY_SwiftModuleSummaryFile) /// The output path to generate ABI baseline. OUTPUT(ABIDescriptorOutputPath, TY_SwiftABIDescriptor) +/// The output path to the module's API description. +OUTPUT(APIDescriptorOutputPath, TY_SwiftAPIDescriptor) + /// The output path for extracted compile-time-known value information OUTPUT(ConstValuesOutputPath, TY_ConstValues) diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index aba24b77283bb..910315d93f8fb 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -428,6 +428,11 @@ class CompilerInvocation { std::string getModuleInterfaceOutputPathForWholeModule() const; std::string getPrivateModuleInterfaceOutputPathForWholeModule() const; + /// APIDescriptorPath only makes sense in whole module compilation mode, + /// so return the APIDescriptorPath when in that mode and fail an assert + /// if not in that mode. + std::string getAPIDescriptorPathForWholeModule() const; + public: /// Given the current configuration of this frontend invocation, a set of /// supplementary output paths, and a module, compute the appropriate set of diff --git a/include/swift/Frontend/FrontendInputsAndOutputs.h b/include/swift/Frontend/FrontendInputsAndOutputs.h index 166c461cd53e6..09a6c96323a96 100644 --- a/include/swift/Frontend/FrontendInputsAndOutputs.h +++ b/include/swift/Frontend/FrontendInputsAndOutputs.h @@ -265,6 +265,7 @@ class FrontendInputsAndOutputs { bool hasModuleInterfaceOutputPath() const; bool hasPrivateModuleInterfaceOutputPath() const; bool hasABIDescriptorOutputPath() const; + bool hasAPIDescriptorOutputPath() const; bool hasConstValuesOutputPath() const; bool hasModuleSemanticInfoOutputPath() const; bool hasModuleSummaryOutputPath() const; diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 7c90061dc178d..b14ca2dfb67f8 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -569,6 +569,7 @@ class FrontendOptions { static bool canActionEmitModuleSummary(ActionType); static bool canActionEmitInterface(ActionType); static bool canActionEmitABIDescriptor(ActionType); + static bool canActionEmitAPIDescriptor(ActionType); static bool canActionEmitConstValues(ActionType); static bool canActionEmitModuleSemanticInfo(ActionType); diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 9c41bfed7c0e7..3a5793f71a8ff 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -626,7 +626,19 @@ def emit_const_values : def emit_const_values_path : Separate<["-"], "emit-const-values-path">, Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath, SupplementaryOutput, CacheInvariant]>, - MetaVarName<"">, HelpText<"Emit the extracted compile-time known values to ">; + MetaVarName<"">, + HelpText<"Emit the extracted compile-time known values to ">; + +def emit_api_descriptor : + Flag<["-"], "emit-api-descriptor">, + Flags<[NoInteractiveOption, SupplementaryOutput, CacheInvariant]>, + HelpText<"Output a JSON file describing the module's API">; +def emit_api_descriptor_path : + Separate<["-"], "emit-api-descriptor-path">, + Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath, + SupplementaryOutput, CacheInvariant]>, + MetaVarName<"">, + HelpText<"Output a JSON file describing the module's API to ">; def emit_objc_header : Flag<["-"], "emit-objc-header">, Flags<[FrontendOption, NoInteractiveOption, SupplementaryOutput, CacheInvariant]>, diff --git a/lib/Basic/FileTypes.cpp b/lib/Basic/FileTypes.cpp index 3a63ecb46b833..556cb2d319554 100644 --- a/lib/Basic/FileTypes.cpp +++ b/lib/Basic/FileTypes.cpp @@ -86,6 +86,7 @@ bool file_types::isTextual(ID Id) { case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: case file_types::TY_SwiftABIDescriptor: + case file_types::TY_SwiftAPIDescriptor: case file_types::TY_ConstValues: return true; case file_types::TY_Image: @@ -164,6 +165,7 @@ bool file_types::isAfterLLVM(ID Id) { case file_types::TY_JSONFeatures: case file_types::TY_IndexUnitOutputPath: case file_types::TY_SwiftABIDescriptor: + case file_types::TY_SwiftAPIDescriptor: case file_types::TY_ConstValues: case file_types::TY_SwiftFixIt: case file_types::TY_ModuleSemanticInfo: @@ -220,6 +222,7 @@ bool file_types::isPartOfSwiftCompilation(ID Id) { case file_types::TY_JSONFeatures: case file_types::TY_IndexUnitOutputPath: case file_types::TY_SwiftABIDescriptor: + case file_types::TY_SwiftAPIDescriptor: case file_types::TY_ConstValues: case file_types::TY_SwiftFixIt: case file_types::TY_ModuleSemanticInfo: diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index c3dc3aa283897..4335a6fdc9598 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -2090,6 +2090,7 @@ void Driver::buildActions(SmallVectorImpl &TopLevelActions, case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: case file_types::TY_SwiftABIDescriptor: + case file_types::TY_SwiftAPIDescriptor: case file_types::TY_ConstValues: case file_types::TY_SwiftFixIt: case file_types::TY_ModuleSemanticInfo: diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index b01044d4f02ae..718b14354be14 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -733,6 +733,7 @@ const char *ToolChain::JobContext::computeFrontendModeForCompile() const { case file_types::TY_SwiftOverlayFile: case file_types::TY_IndexUnitOutputPath: case file_types::TY_SwiftABIDescriptor: + case file_types::TY_SwiftAPIDescriptor: case file_types::TY_ConstValues: case file_types::TY_SwiftFixIt: case file_types::TY_ModuleSemanticInfo: @@ -997,6 +998,7 @@ ToolChain::constructInvocation(const BackendJobAction &job, case file_types::TY_SwiftOverlayFile: case file_types::TY_IndexUnitOutputPath: case file_types::TY_SwiftABIDescriptor: + case file_types::TY_SwiftAPIDescriptor: case file_types::TY_ConstValues: case file_types::TY_SwiftFixIt: case file_types::TY_ModuleSemanticInfo: diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index ffe99cf61339d..2ec677d71c2a4 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -765,6 +765,11 @@ bool ArgsToFrontendOptionsConverter::checkUnusedSupplementaryOutputPaths() Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_abi_descriptor); return true; } + if (!FrontendOptions::canActionEmitAPIDescriptor(Opts.RequestedAction) && + Opts.InputsAndOutputs.hasAPIDescriptorOutputPath()) { + Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_api_descriptor); + return true; + } if (!FrontendOptions::canActionEmitConstValues(Opts.RequestedAction) && Opts.InputsAndOutputs.hasConstValuesOutputPath()) { Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_const_values); diff --git a/lib/Frontend/ArgsToFrontendOutputsConverter.cpp b/lib/Frontend/ArgsToFrontendOutputsConverter.cpp index 9ad436912bfe7..9b8fb60d39c04 100644 --- a/lib/Frontend/ArgsToFrontendOutputsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOutputsConverter.cpp @@ -331,6 +331,8 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments() options::OPT_emit_module_summary_path); auto abiDescriptorOutput = getSupplementaryFilenamesFromArguments( options::OPT_emit_abi_descriptor_path); + auto apiDescriptorOutput = getSupplementaryFilenamesFromArguments( + options::OPT_emit_api_descriptor_path); auto constValuesOutput = getSupplementaryFilenamesFromArguments( options::OPT_emit_const_values_path); auto moduleSemanticInfoOutput = getSupplementaryFilenamesFromArguments( @@ -365,6 +367,7 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments() sop.ModuleSourceInfoOutputPath = (*moduleSourceInfoOutput)[i]; sop.ModuleSummaryOutputPath = (*moduleSummaryOutput)[i]; sop.ABIDescriptorOutputPath = (*abiDescriptorOutput)[i]; + sop.APIDescriptorOutputPath = (*apiDescriptorOutput)[i]; sop.ConstValuesOutputPath = (*constValuesOutput)[i]; sop.ModuleSemanticInfoOutputPath = (*moduleSemanticInfoOutput)[i]; sop.YAMLOptRecordPath = (*optRecordOutput)[i]; @@ -475,8 +478,13 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput( // There is no non-path form of -emit-abi-descriptor-path auto ABIDescriptorOutputPath = pathsFromArguments.ABIDescriptorOutputPath; + + // There is no non-path form of -emit-api-descriptor-path + auto APIDescriptorOutputPath = pathsFromArguments.APIDescriptorOutputPath; + // There is no non-path form of -emit-module-semantic-info-path - auto ModuleSemanticInfoOutputPath = pathsFromArguments.ModuleSemanticInfoOutputPath; + auto ModuleSemanticInfoOutputPath = + pathsFromArguments.ModuleSemanticInfoOutputPath; ID emitModuleOption; std::string moduleExtension; @@ -513,6 +521,7 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput( sop.ModuleSourceInfoOutputPath = moduleSourceInfoOutputPath; sop.ModuleSummaryOutputPath = moduleSummaryOutputPath; sop.ABIDescriptorOutputPath = ABIDescriptorOutputPath; + sop.APIDescriptorOutputPath = APIDescriptorOutputPath; sop.ConstValuesOutputPath = constValuesOutputPath; sop.ModuleSemanticInfoOutputPath = ModuleSemanticInfoOutputPath; sop.YAMLOptRecordPath = YAMLOptRecordPath; diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 610b5f30ab072..23387bbdbb32c 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -165,6 +165,14 @@ CompilerInvocation::getPrivateModuleInterfaceOutputPathForWholeModule() const { .SupplementaryOutputs.PrivateModuleInterfaceOutputPath; } +std::string CompilerInvocation::getAPIDescriptorPathForWholeModule() const { + assert( + getFrontendOptions().InputsAndOutputs.isWholeModule() && + "APIDescriptorPath only makes sense when the whole module can be seen"); + return getPrimarySpecificPathsForAtMostOnePrimary() + .SupplementaryOutputs.APIDescriptorOutputPath; +} + SerializationOptions CompilerInvocation::computeSerializationOptions( const SupplementaryOutputPaths &outs, const ModuleDecl *module) const { const FrontendOptions &opts = getFrontendOptions(); diff --git a/lib/Frontend/FrontendInputsAndOutputs.cpp b/lib/Frontend/FrontendInputsAndOutputs.cpp index 2d5227522e397..d41d92cec23e0 100644 --- a/lib/Frontend/FrontendInputsAndOutputs.cpp +++ b/lib/Frontend/FrontendInputsAndOutputs.cpp @@ -511,6 +511,12 @@ bool FrontendInputsAndOutputs::hasABIDescriptorOutputPath() const { return outs.ABIDescriptorOutputPath; }); } +bool FrontendInputsAndOutputs::hasAPIDescriptorOutputPath() const { + return hasSupplementaryOutputPath( + [](const SupplementaryOutputPaths &outs) -> const std::string & { + return outs.APIDescriptorOutputPath; + }); +} bool FrontendInputsAndOutputs::hasConstValuesOutputPath() const { return hasSupplementaryOutputPath( [](const SupplementaryOutputPaths &outs) -> const std::string & { diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp index eb381672154b4..a449922eb288e 100644 --- a/lib/Frontend/FrontendOptions.cpp +++ b/lib/Frontend/FrontendOptions.cpp @@ -743,6 +743,48 @@ bool FrontendOptions::canActionEmitInterface(ActionType action) { llvm_unreachable("unhandled action"); } +bool FrontendOptions::canActionEmitAPIDescriptor(ActionType action) { + switch (action) { + case ActionType::NoneAction: + case ActionType::Parse: + case ActionType::DumpParse: + case ActionType::DumpInterfaceHash: + case ActionType::DumpAST: + case ActionType::PrintAST: + case ActionType::PrintASTDecl: + case ActionType::EmitImportedModules: + case ActionType::EmitPCH: + case ActionType::DumpScopeMaps: + case ActionType::DumpTypeRefinementContexts: + case ActionType::DumpTypeInfo: + case ActionType::EmitSILGen: + case ActionType::EmitSIBGen: + case ActionType::CompileModuleFromInterface: + case ActionType::TypecheckModuleFromInterface: + case ActionType::Immediate: + case ActionType::REPL: + case ActionType::EmitPCM: + case ActionType::DumpPCM: + case ActionType::ScanDependencies: + case ActionType::PrintFeature: + return false; + case ActionType::ResolveImports: + case ActionType::Typecheck: + case ActionType::MergeModules: + case ActionType::EmitModuleOnly: + case ActionType::EmitSIL: + case ActionType::EmitSIB: + case ActionType::EmitIRGen: + case ActionType::EmitIR: + case ActionType::EmitBC: + case ActionType::EmitAssembly: + case ActionType::EmitObject: + case ActionType::PrintVersion: + return true; + } + llvm_unreachable("unhandled action"); +} + bool FrontendOptions::doesActionProduceOutput(ActionType action) { switch (action) { case ActionType::Parse: diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index afbc57cdf2f37..573b2573d677e 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -809,6 +809,34 @@ static bool writeTBDIfNeeded(CompilerInstance &Instance) { Instance.getOutputBackend(), tbdOpts); } +static bool writeAPIDescriptor(ModuleDecl *M, StringRef OutputPath, + llvm::vfs::OutputBackend &Backend) { + return withOutputPath(M->getDiags(), Backend, OutputPath, + [&](raw_ostream &OS) -> bool { + writeAPIJSONFile(M, OS, /*PrettyPrinted=*/false); + return false; + }); +} + +static bool writeAPIDescriptorIfNeeded(CompilerInstance &Instance) { + const auto &Invocation = Instance.getInvocation(); + const auto &frontendOpts = Invocation.getFrontendOptions(); + if (!frontendOpts.InputsAndOutputs.hasAPIDescriptorOutputPath()) + return false; + + if (!frontendOpts.InputsAndOutputs.isWholeModule()) { + Instance.getDiags().diagnose( + SourceLoc(), diag::api_descriptor_only_supported_in_whole_module); + return false; + } + + const std::string &APIDescriptorPath = + Invocation.getAPIDescriptorPathForWholeModule(); + + return writeAPIDescriptor(Instance.getMainModule(), APIDescriptorPath, + Instance.getOutputBackend()); +} + static bool performCompileStepsPostSILGen(CompilerInstance &Instance, std::unique_ptr SM, ModuleOrSourceFile MSF, @@ -975,6 +1003,10 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs( hadAnyError |= writeTBDIfNeeded(Instance); } + { + hadAnyError |= writeAPIDescriptorIfNeeded(Instance); + } + { hadAnyError |= writeModuleSemanticInfoIfNeeded(Instance); } diff --git a/lib/IRGen/TBDGen.cpp b/lib/IRGen/TBDGen.cpp index 958100d6fdc90..0d0d13a0a1f97 100644 --- a/lib/IRGen/TBDGen.cpp +++ b/lib/IRGen/TBDGen.cpp @@ -664,8 +664,13 @@ class APIGenRecorder final : public APIRecorder { public: APIGenRecorder(apigen::API &api, ModuleDecl *module) : api(api), module(module) { - const auto &MainFile = module->getMainFile(FileUnitKind::SerializedAST); - moduleLoc = apigen::APILoc(MainFile.getModuleDefiningPath().str(), 0, 0); + // If we're working with a serialized module, make the default location + // for symbols the path to the binary module. + if (FileUnit *MainFile = module->getFiles().front()) { + if (MainFile->getKind() == FileUnitKind::SerializedAST) + defaultLoc = + apigen::APILoc(MainFile->getModuleDefiningPath().str(), 0, 0); + } } ~APIGenRecorder() {} @@ -682,7 +687,7 @@ class APIGenRecorder final : public APIRecorder { access = apigen::APIAccess::Private; } - api.addSymbol(symbol, moduleLoc, apigen::APILinkage::Exported, + api.addSymbol(symbol, getAPILocForDecl(decl), apigen::APILinkage::Exported, apigen::APIFlags::None, access, availability); } @@ -700,12 +705,12 @@ class APIGenRecorder final : public APIRecorder { apigen::APIAvailability availability; bool isInstanceMethod = true; auto access = apigen::APIAccess::Public; - if (method.hasDecl()) { - availability = getAvailability(method.getDecl()); - if (method.getDecl()->getDescriptiveKind() == - DescriptiveDeclKind::ClassMethod) + auto decl = method.hasDecl() ? method.getDecl() : nullptr; + if (decl) { + availability = getAvailability(decl); + if (decl->getDescriptiveKind() == DescriptiveDeclKind::ClassMethod) isInstanceMethod = false; - if (isSPI(method.getDecl())) + if (isSPI(decl)) access = apigen::APIAccess::Private; } @@ -716,11 +721,27 @@ class APIGenRecorder final : public APIRecorder { record = addOrGetObjCCategory(ext); if (record) - api.addObjCMethod(record, name, moduleLoc, access, isInstanceMethod, - false, availability); + api.addObjCMethod(record, name, getAPILocForDecl(decl), access, + isInstanceMethod, false, availability); } private: + apigen::APILoc getAPILocForDecl(const Decl *decl) { + if (!decl) + return defaultLoc; + + SourceLoc loc = decl->getLoc(); + if (!loc.isValid()) + return defaultLoc; + + auto &SM = decl->getASTContext().SourceMgr; + unsigned line, col; + std::tie(line, col) = SM.getPresumedLineAndColumnForLoc(loc); + auto displayName = SM.getDisplayNameForLoc(loc); + + return apigen::APILoc(std::string(displayName), line, col); + } + /// Follow the naming schema that IRGen uses for Categories (see /// ClassDataBuilder). using CategoryNameKey = std::pair; @@ -776,8 +797,8 @@ class APIGenRecorder final : public APIRecorder { decl->getFormalAccess() == AccessLevel::Public && decl->isObjC() ? apigen::APILinkage::Exported : apigen::APILinkage::Internal; - auto cls = api.addObjCClass(name, linkage, moduleLoc, access, availability, - superCls); + auto cls = api.addObjCClass(name, linkage, getAPILocForDecl(decl), access, + availability, superCls); classMap.try_emplace(decl, cls); return cls; } @@ -809,15 +830,16 @@ class APIGenRecorder final : public APIRecorder { decl->getMaxAccessLevel() == AccessLevel::Public ? apigen::APILinkage::Exported : apigen::APILinkage::Internal; - auto category = api.addObjCCategory(nameBuffer, linkage, moduleLoc, access, - availability, interface); + auto category = + api.addObjCCategory(nameBuffer, linkage, getAPILocForDecl(decl), access, + availability, interface); categoryMap.try_emplace(decl, category); return category; } apigen::API &api; ModuleDecl *module; - apigen::APILoc moduleLoc; + apigen::APILoc defaultLoc; llvm::DenseMap classMap; llvm::DenseMap diff --git a/test/APIJSON/apigen.swift b/test/APIJSON/apigen.swift index 432f97ad33b9a..d053ef2c68b62 100644 --- a/test/APIJSON/apigen.swift +++ b/test/APIJSON/apigen.swift @@ -2,7 +2,9 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/ModuleCache) // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 -// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s +// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s --check-prefixes=CHECK,CHECK-EXTRACT +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 -emit-api-descriptor-path %t/api.json +// RUN: %validate-json %t/api.json | %FileCheck %s --check-prefixes=CHECK,CHECK-EMIT import Foundation @@ -52,306 +54,360 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule10myFunctionSiyF", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule11myFunction1yyF", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "obsoleted": "10.9" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule11myFunction2yyF", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "unavailable": true // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule11myGlobalVarSivM", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule11myGlobalVarSivg", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule11myGlobalVarSivs", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7method1yyFTj", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7method1yyFTq", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7method2yyFZTj", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.14" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7method2yyFZTq", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.14" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7nonObjcyyFTj", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7nonObjcyyFTq", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCACycfC", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCACycfc", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCMa", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCMn", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCMo", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCMu", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCN", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCfD", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test2CMa", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test2CMm", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test2CMn", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test2CMo", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, +// CHECK-EMIT-NEXT: { +// CHECK-EMIT-NEXT: "name": "_$s8MyModule5Test2CMu", +// CHECK-EMIT-NEXT: "access": "public", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", +// CHECK-EMIT-NEXT: "linkage": "exported" +// CHECK-EMIT-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test2CN", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test2CfD", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test2Cfd", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3C7fromIntACSi_tcfC", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3C7fromIntACSi_tcfCTj", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3C7fromIntACSi_tcfCTq", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3C7fromIntACSi_tcfc", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CACycfC", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CACycfc", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CMa", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CMn", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CMo", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CMu", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CN", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CfD", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CyACSfcfC", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test3CyACSfcfc", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCACycfC", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCACycfc", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCMa", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCMn", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCMo", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCN", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCfD", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: } // CHECK-NEXT: ], @@ -359,7 +415,8 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule4Test", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13", // CHECK-NEXT: "super": "NSObject", @@ -367,19 +424,22 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: { // CHECK-NEXT: "name": "method1", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "method2", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "introduced": "10.14" // CHECK-NEXT: } // CHECK-NEXT: ] @@ -387,24 +447,28 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule5Test3", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "super": "NSObject", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "initFromInt:", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "init:", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] @@ -412,7 +476,8 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule7Derived", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13", // CHECK-NEXT: "super": "_TtC8MyModule4Test", @@ -420,12 +485,14 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: { // CHECK-NEXT: "name": "method1", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] diff --git a/test/APIJSON/extension.swift b/test/APIJSON/extension.swift index f2f919d9c92a9..9165d212c004a 100644 --- a/test/APIJSON/extension.swift +++ b/test/APIJSON/extension.swift @@ -2,7 +2,9 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/ModuleCache) // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 -// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s +// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s --check-prefixes=CHECK,CHECK-EXTRACT +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 -emit-api-descriptor-path %t/api.json +// RUN: %validate-json %t/api.json | %FileCheck %s --check-prefixes=CHECK,CHECK-EMIT import Foundation @@ -47,14 +49,16 @@ extension B { // CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule1B", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/extension.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "super": "NSObject", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/extension.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] @@ -64,14 +68,16 @@ extension B { // CHECK-NEXT: { // CHECK-NEXT: "name": "MyModule", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/extension.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "interface": "NSDictionary", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "__custom_name:", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/extension.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] @@ -79,14 +85,16 @@ extension B { // CHECK-NEXT: { // CHECK-NEXT: "name": "MyModule", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/extension.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "interface": "_TtC8MyModule1B", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "run", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/extension.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] @@ -94,14 +102,16 @@ extension B { // CHECK-NEXT: { // CHECK-NEXT: "name": "MyModule1", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/extension.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "interface": "_TtC8MyModule1B", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "fun", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/extension.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] diff --git a/test/APIJSON/non-objc-class.swift b/test/APIJSON/non-objc-class.swift index 8d97fc0a303be..522dee7852f73 100644 --- a/test/APIJSON/non-objc-class.swift +++ b/test/APIJSON/non-objc-class.swift @@ -2,7 +2,9 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/ModuleCache) // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 -// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s +// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s -check-prefixes=CHECK,CHECK-EXTRACT +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 -emit-api-descriptor-path %t/api.json +// RUN: %validate-json %t/api.json | %FileCheck %s --check-prefixes=CHECK,CHECK-EMIT import Foundation @@ -30,19 +32,22 @@ public class NonObjC3 { // CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule7NonObjC", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift", // CHECK-NEXT: "linkage": "internal", // CHECK-NEXT: "super": "", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "testMethod", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] @@ -50,14 +55,16 @@ public class NonObjC3 { // CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule8NonObjC1", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift", // CHECK-NEXT: "linkage": "internal", // CHECK-NEXT: "super": "", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "testMethod", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] @@ -65,14 +72,16 @@ public class NonObjC3 { // CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule8NonObjC2", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift", // CHECK-NEXT: "linkage": "internal", // CHECK-NEXT: "super": "", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "testMethod", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] @@ -80,14 +89,16 @@ public class NonObjC3 { // CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule8NonObjC3", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift", // CHECK-NEXT: "linkage": "internal", // CHECK-NEXT: "super": "", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/non-objc-class.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] diff --git a/test/APIJSON/non-swift-api.swift b/test/APIJSON/non-swift-api.swift index fe29388458e16..b2e0bc18dfb7a 100644 --- a/test/APIJSON/non-swift-api.swift +++ b/test/APIJSON/non-swift-api.swift @@ -5,6 +5,8 @@ // RUN: cp %S/Inputs/NativeDep.h %t/NativeDep.framework/Headers // RUN: %target-swift-frontend %s -parse-as-library -emit-module -emit-module-interface-path %t/MyModule.swiftinterface -emit-module-path %t/MyModule.swiftmodule -F %t -enable-library-evolution -module-cache-path %t/cache -module-name MyModule -swift-version 5 +// RUN: %target-swift-frontend %s -parse-as-library -emit-module -emit-module-interface-path %t/MyModule.swiftinterface -emit-module-path %t/MyModule.swiftmodule -F %t -enable-library-evolution -module-cache-path %t/cache -module-name MyModule -swift-version 5 -emit-api-descriptor-path %t/api.json +// RUN: %validate-json %t/api.json | %FileCheck %s /// Check that both swiftmodule and swiftinterface can be used as input. // RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftmodule -module-name MyModule -module-cache-path %t/cache -F %t | %FileCheck %s diff --git a/test/APIJSON/spi.swift b/test/APIJSON/spi.swift index 30e43916ec772..8e65881387a00 100644 --- a/test/APIJSON/spi.swift +++ b/test/APIJSON/spi.swift @@ -4,8 +4,10 @@ // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 // RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -emit-module -emit-module-path %t/MyModule.swiftmodule -enable-library-evolution -module-name MyModule -swift-version 5 -// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftmodule -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s --check-prefix=CHECK-SPI +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -parse-as-library -emit-module -emit-module-path %t/MyModule.swiftmodule -enable-library-evolution -module-name MyModule -swift-version 5 +// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftmodule -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s --check-prefixes=CHECK-SPI,CHECK-SPI-EXTRACT +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -parse-as-library -emit-module -emit-module-path %t/MyModule.swiftmodule -enable-library-evolution -module-name MyModule -swift-version 5 -emit-api-descriptor-path %t/api.json +// RUN: %validate-json %t/api.json | %FileCheck %s --check-prefixes=CHECK-SPI,CHECK-SPI-EMIT import Foundation @@ -132,174 +134,195 @@ public func spiAvailableFunc() {} // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassC9spiMethodyyFTj", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassC9spiMethodyyFTq", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCACycfC", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCACycfc", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMa", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMn", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMo", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMu", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCN", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCfD", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2C18spiAvailableMethodyyFTj", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported", // CHECK-SPI-NEXT: "introduced": "10.10" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2C18spiAvailableMethodyyFTq", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported", // CHECK-SPI-NEXT: "introduced": "10.10" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2C9spiMethodyyFTj", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2C9spiMethodyyFTq", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CACycfC", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CACycfc", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CMa", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CMn", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CMo", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CMu", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CN", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CfD", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule15newUnprovenFuncyyF", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_$s8MyModule16spiAvailableFuncyyF", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported", // CHECK-SPI-NEXT: "introduced": "10.10" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_main", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-NEXT: "linkage": "exported" // CHECK-SPI-NEXT: } // CHECK-SPI-NEXT: ], // CHECK-SPI-NEXT: "interfaces": [ // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_TtC8MyModule7MyClass", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported", // CHECK-SPI-NEXT: "super": "NSObject", // CHECK-SPI-NEXT: "instanceMethods": [ // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "spiMethod", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "init", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" // CHECK-SPI-NEXT: } // CHECK-SPI-NEXT: ], // CHECK-SPI-NEXT: "classMethods": [] @@ -307,25 +330,29 @@ public func spiAvailableFunc() {} // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "_TtC8MyModule8MyClass2", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "linkage": "exported", // CHECK-SPI-NEXT: "super": "NSObject", // CHECK-SPI-NEXT: "instanceMethods": [ // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "spiMethod", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "spiAvailableMethod", // CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule", +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-SPI-NEXT: "introduced": "10.10" // CHECK-SPI-NEXT: }, // CHECK-SPI-NEXT: { // CHECK-SPI-NEXT: "name": "init", // CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" +// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" // CHECK-SPI-NEXT: } // CHECK-SPI-NEXT: ], // CHECK-SPI-NEXT: "classMethods": [] diff --git a/test/APIJSON/struct.swift b/test/APIJSON/struct.swift index ac7d27bcc18b9..47c63a69cb1d1 100644 --- a/test/APIJSON/struct.swift +++ b/test/APIJSON/struct.swift @@ -2,7 +2,9 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/ModuleCache) // RUN: %target-swift-frontend %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 -// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s +// RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t/ModuleCache | %FileCheck %s --check-prefixes=CHECK,CHECK-EXTRACT +// RUN: %target-swift-frontend %s -typecheck -parse-as-library -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 -emit-api-descriptor-path %t/api.json +// RUN: %validate-json %t/api.json | %FileCheck %s --check-prefixes=CHECK,CHECK-EMIT // Struct has no objc data. @available(macOS 10.13, *) @@ -19,34 +21,39 @@ public struct TestStruct { // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule10TestStructV10testMethodyyF", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/struct.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.14" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule10TestStructVACycfC", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/struct.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule10TestStructVMa", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/struct.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule10TestStructVMn", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/struct.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule10TestStructVN", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EXTRACT-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/struct.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: } diff --git a/test/Frontend/supplementary-output-support.swift b/test/Frontend/supplementary-output-support.swift index 5f9dc91e807b8..98146963b534d 100644 --- a/test/Frontend/supplementary-output-support.swift +++ b/test/Frontend/supplementary-output-support.swift @@ -36,3 +36,6 @@ // RUN: not %target-swift-frontend -parse -emit-const-values-path %t %s 2>&1 | %FileCheck -check-prefix=PARSE_NO_CONST_VALUES %s // PARSE_NO_CONST_VALUES: error: this mode does not support emitting extracted const values{{$}} + +// RUN: not %target-swift-frontend -parse -emit-api-descriptor-path %t %s 2>&1 | %FileCheck -check-prefix=PARSE_NO_API_DESCRIPTOR %s +// PARSE_NO_API_DESCRIPTOR: error: this mode does not support emitting API descriptor files{{$}}