diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 68feecaf114ff..b3325f86f4de9 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -84,6 +84,7 @@ namespace swift { class LazyIterableDeclContextData; class LazyMemberLoader; class ModuleDependencies; + class PackageAttr; class PatternBindingDecl; class PatternBindingInitializer; class SourceFile; @@ -324,6 +325,9 @@ class ASTContext final { llvm::DenseMap SILAutoDiffDerivativeFunctions; + /// Cache of `@package` attributes. + llvm::SetVector> PackageAttrs; + /// Cache of `@differentiable` attributes keyed by parameter indices. Used to /// diagnose duplicate `@differentiable` attributes for the same key. llvm::DenseMap, DifferentiableAttr *> diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def index 20322e5655d2c..8aecbd31fa88f 100644 --- a/include/swift/AST/Attr.def +++ b/include/swift/AST/Attr.def @@ -674,6 +674,12 @@ SIMPLE_DECL_ATTR(_assemblyVision, EmitAssemblyVisionRemarks, ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove, 120) +DECL_ATTR(package, Package, OnImport | + ABIStableToAdd | ABIStableToRemove | + APIStableToAdd | APIStableToRemove | + NotSerialized, + 121) + #undef TYPE_ATTR #undef DECL_ATTR_ALIAS #undef CONTEXTUAL_DECL_ATTR_ALIAS diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h index 272348b701c0a..c38682b724582 100644 --- a/include/swift/AST/Attr.h +++ b/include/swift/AST/Attr.h @@ -1661,6 +1661,45 @@ class OriginallyDefinedInAttr: public DeclAttribute { } }; +/// The `@package` attribute implies its following imports has +/// external package dependencies. +/// +/// Syntax definition is passed in on frontend calls. +class PackageAttr final: public DeclAttribute, + public TrailingCallArguments { + /// The package declaration string. + const StringRef PackageDeclaration; + + unsigned NumArgLabels : 16; + Expr *Arg; + +public: + PackageAttr(SourceLoc AtLoc, SourceRange Range, + StringRef PackageDeclaration, + Expr * Arg, + ArrayRef ArgLabels, + ArrayRef ArgLabelLocs, + bool Implicit) + : DeclAttribute(DAK_Package, AtLoc, Range, Implicit), + PackageDeclaration(PackageDeclaration), + Arg(Arg) { + NumArgLabels = ArgLabels.size(); + initializeCallArguments(ArgLabels, ArgLabelLocs); + } + + /// The getter of `PackageDeclaration`. + const StringRef getPackageDeclaration() { + return PackageDeclaration; + } + + Expr *getArg() const { return Arg; } + unsigned getNumArguments() const { return NumArgLabels; } + + static bool classof(const DeclAttribute *DA) { + return DA->getKind() == DAK_Package; + } +}; + /// Attribute that marks a function as differentiable. /// /// Examples: diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index 644484204d4da..7365fa071307b 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -1860,5 +1860,9 @@ ERROR(expected_closure_literal,none, ERROR(expected_multiple_closures_block_rbrace,none, "expected '}' at the end of a trailing closures block", ()) +// Package declaration errors +ERROR(package_declarations_not_allowed,none, + "package declaration is not allowed", ()) + #define UNDEFINE_DIAGNOSTIC_MACROS #include "DefineDiagnosticMacros.h" diff --git a/include/swift/AST/Import.h b/include/swift/AST/Import.h index b6a1f7a2d352a..1e5e92fb10aa7 100644 --- a/include/swift/AST/Import.h +++ b/include/swift/AST/Import.h @@ -80,6 +80,9 @@ enum class ImportFlags { /// implementation detail of this file. SPIAccessControl = 0x10, + /// The module is explicitly marked to be imported from SwiftPM. + Package = 0x20, + /// Used for DenseMap. Reserved = 0x80 }; diff --git a/include/swift/Basic/FileTypes.def b/include/swift/Basic/FileTypes.def index 158c891df3103..28d5255220110 100644 --- a/include/swift/Basic/FileTypes.def +++ b/include/swift/Basic/FileTypes.def @@ -77,6 +77,8 @@ TYPE("json-dependencies", JSONDependencies, "dependencies.json", // Complete feature information for the given Swift compiler. TYPE("json-features", JSONFeatures, "features.json", "") +// Complete package dependency information for the given Swift files as JSON. +TYPE("package-declarations", PackageDeclarations, "package-declarations.json", "") TYPE("index-data", IndexData, "", "") TYPE("index-unit-output-path", IndexUnitOutputPath, "", "") diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index d2dbef5de265d..f6775f9250c0b 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -443,6 +443,12 @@ namespace swift { // FrontendOptions. bool AllowModuleWithCompilerErrors = false; + // Allow @package attributes in the file. + bool AllowPackageDeclarations = false; + + // Ingore @package attributes in the file. + bool IgnorePackageDeclarations = false; + /// A helper enum to represent whether or not we customized the default /// ASTVerifier behavior via a frontend flag. By default, we do not /// customize. diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 07b74b8fe1a9f..806852e63ad0f 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -154,6 +154,8 @@ class FrontendOptions { ScanDependencies, ///< Scan dependencies of Swift source files PrintVersion, ///< Print version information. PrintFeature, ///< Print supported feature of this compiler + + PrintPackageDeclarations ///< Print package declarations from the Swift source file }; /// Indicates the action the user requested that the frontend perform. @@ -422,6 +424,9 @@ class FrontendOptions { /// Whether to include symbols with SPI information in the symbol graph. bool IncludeSPISymbolsInSymbolGraph = false; + /// Whether to ignore package declarations. + bool IgnorePackageDeclarations = false; + private: static bool canActionEmitDependencies(ActionType); static bool canActionEmitReferenceDependencies(ActionType); diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index fa35027ac696f..52f198cd888c6 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -872,4 +872,8 @@ def new_driver_path : Separate<["-"], "new-driver-path">, MetaVarName<"">, HelpText<"Path of the new driver to be used">; +def ignore_package_declarations : Flag<["-"], "ignore-package-declarations">, + HelpText<"Ignore all package declarations in the file, assuming all external" + "dependencies are provided as modules.">; + } // end let Flags = [FrontendOption, NoDriverOption, HelpHidden] diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 28dcce43f7b78..a5d50e42b5386 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -1013,6 +1013,10 @@ def dump_pcm : Flag<["-"], "dump-pcm">, HelpText<"Dump debugging information about a precompiled Clang module">, ModeOpt, Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>; +def print_package_declarations : Flag<["-"], "print-package-declarations">, + HelpText<"Print all package declarations in the file.">, + ModeOpt, + Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>; // Other Modes def repl : Flag<["-"], "repl">, diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index ab6607f819c55..742afe073a853 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -189,6 +189,16 @@ class Parser { bool allowTopLevelCode() const; + bool ignorePackageDeclarations() const { + return Context.LangOpts.IgnorePackageDeclarations; + } + bool allowPackageDeclaration() const { + return Context.LangOpts.AllowPackageDeclarations || + Context.LangOpts.IgnorePackageDeclarations; + } + + void registerPackageDeclaration(PackageAttr *Package); + const std::vector &getSplitTokens() const { return SplitTokens; } void markSplitToken(tok Kind, StringRef Txt); @@ -1067,6 +1077,10 @@ class Parser { ParserResult parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc); + /// Parse the @package attribute. + ParserResult parsePackageAttribute(SourceLoc AtLoc, + SourceLoc Loc); + /// Parse the @differentiable attribute. ParserResult parseDifferentiableAttribute(SourceLoc AtLoc, SourceLoc Loc); diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp index f75a9ac48e702..e9fc83540fa83 100644 --- a/lib/AST/Attr.cpp +++ b/lib/AST/Attr.cpp @@ -1239,6 +1239,8 @@ StringRef DeclAttribute::getAttrName() const { return "transpose"; case DAK_CompletionHandlerAsync: return "completionHandlerAsync"; + case DAK_Package: + return "package"; } llvm_unreachable("bad DeclAttrKind"); } diff --git a/lib/Basic/FileTypes.cpp b/lib/Basic/FileTypes.cpp index 3d6151940a832..0025edff8b027 100644 --- a/lib/Basic/FileTypes.cpp +++ b/lib/Basic/FileTypes.cpp @@ -84,6 +84,7 @@ bool file_types::isTextual(ID Id) { case file_types::TY_SwiftOverlayFile: case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: + case file_types::TY_PackageDeclarations: return true; case file_types::TY_Image: case file_types::TY_Object: @@ -157,6 +158,7 @@ bool file_types::isAfterLLVM(ID Id) { case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: case file_types::TY_IndexUnitOutputPath: + case file_types::TY_PackageDeclarations: return false; case file_types::TY_INVALID: llvm_unreachable("Invalid type ID."); @@ -208,6 +210,7 @@ bool file_types::isPartOfSwiftCompilation(ID Id) { case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: case file_types::TY_IndexUnitOutputPath: + case file_types::TY_PackageDeclarations: return false; case file_types::TY_INVALID: llvm_unreachable("Invalid type ID."); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index dece951514d03..7014fa2d668b3 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -2062,6 +2062,7 @@ void Driver::buildActions(SmallVectorImpl &TopLevelActions, case file_types::TY_SwiftOverlayFile: case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: + case file_types::TY_PackageDeclarations: // We could in theory handle assembly or LLVM input, but let's not. // FIXME: What about LTO? Diags.diagnose(SourceLoc(), diag::error_unexpected_input_file, diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 1c461611d2529..2e4f7b97680bd 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -640,6 +640,8 @@ const char *ToolChain::JobContext::computeFrontendModeForCompile() const { return "-typecheck"; case file_types::TY_Remapping: return "-update-code"; + case file_types::TY_PackageDeclarations: + return "-print-package-declarations"; case file_types::TY_Nothing: // We were told to output nothing, so get the last mode option and use that. if (const Arg *A = Args.getLastArg(options::OPT_modes_Group)) @@ -904,6 +906,7 @@ ToolChain::constructInvocation(const BackendJobAction &job, case file_types::TY_IndexData: case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: + case file_types::TY_PackageDeclarations: llvm_unreachable("Cannot be output from backend job"); case file_types::TY_Swift: case file_types::TY_dSYM: diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index 9d41f36c4934c..69d80828558e3 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -276,6 +276,8 @@ bool ArgsToFrontendOptionsConverter::convert( Opts.Static = Args.hasArg(OPT_static); + Opts.IgnorePackageDeclarations = Args.hasArg(OPT_ignore_package_declarations); + return false; } @@ -472,6 +474,9 @@ ArgsToFrontendOptionsConverter::determineRequestedAction(const ArgList &args) { return FrontendOptions::ActionType::TypecheckModuleFromInterface; if (Opt.matches(OPT_emit_supported_features)) return FrontendOptions::ActionType::PrintFeature; + + if (Opt.matches(OPT_print_package_declarations)) + return FrontendOptions::ActionType::PrintPackageDeclarations; llvm_unreachable("Unhandled mode option"); } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 0883766549ef9..39a6e69d36d68 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -774,6 +774,13 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.VerifySyntaxTree = true; } + if (FrontendOpts.RequestedAction == FrontendOptions::ActionType::PrintPackageDeclarations) { + Opts.AllowPackageDeclarations = true; + } + if (FrontendOpts.IgnorePackageDeclarations) { + Opts.IgnorePackageDeclarations = true; + } + // Configure lexing to parse and remember comments if: // - Emitting a swiftdoc/swiftsourceinfo // - Performing index-while-building diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp index 452c1e5b99f87..ca73b8935e61f 100644 --- a/lib/Frontend/FrontendOptions.cpp +++ b/lib/Frontend/FrontendOptions.cpp @@ -43,6 +43,7 @@ bool FrontendOptions::needsProperModuleName(ActionType action) { case ActionType::DumpTypeRefinementContexts: case ActionType::DumpPCM: case ActionType::EmitPCH: + case ActionType::PrintPackageDeclarations: return false; case ActionType::EmitSILGen: case ActionType::EmitSIL: @@ -82,6 +83,7 @@ bool FrontendOptions::shouldActionOnlyParse(ActionType action) { case ActionType::ScanDependencies: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return true; default: return false; @@ -104,6 +106,7 @@ bool FrontendOptions::doesActionRequireSwiftStandardLibrary(ActionType action) { case ActionType::CompileModuleFromInterface: case ActionType::TypecheckModuleFromInterface: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::ResolveImports: case ActionType::Typecheck: @@ -169,6 +172,7 @@ bool FrontendOptions::doesActionRequireInputs(ActionType action) { case ActionType::EmitBC: case ActionType::EmitObject: case ActionType::DumpTypeInfo: + case ActionType::PrintPackageDeclarations: return true; } llvm_unreachable("Unknown ActionType"); @@ -211,6 +215,7 @@ bool FrontendOptions::doesActionPerformEndOfPipelineActions(ActionType action) { case ActionType::EmitBC: case ActionType::EmitObject: case ActionType::DumpTypeInfo: + case ActionType::PrintPackageDeclarations: return true; } llvm_unreachable("Unknown ActionType"); @@ -311,6 +316,9 @@ FrontendOptions::formatForPrincipalOutputFileForAction(ActionType action) { return TY_JSONDependencies; case ActionType::PrintFeature: return TY_JSONFeatures; + + case ActionType::PrintPackageDeclarations: + return TY_PackageDeclarations; } llvm_unreachable("unhandled action"); } @@ -352,6 +360,7 @@ bool FrontendOptions::canActionEmitDependencies(ActionType action) { case ActionType::EmitImportedModules: case ActionType::EmitPCM: case ActionType::ScanDependencies: + case ActionType::PrintPackageDeclarations: return true; } llvm_unreachable("unhandled action"); @@ -379,6 +388,7 @@ bool FrontendOptions::canActionEmitReferenceDependencies(ActionType action) { case ActionType::ScanDependencies: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::Typecheck: case ActionType::MergeModules: @@ -428,6 +438,7 @@ bool FrontendOptions::canActionEmitModuleSummary(ActionType action) { case ActionType::EmitModuleOnly: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::EmitSIL: case ActionType::EmitSIB: @@ -464,6 +475,7 @@ bool FrontendOptions::canActionEmitObjCHeader(ActionType action) { case ActionType::ScanDependencies: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::Typecheck: case ActionType::MergeModules: @@ -504,6 +516,7 @@ bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) { case ActionType::ScanDependencies: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::ResolveImports: case ActionType::Typecheck: @@ -550,6 +563,7 @@ bool FrontendOptions::canActionEmitModule(ActionType action) { case ActionType::ScanDependencies: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::MergeModules: case ActionType::EmitModuleOnly: @@ -596,6 +610,7 @@ bool FrontendOptions::canActionEmitInterface(ActionType action) { case ActionType::DumpPCM: case ActionType::ScanDependencies: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::Typecheck: case ActionType::MergeModules: @@ -645,6 +660,7 @@ bool FrontendOptions::doesActionProduceOutput(ActionType action) { case ActionType::DumpPCM: case ActionType::ScanDependencies: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return true; case ActionType::NoneAction: @@ -694,6 +710,7 @@ bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) { case ActionType::ScanDependencies: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return true; } llvm_unreachable("unhandled action"); @@ -721,6 +738,7 @@ bool FrontendOptions::doesActionGenerateSIL(ActionType action) { case ActionType::ScanDependencies: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::EmitSILGen: case ActionType::EmitSIBGen: @@ -770,6 +788,7 @@ bool FrontendOptions::doesActionGenerateIR(ActionType action) { case ActionType::ScanDependencies: case ActionType::PrintVersion: case ActionType::PrintFeature: + case ActionType::PrintPackageDeclarations: return false; case ActionType::Immediate: case ActionType::REPL: diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index c7696dbb66d5e..b4a80fcfa70db 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -41,6 +41,7 @@ #include "swift/Basic/Dwarf.h" #include "swift/Basic/Edit.h" #include "swift/Basic/FileSystem.h" +#include "swift/Basic/JSONSerialization.h" #include "swift/Basic/LLVMInitialize.h" #include "swift/Basic/ParseableOutput.h" #include "swift/Basic/Platform.h" @@ -1143,6 +1144,42 @@ static bool performScanDependencies(CompilerInstance &Instance) { } } +template <> struct swift::json::ObjectTraits> { + static void mapping(Output &out, + std::tuple &value) { + out.mapRequired("file", std::get<0>(value)); + out.mapRequired("line", std::get<1>(value)); + StringRef declaration = std::get<2>(value)->getPackageDeclaration(); + out.mapRequired("declaration", declaration); + } +}; + +template <> +struct swift::json::ArrayTraits>> { + static size_t size(Output &out, llvm::SetVector> &seq) { + return seq.size(); + } + static std::tuple & + element(Output &out, llvm::SetVector> &seq, size_t index) { + return const_cast &>(seq[index]); + } +}; + +static bool printPackageDeclarations(CompilerInstance &Instance) { + for (auto *file : Instance.getMainModule()->getFiles()) { + if (auto *SF = dyn_cast(file)) + (void)SF->getTopLevelDecls(); + } + auto &ctx = Instance.getASTContext(); + if (ctx.hadError()) + return true; + + json::Output Out(llvm::outs(), /*UserInfo=*/{}, /*PrettyPrint=*/true); + Out << ctx.PackageAttrs; + llvm::outs() << "\n"; + return false; +} + static bool performParseOnly(ModuleDecl &MainModule) { // A -parse invocation only cares about the side effects of parsing, so // force the parsing of all the source files. @@ -1226,6 +1263,8 @@ static bool performAction(CompilerInstance &Instance, // MARK: Dependency Scanning Actions case FrontendOptions::ActionType::ScanDependencies: return performScanDependencies(Instance); + case FrontendOptions::ActionType::PrintPackageDeclarations: + return printPackageDeclarations(Instance); // MARK: General Compilation Actions case FrontendOptions::ActionType::Parse: diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 4395546539412..c971c04727de5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -843,6 +843,55 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) { MemberNameLoc)); } +/// Parse a `@package` attribute. +ParserResult +Parser::parsePackageAttribute(SourceLoc AtLoc, SourceLoc Loc) { + StringRef AttrName = "package"; + SourceLoc lParenLoc; + SourceLoc rParenLoc; + SmallVector Args; + SmallVector ArgLabels; + SmallVector ArgLabelLocs; + SmallVector TrailingClosures; + ParserStatus Status; + if (Tok.isNot(tok::l_paren)) { + diagnose(Loc, diag::attr_expected_lparen, AttrName, + /*DeclModifier=*/false); + Status.setIsParseError(); + return Status; + } + Status = parseExprList(tok::l_paren, tok::r_paren, + /*isPostfix=*/true, /*isExprBasic*/true, + lParenLoc, Args, ArgLabels, + ArgLabelLocs, rParenLoc, TrailingClosures, + SyntaxKind::TupleExprElementList); + assert(TrailingClosures.size() == 0 && + "package attribute parsing shouldn't allow trailing closure"); + + // TODO: Examining package declaration syntax + if (Status.isError()) { + return Status; + } + + SourceRange range = SourceRange(lParenLoc, rParenLoc); + StringRef declaration = SourceMgr.extractText( + Lexer::getCharSourceRangeFromSourceRange(SourceMgr, range)); + + SmallVector argLabelsScratch; + SmallVector argLabelLocsScratch; + ArrayRef args = Args; + ArrayRef argLabels = ArgLabels; + ArrayRef argLabelLocs = ArgLabelLocs; + Expr *arg = packSingleArgument(Context, lParenLoc, + args, argLabels, argLabelLocs, + rParenLoc, {}, /*implicit*/false, + argLabelsScratch, argLabelLocsScratch); + + return ParserResult( + new (Context) PackageAttr(AtLoc, range, declaration, arg, + ArgLabels, ArgLabelLocs, /*implicit*/false)); +} + /// Parse a `@differentiable` attribute, returning true on error. /// /// \verbatim @@ -2696,6 +2745,23 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc, Attributes.add(attr); break; } + + case DAK_Package: { + if (!allowPackageDeclaration()) { + diagnose(Loc, diag::package_declarations_not_allowed); + return false; + } + + ParserResult Package; + // Parse package declaration + Package = parsePackageAttribute(AtLoc, Loc); + + if (Package.isNonNull() && !ignorePackageDeclarations()) { + registerPackageDeclaration(Package.get()); + Attributes.add(Package.get()); + } + break; + } } if (DuplicateAttribute) { diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 2efb3205c0ba6..39e680c32cd6a 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -569,6 +569,13 @@ bool Parser::allowTopLevelCode() const { return SF.isScriptMode(); } +void Parser::registerPackageDeclaration(PackageAttr *Package) { + unsigned BufferID = SourceMgr.findBufferContainingLoc(Package->AtLoc); + StringRef File = SourceMgr.getIdentifierForBuffer(BufferID); + unsigned Line = SourceMgr.getPresumedLineAndColumnForLoc(Package->AtLoc, BufferID).first; + Context.PackageAttrs.insert(std::make_tuple(File, Line, Package)); +} + const Token &Parser::peekToken() { return L->peekNextToken(); } diff --git a/lib/Sema/ImportResolution.cpp b/lib/Sema/ImportResolution.cpp index 6a017f687b8ac..192305b112a3a 100644 --- a/lib/Sema/ImportResolution.cpp +++ b/lib/Sema/ImportResolution.cpp @@ -535,6 +535,9 @@ UnboundImport::UnboundImport(ImportDecl *ID) if (ID->getAttrs().hasAttribute()) import.options |= ImportFlags::ImplementationOnly; + if (ID->getAttrs().hasAttribute()) + import.options |= ImportFlags::Package; + if (auto *privateImportAttr = ID->getAttrs().getAttribute()) { import.options |= ImportFlags::PrivateImport; diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index fdc34047036d7..7f587c9f853bb 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -27,6 +27,7 @@ #include "swift/AST/GenericEnvironment.h" #include "swift/AST/GenericSignatureBuilder.h" #include "swift/AST/ImportCache.h" +#include "swift/AST/Module.h" #include "swift/AST/ModuleNameLookup.h" #include "swift/AST/NameLookup.h" #include "swift/AST/NameLookupRequests.h" @@ -114,6 +115,7 @@ class AttributeChecker : public AttributeVisitor { IGNORED_ATTR(ImplicitSelfCapture) IGNORED_ATTR(InheritActorContext) IGNORED_ATTR(Isolated) + IGNORED_ATTR(Package) #undef IGNORED_ATTR void visitAlignmentAttr(AlignmentAttr *attr) { diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index f3498ef46212e..0df75e1e5f458 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -1476,6 +1476,7 @@ namespace { UNINTERESTING_ATTR(ObjCBridged) UNINTERESTING_ATTR(Optional) UNINTERESTING_ATTR(Override) + UNINTERESTING_ATTR(Package) UNINTERESTING_ATTR(RawDocComment) UNINTERESTING_ATTR(Required) UNINTERESTING_ATTR(Convenience) diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 1defcdf5115ad..6ed57dc5559c4 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -1848,6 +1848,8 @@ namespace decls_block { using ClangImporterSynthesizedTypeDeclAttrLayout = BCRecordLayout; using PrivateImportDeclAttrLayout = BCRecordLayout; + using PackageDeclAttrLayout = BCRecordLayout; + using ProjectedValuePropertyDeclAttrLayout = BCRecordLayout< ProjectedValueProperty_DECL_ATTR, BCFixed<1>, // isImplicit diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index e5a9a3b4fd52b..66f7c18fcf014 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -2331,6 +2331,7 @@ class Serializer::DeclSerializer : public DeclVisitor { case DAK_RestatedObjCConformance: case DAK_ClangImporterSynthesizedType: case DAK_PrivateImport: + case DAK_Package: llvm_unreachable("cannot serialize attribute"); case DAK_Count: diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift index 9b7fda53c7167..c6fd71b76bca4 100644 --- a/test/IDE/complete_decl_attribute.swift +++ b/test/IDE/complete_decl_attribute.swift @@ -257,6 +257,7 @@ struct _S { // ON_MEMBER_LAST-DAG: Keyword/None: transpose[#Declaration Attribute#]; name=transpose // ON_MEMBER_LAST-DAG: Keyword/None: noDerivative[#Declaration Attribute#]; name=noDerivative // ON_MEMBER_LAST-DAG: Keyword/None: Sendable[#Declaration Attribute#]; name=Sendable +// ON_MEMBER_LAST-DAG: Keyword/None: Package[#Declaration Attribute#]; name=Package // ON_MEMBER_LAST-NOT: Keyword // ON_MEMBER_LAST: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct // ON_MEMBER_LAST-NOT: Decl[PrecedenceGroup] @@ -307,6 +308,7 @@ func dummy2() {} // KEYWORD_LAST-DAG: Keyword/None: transpose[#Declaration Attribute#]; name=transpose // KEYWORD_LAST-DAG: Keyword/None: noDerivative[#Declaration Attribute#]; name=noDerivative // KEYWORD_LAST-DAG: Keyword/None: Sendable[#Declaration Attribute#]; name=Sendable +// KEYWORD_LAST-DAG: Keyword/None: Package[#Declaration Attribute#]; name=Package // KEYWORD_LAST-NOT: Keyword // KEYWORD_LAST: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct // KEYWORD_LAST: End completions diff --git a/utils/build-script b/utils/build-script index e19967df1fa40..172e33e26fb84 100755 --- a/utils/build-script +++ b/utils/build-script @@ -944,6 +944,8 @@ class BuildScriptInvocation(object): product_classes.append(products.SwiftInspect) if self.args.tsan_libdispatch_test: product_classes.append(products.TSanLibDispatch) + if self.args.build_packageparser: + product_classes.append(products.PackageSyntaxParser) # Keep SwiftDriver at last. # swift-driver's integration with the build scripts is not fully diff --git a/utils/build_swift/build_swift/driver_arguments.py b/utils/build_swift/build_swift/driver_arguments.py index 850c30dce3d86..2c2bb539bf7a0 100644 --- a/utils/build_swift/build_swift/driver_arguments.py +++ b/utils/build_swift/build_swift/driver_arguments.py @@ -193,6 +193,7 @@ def _apply_default_arguments(args): args.test_swiftformat = False args.test_swiftevolve = False args.test_toolchainbenchmarks = False + args.test_packageparser = False # --test implies --test-early-swift-driver # (unless explicitly skipped with `--skip-test-early-swift-driver`) @@ -617,6 +618,9 @@ def create_argument_parser(): option(['--swiftevolve'], toggle_true('build_swiftevolve'), help='build the swift-evolve tool') + option(['--package-parser'], toggle_true('build_packageparser'), + help='build package-syntax-parser') + option(['--swift-driver'], toggle_true('build_swift_driver'), help='build swift-driver') @@ -1097,6 +1101,8 @@ def create_argument_parser(): option('--skip-test-swift-inspect', toggle_false('test_swift_inspect'), help='skip testing swift_inspect') + option('--skip-test-package-parser', toggle_false('test_packageparser'), + help='skip testing package-syntax-parser') # ------------------------------------------------------------------------- in_group('Build settings specific for LLVM') diff --git a/utils/build_swift/resources/SwiftPM-Unified-Build.xcworkspace/contents.xcworkspacedata b/utils/build_swift/resources/SwiftPM-Unified-Build.xcworkspace/contents.xcworkspacedata index 92ad6dd28df5b..10f76c0b65b2a 100644 --- a/utils/build_swift/resources/SwiftPM-Unified-Build.xcworkspace/contents.xcworkspacedata +++ b/utils/build_swift/resources/SwiftPM-Unified-Build.xcworkspace/contents.xcworkspacedata @@ -10,6 +10,9 @@ + + diff --git a/utils/build_swift/tests/expected_options.py b/utils/build_swift/tests/expected_options.py index bc0041beea192..38288e0e5bb82 100644 --- a/utils/build_swift/tests/expected_options.py +++ b/utils/build_swift/tests/expected_options.py @@ -99,6 +99,7 @@ 'test_indexstoredb_sanitize_all': False, 'test_sourcekitlsp_sanitize_all': False, 'build_sourcekitlsp': False, + 'build_packageparser': False, 'install_swiftpm': False, 'install_swiftsyntax': False, 'install_swift_driver': False, @@ -107,6 +108,7 @@ 'install_sourcekitlsp': False, 'install_skstresstester': False, 'install_swiftevolve': False, + 'install_packageparser': False, 'build_toolchainbenchmarks': False, 'build_tvos': True, 'build_tvos_device': False, @@ -257,6 +259,7 @@ 'test_swiftformat': False, 'test_swiftevolve': False, 'test_toolchainbenchmarks': False, + 'test_packageparser': False, 'tvos': False, 'tvos_all': False, 'validation_test': None, @@ -498,6 +501,7 @@ class BuildScriptImplOption(_BaseOption): SetTrueOption('--skstresstester', dest='build_skstresstester'), SetTrueOption('--swiftformat', dest='build_swiftformat'), SetTrueOption('--swiftevolve', dest='build_swiftevolve'), + SetTrueOption('--package-parser', dest='build_packageparser'), SetTrueOption('-B', dest='benchmark'), SetTrueOption('-S', dest='skip_build'), SetTrueOption('-b', dest='build_llbuild'), @@ -630,6 +634,7 @@ class BuildScriptImplOption(_BaseOption): DisableOption('--skip-test-skstresstester', dest='test_skstresstester'), DisableOption('--skip-test-swiftformat', dest='test_swiftformat'), DisableOption('--skip-test-swiftevolve', dest='test_swiftevolve'), + DisableOption('--skip-test-package-parser', dest='test_packageparser'), DisableOption('--skip-test-toolchain-benchmarks', dest='test_toolchainbenchmarks'), DisableOption('--skip-test-swift-inspect', diff --git a/utils/swift_build_support/swift_build_support/products/__init__.py b/utils/swift_build_support/swift_build_support/products/__init__.py index c13c0dc4b5491..00cf5d6dc7309 100644 --- a/utils/swift_build_support/swift_build_support/products/__init__.py +++ b/utils/swift_build_support/swift_build_support/products/__init__.py @@ -34,6 +34,7 @@ from .swiftsyntax import SwiftSyntax from .tsan_libdispatch import TSanLibDispatch from .xctest import XCTest +from .packageparser import PackageSyntaxParser __all__ = [ 'CMark', @@ -61,4 +62,5 @@ 'SourceKitLSP', 'Benchmarks', 'TSanLibDispatch', + 'PackageSyntaxParser', ] diff --git a/utils/swift_build_support/swift_build_support/products/packageparser.py b/utils/swift_build_support/swift_build_support/products/packageparser.py new file mode 100644 index 0000000000000..a377f2a59bdb2 --- /dev/null +++ b/utils/swift_build_support/swift_build_support/products/packageparser.py @@ -0,0 +1,107 @@ +# swift_build_support/products/packageparser.py -----------------*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See https://swift.org/LICENSE.txt for license information +# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- + +import os + +from build_swift.build_swift.constants import MULTIROOT_DATA_FILE_PATH + +from . import cmark +from . import foundation +from . import libcxx +from . import libdispatch +from . import libicu +from . import llbuild +from . import llvm +from . import product +from . import swift +from . import swiftpm +from . import swiftsyntax +from . import xctest +from .. import shell + + +class PackageSyntaxParser(product.Product): + @classmethod + def product_source_name(cls): + """product_source_name() -> str + + The name of the source code directory of this product. + """ + return "package-syntax-parser" + + @classmethod + def is_build_script_impl_product(cls): + return False + + @classmethod + def is_before_build_script_impl_product(cls): + return False + + @classmethod + def is_swiftpm_unified_build_product(cls): + return True + + def run_build_script_helper(self, action, host_target, additional_params=[]): + script_path = os.path.join( + self.source_dir, 'build-script-helper.py') + + configuration = 'release' if self.is_release() else 'debug' + + helper_cmd = [ + script_path, + action, + '--toolchain', self.install_toolchain_path(host_target), + '--configuration', configuration, + '--build-path', self.build_dir, + '--multiroot-data-file', MULTIROOT_DATA_FILE_PATH, + # There might have been a Package.resolved created by other builds + # or by the package being opened using Xcode. Discard that and + # reset the dependencies to be local. + '--update' + ] + if self.args.verbose_build: + helper_cmd.append('--verbose') + helper_cmd.extend(additional_params) + + shell.call(helper_cmd) + + def should_build(self, host_target): + return True + + def build(self, host_target): + self.run_build_script_helper('build', host_target) + + def should_test(self, host_target): + return self.args.test_packageparser + + def test(self, host_target): + self.run_build_script_helper('test', host_target) + + def should_install(self, host_target): + return self.args.install_swiftpm + + def install(self, host_target): + self.run_build_script_helper('install', host_target) + + @classmethod + def get_dependencies(cls): + return [cmark.CMark, + llvm.LLVM, + libcxx.LibCXX, + libicu.LibICU, + swift.Swift, + libdispatch.LibDispatch, + foundation.Foundation, + xctest.XCTest, + llbuild.LLBuild, + swiftpm.SwiftPM, + swiftsyntax.SwiftSyntax] diff --git a/utils/update_checkout/update-checkout-config.json b/utils/update_checkout/update-checkout-config.json index 4ce7f2850f64b..449f230eefd62 100644 --- a/utils/update_checkout/update-checkout-config.json +++ b/utils/update_checkout/update-checkout-config.json @@ -3,7 +3,7 @@ "https-clone-pattern": "https://github.com/%s.git", "repos" : { "swift": { - "remote": { "id": "apple/swift" } }, + "remote": { "id": "stevapple/swift" } }, "cmark": { "remote": { "id": "apple/swift-cmark" } }, "llbuild": { @@ -17,13 +17,13 @@ "swift-crypto": { "remote": { "id": "apple/swift-crypto" } }, "swift-driver": { - "remote": { "id": "apple/swift-driver" } }, + "remote": { "id": "stevapple/swift-driver" } }, "swift-numerics": { - "remote": { "id": "apple/swift-numerics" } }, + "remote": { "id": "apple/swift-numerics" } }, "swift-tools-support-core": { "remote": { "id": "apple/swift-tools-support-core" } }, "swiftpm": { - "remote": { "id": "apple/swift-package-manager" } }, + "remote": { "id": "stevapple/swift-package-manager" } }, "swift-syntax": { "remote": { "id": "apple/swift-syntax" } }, "swift-system": { @@ -53,18 +53,53 @@ "remote": { "id": "KitWare/CMake" }, "platforms": [ "Linux" ] }, - "indexstore-db": { + "indexstore-db": { "remote": { "id": "apple/indexstore-db" } }, "sourcekit-lsp": { "remote": { "id": "apple/sourcekit-lsp" } }, "swift-format": { "remote": { "id": "apple/swift-format" } }, "llvm-project": { - "remote": { "id": "apple/llvm-project" } } + "remote": { "id": "apple/llvm-project" } }, + "package-syntax-parser": { + "remote": { "id": "stevapple/package-syntax-parser" } } }, - "default-branch-scheme": "main", + "default-branch-scheme": "gsoc", "branch-schemes": { - "main": { + "gsoc": { + "aliases": ["gsoc-2021", "package-syntax", "gsoc"], + "repos": { + "llvm-project": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swift": "gsoc-2021", + "cmark": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "llbuild": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swift-tools-support-core": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swiftpm": "gsoc-2021", + "swift-argument-parser": "0.4.3", + "swift-atomics": "0.0.3", + "swift-collections": "0.0.4", + "swift-crypto": "1.1.5", + "swift-driver": "gsoc-2021", + "swift-numerics": "0.1.0", + "swift-syntax": "swift-DEVELOPMENT-SNAPSHOT-2021-07-30-a", + "swift-system": "0.0.2", + "swift-stress-tester": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swift-corelibs-xctest": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swift-corelibs-fswoundation": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swift-corelibs-libdispatch": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swift-integration-tests": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swift-xcode-playground-support": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "ninja": "v1.10.2", + "icu": "release-65-1", + "yams": "4.0.2", + "cmake": "v3.19.6", + "indexstore-db": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "sourcekit-lsp": "swift-DEVELOPMENT-SNAPSHOT-2021-08-14-a", + "swift-format": "e3a4b21152e07873b647831c8cc019d2b44c3eaa", + "package-syntax-parser": "main" + } + }, + "main": { "aliases": ["master", "swift/main", "main"], "repos": { "llvm-project": "swift/main", @@ -96,7 +131,7 @@ "swift-format": "main" } }, - "release/5.5": { + "release/5.5": { "aliases": ["release/5.5", "swift/release/5.5"], "repos": { "llvm-project": "swift/release/5.5",