diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index 0919940dde6..793de381f81 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -39,7 +39,6 @@ #include "swift/IRGen/TBDGen.h" #include "swift/Migrator/MigratorOptions.h" #include "swift/Parse/IDEInspectionCallbacks.h" -#include "swift/Parse/Parser.h" #include "swift/Sema/SourceLoader.h" #include "swift/Serialization/Validation.h" #include "swift/Subsystems.h" @@ -52,9 +51,9 @@ #include "llvm/Option/ArgList.h" #include "llvm/Support/BLAKE3.h" #include "llvm/Support/HashingOutputBackend.h" -#include "llvm/TargetParser/Host.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/VirtualOutputBackend.h" +#include "llvm/TargetParser/Host.h" #include diff --git a/include/swift/Migrator/FixitFilter.h b/include/swift/Migrator/FixitFilter.h index 7934b41d2eb..718331d76b1 100644 --- a/include/swift/Migrator/FixitFilter.h +++ b/include/swift/Migrator/FixitFilter.h @@ -18,6 +18,7 @@ #define SWIFT_MIGRATOR_FIXITFILTER_H #include "swift/AST/DiagnosticConsumer.h" +#include "swift/AST/DiagnosticsParse.h" #include "swift/AST/DiagnosticsSema.h" namespace swift { diff --git a/include/swift/Parse/ParseDeclName.h b/include/swift/Parse/ParseDeclName.h new file mode 100644 index 00000000000..a07c1752008 --- /dev/null +++ b/include/swift/Parse/ParseDeclName.h @@ -0,0 +1,100 @@ +//===--- ParseDeclName.h ----------------------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2024 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 +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_PARSE_PARSEDECLNAME_H +#define SWIFT_PARSE_PARSEDECLNAME_H + +#include "swift/AST/Identifier.h" +#include "swift/Basic/LLVM.h" +#include "swift/Parse/Lexer.h" + +namespace swift { + +/// Describes a parsed declaration name. +struct ParsedDeclName { + /// The name of the context of which the corresponding entity should + /// become a member. + StringRef ContextName; + + /// The base name of the declaration. + StringRef BaseName; + + /// The argument labels for a function declaration. + SmallVector ArgumentLabels; + + /// Whether this is a function name (vs. a value name). + bool IsFunctionName = false; + + /// Whether this is a getter for the named property. + bool IsGetter = false; + + /// Whether this is a setter for the named property. + bool IsSetter = false; + + bool IsSubscript = false; + + /// For a declaration name that makes the declaration into an + /// instance member, the index of the "Self" parameter. + std::optional SelfIndex; + + /// Determine whether this is a valid name. + explicit operator bool() const { return !BaseName.empty(); } + + /// Whether this declaration name turns the declaration into a + /// member of some named context. + bool isMember() const { return !ContextName.empty(); } + + /// Whether the result is translated into an instance member. + bool isInstanceMember() const { + return isMember() && static_cast(SelfIndex); + } + + /// Whether the result is translated into a static/class member. + bool isClassMember() const { + return isMember() && !static_cast(SelfIndex); + } + + /// Whether this is a property accessor. + bool isPropertyAccessor() const { return IsGetter || IsSetter; } + + /// Whether this is an operator. + bool isOperator() const { return Lexer::isOperator(BaseName); } + + /// Form a declaration name from this parsed declaration name. + DeclName formDeclName(ASTContext &ctx, bool isSubscript = false, + bool isCxxClassTemplateSpec = false) const; + + /// Form a declaration name from this parsed declaration name. + DeclNameRef formDeclNameRef(ASTContext &ctx, bool isSubscript = false, + bool isCxxClassTemplateSpec = false) const; +}; + +/// Parse a stringified Swift declaration name, +/// e.g. "Foo.translateBy(self:x:y:)". +ParsedDeclName parseDeclName(StringRef name) LLVM_READONLY; + +/// Form a Swift declaration name from its constituent parts. +DeclName formDeclName(ASTContext &ctx, StringRef baseName, + ArrayRef argumentLabels, bool isFunctionName, + bool isInitializer, bool isSubscript = false, + bool isCxxClassTemplateSpec = false); + +/// Form a Swift declaration name reference from its constituent parts. +DeclNameRef formDeclNameRef(ASTContext &ctx, StringRef baseName, + ArrayRef argumentLabels, + bool isFunctionName, bool isInitializer, + bool isSubscript = false, + bool isCxxClassTemplateSpec = false); + +} // namespace swift + +#endif // SWIFT_PARSE_PARSEDECLNAME_H diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index ca475d44826..bfd810a860a 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2024 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 @@ -2118,67 +2118,6 @@ public: ParserResult parseExprFromSyntaxTree(); }; -/// Describes a parsed declaration name. -struct ParsedDeclName { - /// The name of the context of which the corresponding entity should - /// become a member. - StringRef ContextName; - - /// The base name of the declaration. - StringRef BaseName; - - /// The argument labels for a function declaration. - SmallVector ArgumentLabels; - - /// Whether this is a function name (vs. a value name). - bool IsFunctionName = false; - - /// Whether this is a getter for the named property. - bool IsGetter = false; - - /// Whether this is a setter for the named property. - bool IsSetter = false; - - bool IsSubscript = false; - - /// For a declaration name that makes the declaration into an - /// instance member, the index of the "Self" parameter. - std::optional SelfIndex; - - /// Determine whether this is a valid name. - explicit operator bool() const { return !BaseName.empty(); } - - /// Whether this declaration name turns the declaration into a - /// member of some named context. - bool isMember() const { return !ContextName.empty(); } - - /// Whether the result is translated into an instance member. - bool isInstanceMember() const { - return isMember() && static_cast(SelfIndex); - } - - /// Whether the result is translated into a static/class member. - bool isClassMember() const { - return isMember() && !static_cast(SelfIndex); - } - - /// Whether this is a property accessor. - bool isPropertyAccessor() const { return IsGetter || IsSetter; } - - /// Whether this is an operator. - bool isOperator() const { - return Lexer::isOperator(BaseName); - } - - /// Form a declaration name from this parsed declaration name. - DeclName formDeclName(ASTContext &ctx, bool isSubscript = false, - bool isCxxClassTemplateSpec = false) const; - - /// Form a declaration name from this parsed declaration name. - DeclNameRef formDeclNameRef(ASTContext &ctx, bool isSubscript = false, - bool isCxxClassTemplateSpec = false) const; -}; - /// To assist debugging parser crashes, tell us the location of the /// current token. class PrettyStackTraceParser : public llvm::PrettyStackTraceEntry { @@ -2188,28 +2127,6 @@ public: void print(llvm::raw_ostream &out) const override; }; -/// Parse a stringified Swift declaration name, -/// e.g. "Foo.translateBy(self:x:y:)". -ParsedDeclName parseDeclName(StringRef name) LLVM_READONLY; - -/// Form a Swift declaration name from its constituent parts. -DeclName formDeclName(ASTContext &ctx, - StringRef baseName, - ArrayRef argumentLabels, - bool isFunctionName, - bool isInitializer, - bool isSubscript = false, - bool isCxxClassTemplateSpec = false); - -/// Form a Swift declaration name reference from its constituent parts. -DeclNameRef formDeclNameRef(ASTContext &ctx, - StringRef baseName, - ArrayRef argumentLabels, - bool isFunctionName, - bool isInitializer, - bool isSubscript = false, - bool isCxxClassTemplateSpec = false); - /// Whether a given token can be the start of a decl. bool isKeywordPossibleDeclStart(const LangOptions &options, const Token &Tok); diff --git a/lib/APIDigester/ModuleAnalyzerNodes.cpp b/lib/APIDigester/ModuleAnalyzerNodes.cpp index 5ac602665d8..3afcb370694 100644 --- a/lib/APIDigester/ModuleAnalyzerNodes.cpp +++ b/lib/APIDigester/ModuleAnalyzerNodes.cpp @@ -1,10 +1,11 @@ -#include "llvm/ADT/STLExtras.h" #include "swift/AST/ASTMangler.h" #include "swift/Basic/Assertions.h" #include "swift/Basic/Defer.h" +#include "swift/Parse/Lexer.h" #include "swift/Sema/IDETypeChecking.h" -#include +#include "llvm/ADT/STLExtras.h" #include +#include using namespace swift; using namespace ide; diff --git a/lib/AST/AccessNotes.cpp b/lib/AST/AccessNotes.cpp index 3612af55a15..9852876ad74 100644 --- a/lib/AST/AccessNotes.cpp +++ b/lib/AST/AccessNotes.cpp @@ -16,12 +16,13 @@ //===----------------------------------------------------------------------===// #include "swift/AST/AccessNotes.h" +#include "swift/AST/ASTContext.h" #include "swift/AST/Attr.h" #include "swift/AST/Decl.h" -#include "swift/AST/Module.h" // DeclContext::isModuleScopeContext() #include "swift/AST/DiagnosticsFrontend.h" +#include "swift/AST/Module.h" // DeclContext::isModuleScopeContext() #include "swift/Basic/Assertions.h" -#include "swift/Parse/Parser.h" +#include "swift/Parse/ParseDeclName.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/YAMLTraits.h" diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 866e71b17a6..4dae2cf79ab 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -47,9 +47,7 @@ #include "swift/Basic/Version.h" #include "swift/ClangImporter/ClangImporterRequests.h" #include "swift/ClangImporter/ClangModule.h" -#include "swift/Parse/Lexer.h" #include "swift/Parse/ParseVersion.h" -#include "swift/Parse/Parser.h" #include "swift/Strings.h" #include "swift/Subsystems.h" #include "clang/AST/ASTContext.h" diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp index 004a12cfe29..3e06aac7f3c 100644 --- a/lib/ClangImporter/ImportName.cpp +++ b/lib/ClangImporter/ImportName.cpp @@ -31,7 +31,7 @@ #include "swift/Basic/STLExtras.h" #include "swift/Basic/StringExtras.h" #include "swift/ClangImporter/ClangImporterRequests.h" -#include "swift/Parse/Parser.h" +#include "swift/Parse/ParseDeclName.h" #include "swift/Strings.h" #include "swift/Subsystems.h" #include "clang/AST/ASTContext.h" diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 06367893cdb..e957be3d572 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -18,18 +18,16 @@ #include "ArgsToFrontendOptionsConverter.h" #include "swift/AST/DiagnosticsFrontend.h" #include "swift/Basic/Assertions.h" -#include "swift/Basic/Assertions.h" #include "swift/Basic/Feature.h" #include "swift/Basic/Platform.h" #include "swift/Option/Options.h" #include "swift/Option/SanitizerOptions.h" +#include "swift/Parse/Lexer.h" #include "swift/Parse/ParseVersion.h" #include "swift/SIL/SILBridging.h" #include "swift/Strings.h" #include "swift/SymbolGraphGen/SymbolGraphOptions.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Support/VersionTuple.h" -#include "llvm/TargetParser/Triple.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" @@ -37,7 +35,9 @@ #include "llvm/Support/LineIterator.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" +#include "llvm/Support/VersionTuple.h" #include "llvm/Support/WithColor.h" +#include "llvm/TargetParser/Triple.h" using namespace swift; using namespace llvm::opt; diff --git a/lib/IDE/Formatting.cpp b/lib/IDE/Formatting.cpp index 3039c4683d2..c4d2c1348ac 100644 --- a/lib/IDE/Formatting.cpp +++ b/lib/IDE/Formatting.cpp @@ -14,11 +14,11 @@ #include "swift/AST/GenericParamList.h" #include "swift/AST/TypeRepr.h" #include "swift/Basic/Assertions.h" -#include "swift/IDE/SourceEntityWalker.h" -#include "swift/Parse/Parser.h" -#include "swift/Frontend/Frontend.h" #include "swift/Basic/SourceManager.h" +#include "swift/Frontend/Frontend.h" #include "swift/IDE/Indenting.h" +#include "swift/IDE/SourceEntityWalker.h" +#include "swift/Parse/Lexer.h" #include "swift/Subsystems.h" using namespace swift; diff --git a/lib/IDE/IDERequests.cpp b/lib/IDE/IDERequests.cpp index fe8a6f2f388..16467f5c48f 100644 --- a/lib/IDE/IDERequests.cpp +++ b/lib/IDE/IDERequests.cpp @@ -10,21 +10,22 @@ // //===----------------------------------------------------------------------===// +#include "swift/IDE/IDERequests.h" +#include "swift/AST/ASTDemangler.h" #include "swift/AST/ASTPrinter.h" #include "swift/AST/Decl.h" #include "swift/AST/Effects.h" #include "swift/AST/NameLookup.h" -#include "swift/AST/ASTDemangler.h" #include "swift/Basic/Assertions.h" #include "swift/Basic/SourceManager.h" #include "swift/Frontend/Frontend.h" #include "swift/Frontend/PrintingDiagnosticConsumer.h" #include "swift/IDE/CommentConversion.h" #include "swift/IDE/Utils.h" -#include "swift/Sema/IDETypeChecking.h" #include "swift/Markup/XMLUtils.h" +#include "swift/Parse/Lexer.h" +#include "swift/Sema/IDETypeChecking.h" #include "swift/Subsystems.h" -#include "swift/IDE/IDERequests.h" using namespace swift; using namespace swift::ide; diff --git a/lib/IDE/REPLCodeCompletion.cpp b/lib/IDE/REPLCodeCompletion.cpp index bad657b6f9f..2fd9b3055b2 100644 --- a/lib/IDE/REPLCodeCompletion.cpp +++ b/lib/IDE/REPLCodeCompletion.cpp @@ -21,11 +21,10 @@ #include "swift/AST/SourceFile.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/SourceManager.h" -#include "swift/Parse/Parser.h" #include "swift/Subsystems.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" #include using namespace swift; diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp index 98ed31e5ec9..544268eaeb7 100644 --- a/lib/Migrator/APIDiffMigratorPass.cpp +++ b/lib/Migrator/APIDiffMigratorPass.cpp @@ -10,26 +10,27 @@ // //===----------------------------------------------------------------------===// -#include "swift/AST/USRGeneration.h" #include "swift/AST/ASTVisitor.h" +#include "swift/AST/USRGeneration.h" #include "swift/Basic/Assertions.h" +#include "swift/Basic/Defer.h" #include "swift/Basic/StringExtras.h" #include "swift/Frontend/Frontend.h" +#include "swift/IDE/APIDigesterData.h" #include "swift/IDE/Utils.h" -#include "swift/Sema/IDETypeChecking.h" #include "swift/Migrator/ASTMigratorPass.h" #include "swift/Migrator/EditorAdapter.h" #include "swift/Migrator/FixitApplyDiagnosticConsumer.h" #include "swift/Migrator/Migrator.h" #include "swift/Migrator/RewriteBufferEditsReceiver.h" +#include "swift/Parse/Lexer.h" +#include "swift/Sema/IDETypeChecking.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Edit/EditedSource.h" #include "clang/Rewrite/Core/RewriteBuffer.h" #include "llvm/Support/FileSystem.h" -#include "swift/IDE/APIDigesterData.h" -#include "swift/Basic/Defer.h" using namespace swift; using namespace swift::migrator; diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt index a919148e118..339dea880a4 100644 --- a/lib/Parse/CMakeLists.txt +++ b/lib/Parse/CMakeLists.txt @@ -11,6 +11,7 @@ add_swift_host_library(swiftParse STATIC Lexer.cpp ParseBridging.cpp ParseDecl.cpp + ParseDeclName.cpp ParseExpr.cpp ParseGeneric.cpp ParseIfConfig.cpp diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index e3776638c02..e9f383ca6f5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -34,6 +34,7 @@ #include "swift/Basic/StringExtras.h" #include "swift/Bridging/ASTGen.h" #include "swift/Parse/IDEInspectionCallbacks.h" +#include "swift/Parse/ParseDeclName.h" #include "swift/Parse/ParseSILSupport.h" #include "swift/Parse/Parser.h" #include "swift/Strings.h" diff --git a/lib/Parse/ParseDeclName.cpp b/lib/Parse/ParseDeclName.cpp new file mode 100644 index 00000000000..56850b443ef --- /dev/null +++ b/lib/Parse/ParseDeclName.cpp @@ -0,0 +1,197 @@ +//===--- ParseDeclName.cpp ------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2024 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 +// +//===----------------------------------------------------------------------===// + +#include "swift/Parse/ParseDeclName.h" +#include "swift/AST/ASTContext.h" + +using namespace swift; + +ParsedDeclName swift::parseDeclName(StringRef name) { + if (name.empty()) + return ParsedDeclName(); + + // Local function to handle the parsing of the base name + context. + // + // Returns true if an error occurred, without recording the base name. + ParsedDeclName result; + auto parseBaseName = [&](StringRef text) -> bool { + // Split the text into context name and base name. + StringRef contextName, baseName; + std::tie(contextName, baseName) = text.rsplit('.'); + if (baseName.empty()) { + baseName = contextName; + contextName = StringRef(); + } else if (contextName.empty()) { + return true; + } + + auto isValidIdentifier = [](StringRef text) -> bool { + return Lexer::isIdentifier(text) && text != "_"; + }; + + // Make sure we have an identifier for the base name. + if (!isValidIdentifier(baseName)) + return true; + + // If we have a context, make sure it is an identifier, or a series of + // dot-separated identifiers. + // FIXME: What about generic parameters? + if (!contextName.empty()) { + StringRef first; + StringRef rest = contextName; + do { + std::tie(first, rest) = rest.split('.'); + if (!isValidIdentifier(first)) + return true; + } while (!rest.empty()); + } + + // Record the results. + result.ContextName = contextName; + result.BaseName = baseName; + return false; + }; + + // If this is not a function name, just parse the base name and + // we're done. + if (name.back() != ')') { + if (Lexer::isOperator(name)) + result.BaseName = name; + else if (parseBaseName(name)) + return ParsedDeclName(); + return result; + } + + // We have a function name. + result.IsFunctionName = true; + + // Split the base name from the parameters. + StringRef baseName, parameters; + std::tie(baseName, parameters) = name.split('('); + if (parameters.empty()) + return ParsedDeclName(); + + // If the base name is prefixed by "getter:" or "setter:", it's an + // accessor. + if (baseName.starts_with("getter:")) { + result.IsGetter = true; + result.IsFunctionName = false; + baseName = baseName.substr(7); + } else if (baseName.starts_with("setter:")) { + result.IsSetter = true; + result.IsFunctionName = false; + baseName = baseName.substr(7); + } + + // If the base name is prefixed by "subscript", it's an subscript. + if (baseName == "subscript") { + result.IsSubscript = true; + } + + // Parse the base name. + if (parseBaseName(baseName)) + return ParsedDeclName(); + + parameters = parameters.drop_back(); // ')' + if (parameters.empty()) + return result; + + if (parameters.back() != ':') + return ParsedDeclName(); + + bool isMember = !result.ContextName.empty(); + do { + StringRef NextParam; + std::tie(NextParam, parameters) = parameters.split(':'); + + if (!Lexer::isIdentifier(NextParam)) + return ParsedDeclName(); + if (NextParam == "_") { + result.ArgumentLabels.push_back(""); + } else if (isMember && NextParam == "self") { + // For a member, "self" indicates the self parameter. There can + // only be one such parameter. + if (result.SelfIndex) + return ParsedDeclName(); + result.SelfIndex = result.ArgumentLabels.size(); + } else { + result.ArgumentLabels.push_back(NextParam); + } + } while (!parameters.empty()); + + return result; +} + +DeclName ParsedDeclName::formDeclName(ASTContext &ctx, bool isSubscript, + bool isCxxClassTemplateSpec) const { + return formDeclNameRef(ctx, isSubscript, isCxxClassTemplateSpec) + .getFullName(); +} + +DeclNameRef ParsedDeclName::formDeclNameRef(ASTContext &ctx, bool isSubscript, + bool isCxxClassTemplateSpec) const { + return swift::formDeclNameRef(ctx, BaseName, ArgumentLabels, IsFunctionName, + /*IsInitializer=*/true, isSubscript, + isCxxClassTemplateSpec); +} + +DeclName swift::formDeclName(ASTContext &ctx, StringRef baseName, + ArrayRef argumentLabels, + bool isFunctionName, bool isInitializer, + bool isSubscript, bool isCxxClassTemplateSpec) { + return formDeclNameRef(ctx, baseName, argumentLabels, isFunctionName, + isInitializer, isSubscript, isCxxClassTemplateSpec) + .getFullName(); +} + +DeclNameRef swift::formDeclNameRef(ASTContext &ctx, StringRef baseName, + ArrayRef argumentLabels, + bool isFunctionName, bool isInitializer, + bool isSubscript, + bool isCxxClassTemplateSpec) { + // We cannot import when the base name is not an identifier. + if (baseName.empty()) + return DeclNameRef(); + + if (!Lexer::isIdentifier(baseName) && !Lexer::isOperator(baseName) && + !isCxxClassTemplateSpec) + return DeclNameRef(); + + // Get the identifier for the base name. Special-case `init`. + DeclBaseName baseNameId; + if (isInitializer && baseName == "init") + baseNameId = DeclBaseName::createConstructor(); + else if (isSubscript && baseName == "subscript") + baseNameId = DeclBaseName::createSubscript(); + else + baseNameId = ctx.getIdentifier(baseName); + + // For non-functions, just use the base name. + if (!isFunctionName && !baseNameId.isSubscript()) + return DeclNameRef(baseNameId); + + // For functions, we need to form a complete name. + + // Convert the argument names. + SmallVector argumentLabelIds; + for (auto argName : argumentLabels) { + if (argumentLabels.empty() || !Lexer::isIdentifier(argName)) { + argumentLabelIds.push_back(Identifier()); + continue; + } + + argumentLabelIds.push_back(ctx.getIdentifier(argName)); + } + + // Build the result. + return DeclNameRef({ctx, baseNameId, argumentLabelIds}); +} diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 07619f85f6f..6e75ef6875d 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2024 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 @@ -15,7 +15,6 @@ //===----------------------------------------------------------------------===// #include "swift/Parse/Parser.h" -#include "swift/Subsystems.h" #include "swift/AST/ASTWalker.h" #include "swift/AST/DiagnosticsParse.h" #include "swift/AST/Module.h" @@ -26,16 +25,18 @@ #include "swift/Basic/Assertions.h" #include "swift/Basic/Defer.h" #include "swift/Basic/SourceManager.h" -#include "swift/Parse/Lexer.h" #include "swift/Parse/IDEInspectionCallbacks.h" +#include "swift/Parse/Lexer.h" +#include "swift/Parse/ParseDeclName.h" #include "swift/Parse/ParseSILSupport.h" +#include "swift/Subsystems.h" #include "swift/SymbolGraphGen/SymbolGraphOptions.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/SaveAndRestore.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SaveAndRestore.h" +#include "llvm/Support/raw_ostream.h" static void getStringPartTokens(const swift::Token &Tok, const swift::LangOptions &LangOpts, @@ -1217,187 +1218,6 @@ SourceFile &ParserUnit::getSourceFile() { return *Impl.SF; } -ParsedDeclName swift::parseDeclName(StringRef name) { - if (name.empty()) return ParsedDeclName(); - - // Local function to handle the parsing of the base name + context. - // - // Returns true if an error occurred, without recording the base name. - ParsedDeclName result; - auto parseBaseName = [&](StringRef text) -> bool { - // Split the text into context name and base name. - StringRef contextName, baseName; - std::tie(contextName, baseName) = text.rsplit('.'); - if (baseName.empty()) { - baseName = contextName; - contextName = StringRef(); - } else if (contextName.empty()) { - return true; - } - - auto isValidIdentifier = [](StringRef text) -> bool { - return Lexer::isIdentifier(text) && text != "_"; - }; - - // Make sure we have an identifier for the base name. - if (!isValidIdentifier(baseName)) - return true; - - // If we have a context, make sure it is an identifier, or a series of - // dot-separated identifiers. - // FIXME: What about generic parameters? - if (!contextName.empty()) { - StringRef first; - StringRef rest = contextName; - do { - std::tie(first, rest) = rest.split('.'); - if (!isValidIdentifier(first)) - return true; - } while (!rest.empty()); - } - - // Record the results. - result.ContextName = contextName; - result.BaseName = baseName; - return false; - }; - - // If this is not a function name, just parse the base name and - // we're done. - if (name.back() != ')') { - if (Lexer::isOperator(name)) - result.BaseName = name; - else if (parseBaseName(name)) - return ParsedDeclName(); - return result; - } - - // We have a function name. - result.IsFunctionName = true; - - // Split the base name from the parameters. - StringRef baseName, parameters; - std::tie(baseName, parameters) = name.split('('); - if (parameters.empty()) return ParsedDeclName(); - - // If the base name is prefixed by "getter:" or "setter:", it's an - // accessor. - if (baseName.starts_with("getter:")) { - result.IsGetter = true; - result.IsFunctionName = false; - baseName = baseName.substr(7); - } else if (baseName.starts_with("setter:")) { - result.IsSetter = true; - result.IsFunctionName = false; - baseName = baseName.substr(7); - } - - // If the base name is prefixed by "subscript", it's an subscript. - if (baseName == "subscript") { - result.IsSubscript = true; - } - - // Parse the base name. - if (parseBaseName(baseName)) return ParsedDeclName(); - - parameters = parameters.drop_back(); // ')' - if (parameters.empty()) return result; - - if (parameters.back() != ':') - return ParsedDeclName(); - - bool isMember = !result.ContextName.empty(); - do { - StringRef NextParam; - std::tie(NextParam, parameters) = parameters.split(':'); - - if (!Lexer::isIdentifier(NextParam)) - return ParsedDeclName(); - if (NextParam == "_") { - result.ArgumentLabels.push_back(""); - } else if (isMember && NextParam == "self") { - // For a member, "self" indicates the self parameter. There can - // only be one such parameter. - if (result.SelfIndex) return ParsedDeclName(); - result.SelfIndex = result.ArgumentLabels.size(); - } else { - result.ArgumentLabels.push_back(NextParam); - } - } while (!parameters.empty()); - - return result; -} - -DeclName ParsedDeclName::formDeclName(ASTContext &ctx, bool isSubscript, - bool isCxxClassTemplateSpec) const { - return formDeclNameRef(ctx, isSubscript, isCxxClassTemplateSpec).getFullName(); -} - -DeclNameRef ParsedDeclName::formDeclNameRef(ASTContext &ctx, - bool isSubscript, - bool isCxxClassTemplateSpec) const { - return swift::formDeclNameRef(ctx, BaseName, ArgumentLabels, IsFunctionName, - /*IsInitializer=*/true, isSubscript, - isCxxClassTemplateSpec); -} - -DeclName swift::formDeclName(ASTContext &ctx, - StringRef baseName, - ArrayRef argumentLabels, - bool isFunctionName, - bool isInitializer, - bool isSubscript, - bool isCxxClassTemplateSpec) { - return formDeclNameRef(ctx, baseName, argumentLabels, isFunctionName, - isInitializer, isSubscript, - isCxxClassTemplateSpec).getFullName(); -} - -DeclNameRef swift::formDeclNameRef(ASTContext &ctx, - StringRef baseName, - ArrayRef argumentLabels, - bool isFunctionName, - bool isInitializer, - bool isSubscript, - bool isCxxClassTemplateSpec) { - // We cannot import when the base name is not an identifier. - if (baseName.empty()) - return DeclNameRef(); - - if (!Lexer::isIdentifier(baseName) && !Lexer::isOperator(baseName) && - !isCxxClassTemplateSpec) - return DeclNameRef(); - - // Get the identifier for the base name. Special-case `init`. - DeclBaseName baseNameId; - if (isInitializer && baseName == "init") - baseNameId = DeclBaseName::createConstructor(); - else if (isSubscript && baseName == "subscript") - baseNameId = DeclBaseName::createSubscript(); - else - baseNameId = ctx.getIdentifier(baseName); - - // For non-functions, just use the base name. - if (!isFunctionName && !baseNameId.isSubscript()) - return DeclNameRef(baseNameId); - - // For functions, we need to form a complete name. - - // Convert the argument names. - SmallVector argumentLabelIds; - for (auto argName : argumentLabels) { - if (argumentLabels.empty() || !Lexer::isIdentifier(argName)) { - argumentLabelIds.push_back(Identifier()); - continue; - } - - argumentLabelIds.push_back(ctx.getIdentifier(argName)); - } - - // Build the result. - return DeclNameRef({ ctx, baseNameId, argumentLabelIds }); -} - void PrettyStackTraceParser::print(llvm::raw_ostream &out) const { out << "With parser at source location: "; P.Tok.getLoc().print(out, P.Context.SourceMgr); diff --git a/lib/PrintAsClang/DeclAndTypePrinter.cpp b/lib/PrintAsClang/DeclAndTypePrinter.cpp index d4fb9199b55..ce4e871b952 100644 --- a/lib/PrintAsClang/DeclAndTypePrinter.cpp +++ b/lib/PrintAsClang/DeclAndTypePrinter.cpp @@ -40,7 +40,6 @@ #include "swift/IRGen/IRABIDetailsProvider.h" #include "swift/IRGen/Linking.h" #include "swift/Parse/Lexer.h" -#include "swift/Parse/Parser.h" #include "SwiftToClangInteropContext.h" #include "clang/AST/ASTContext.h" diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index 5f74c870ebe..0fface3ee0c 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -30,7 +30,6 @@ #include "swift/Demangling/Demangle.h" #include "swift/Parse/Lexer.h" #include "swift/Parse/ParseSILSupport.h" -#include "swift/Parse/Parser.h" #include "swift/SIL/AbstractionPattern.h" #include "swift/SIL/InstructionUtils.h" #include "swift/SIL/OwnershipUtils.h" diff --git a/lib/Sema/ImportResolution.cpp b/lib/Sema/ImportResolution.cpp index 80c7f453bea..73bd961274b 100644 --- a/lib/Sema/ImportResolution.cpp +++ b/lib/Sema/ImportResolution.cpp @@ -28,7 +28,6 @@ #include "swift/Basic/Defer.h" #include "swift/Basic/Statistic.h" #include "swift/ClangImporter/ClangModule.h" -#include "swift/Parse/Parser.h" #include "swift/Subsystems.h" #include "swift/SymbolGraphGen/DocumentationCategory.h" #include "clang/Basic/Module.h" @@ -36,9 +35,9 @@ #include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" -#include "llvm/TargetParser/Host.h" #include "llvm/Support/Path.h" #include "llvm/Support/SaveAndRestore.h" +#include "llvm/TargetParser/Host.h" #include #include using namespace swift; diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index d7d42b895fd..7c52a8d9403 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -39,7 +39,6 @@ #include "swift/Basic/Statistic.h" #include "swift/Basic/StringExtras.h" #include "swift/Parse/Lexer.h" -#include "swift/Parse/Parser.h" #include "swift/Sema/ConstraintSystem.h" #include "swift/Sema/IDETypeChecking.h" #include "clang/AST/DeclObjC.h" diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 9eb7ab76c11..37ca9bd36f1 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -44,7 +44,7 @@ #include "swift/AST/Types.h" #include "swift/Basic/Assertions.h" #include "swift/Parse/Lexer.h" -#include "swift/Parse/Parser.h" +#include "swift/Parse/ParseDeclName.h" #include "swift/Sema/IDETypeChecking.h" #include "clang/Basic/CharInfo.h" #include "llvm/ADT/MapVector.h" diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index c3bd36a9d20..793997831d4 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -22,6 +22,7 @@ #include "TypeChecker.h" #include "swift/AST/ASTWalker.h" #include "swift/AST/ClangModuleLoader.h" +#include "swift/AST/DiagnosticsParse.h" #include "swift/AST/GenericEnvironment.h" #include "swift/AST/Initializer.h" #include "swift/AST/NameLookup.h" @@ -37,7 +38,7 @@ #include "swift/Basic/SourceManager.h" #include "swift/Basic/StringExtras.h" #include "swift/Parse/Lexer.h" -#include "swift/Parse/Parser.h" +#include "swift/Parse/ParseDeclName.h" #include "swift/Sema/IDETypeChecking.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringSwitch.h" diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 9b01ab08000..c208b626f02 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -34,6 +34,7 @@ #include "swift/AST/Attr.h" #include "swift/AST/ClangModuleLoader.h" #include "swift/AST/ConformanceLookup.h" +#include "swift/AST/DiagnosticsParse.h" #include "swift/AST/ExistentialLayout.h" #include "swift/AST/Expr.h" #include "swift/AST/ForeignErrorConvention.h" @@ -51,8 +52,6 @@ #include "swift/Basic/Assertions.h" #include "swift/Basic/Defer.h" #include "swift/Bridging/ASTGen.h" -#include "swift/Parse/Lexer.h" -#include "swift/Parse/Parser.h" #include "swift/Sema/IDETypeChecking.h" #include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Strings.h" diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index cb0687cf896..d6a692e8874 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -36,6 +36,7 @@ #include "swift/AST/ConformanceLookup.h" #include "swift/AST/Decl.h" #include "swift/AST/DeclContext.h" +#include "swift/AST/DiagnosticsParse.h" #include "swift/AST/DiagnosticsSema.h" #include "swift/AST/ExistentialLayout.h" #include "swift/AST/Expr.h" @@ -58,7 +59,6 @@ #include "swift/Basic/Statistic.h" #include "swift/Bridging/MacroEvaluation.h" #include "swift/Parse/Lexer.h" -#include "swift/Parse/Parser.h" #include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Strings.h" #include "clang/Basic/Module.h" diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp index 77ce97ce969..b104b42fe38 100644 --- a/lib/Sema/TypeCheckStmt.cpp +++ b/lib/Sema/TypeCheckStmt.cpp @@ -41,7 +41,6 @@ #include "swift/Basic/Statistic.h" #include "swift/Basic/TopCollection.h" #include "swift/Parse/Lexer.h" -#include "swift/Parse/Parser.h" #include "swift/Sema/ConstraintSystem.h" #include "swift/Sema/IDETypeChecking.h" #include "swift/Subsystems.h"