diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 3f8fee3e1314e..902697efea232 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -22,7 +22,6 @@ add_swift_tool_subdirectory(swift-demangle) add_swift_tool_subdirectory(swift-demangle-yamldump) add_swift_tool_subdirectory(swift-def-to-strings-converter) add_swift_tool_subdirectory(swift-serialize-diagnostics) -add_swift_tool_subdirectory(swift-ast-script) add_swift_tool_subdirectory(swift-refactor) add_swift_tool_subdirectory(libStaticMirror) add_swift_tool_subdirectory(libMockPlugin) diff --git a/tools/swift-ast-script/ASTScript.h b/tools/swift-ast-script/ASTScript.h deleted file mode 100644 index 5c0a10c0a7ce9..0000000000000 --- a/tools/swift-ast-script/ASTScript.h +++ /dev/null @@ -1,40 +0,0 @@ -//===--- ASTScript.h - AST script type --------------------------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 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 -// -//===----------------------------------------------------------------------===// -// -// The AST for a swift-ast-script script. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SCRIPTING_ASTSCRIPT_H -#define SWIFT_SCRIPTING_ASTSCRIPT_H - -#include "swift/Basic/LLVM.h" - -namespace swift { -namespace scripting { -class ASTScriptConfiguration; - -class ASTScript { - ASTScriptConfiguration &Config; - -public: - ASTScript(ASTScriptConfiguration &config) : Config(config) {} - - static std::unique_ptr parse(ASTScriptConfiguration &config); - - bool execute() const; -}; - -} -} - -#endif diff --git a/tools/swift-ast-script/ASTScriptConfiguration.cpp b/tools/swift-ast-script/ASTScriptConfiguration.cpp deleted file mode 100644 index 033798696ce83..0000000000000 --- a/tools/swift-ast-script/ASTScriptConfiguration.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//===--- ASTScriptConfiguration.cpp ---------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 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 -// -//===----------------------------------------------------------------------===// -/// -/// Configuration parsing for an AST script. -/// -//===----------------------------------------------------------------------===// - -#include "ASTScriptConfiguration.h" - -#include "swift/Basic/QuotedString.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/raw_ostream.h" - -using namespace swift; -using namespace scripting; - -std::unique_ptr -ASTScriptConfiguration::parse(CompilerInstance &compiler, - ArrayRef args) { - bool hadError = false; - - std::unique_ptr result( - new ASTScriptConfiguration(compiler)); - -#define emitError(WHAT) do { \ - llvm::errs() << "error: " << WHAT << "\n"; \ - hadError = true; \ - } while (0) - - auto popArg = [&](const char *what) -> StringRef { - // Gracefully handle the case of running out of arguments. - if (args.empty()) { - assert(what && "expected explanation here!"); - emitError(what); - return ""; - } - - auto arg = args.front(); - args = args.slice(1); - return arg; - }; - - auto setScriptFile = [&](StringRef filename) { - if (!result->ScriptFile.empty()) { - emitError("multiple script files (" - << QuotedString(result->ScriptFile) - << ", " - << QuotedString(filename) - << ")"); - } - result->ScriptFile = filename; - }; - - // Parse the arguments. - while (!hadError && !args.empty()) { - StringRef arg = popArg(nullptr); - if (!arg.starts_with("-")) { - setScriptFile(arg); - } else if (arg == "-f") { - StringRef filename = popArg("expected path after -f"); - if (!hadError) - setScriptFile(filename); - } else if (arg == "-h" || arg == "--help") { - llvm::errs() - << "usage: swift-ast-script -- \n" - " -f \n" - " Specify the file to use as the script; required argument\n"; - hadError = true; - } else { - emitError("unknown argument " << QuotedString(arg)); - } - } - - // Check well-formedness. - if (!hadError) { - if (result->ScriptFile.empty()) { - emitError("script file is required"); - } - } - - if (hadError) - result.reset(); - return result; -} diff --git a/tools/swift-ast-script/ASTScriptConfiguration.h b/tools/swift-ast-script/ASTScriptConfiguration.h deleted file mode 100644 index 660f47906add4..0000000000000 --- a/tools/swift-ast-script/ASTScriptConfiguration.h +++ /dev/null @@ -1,45 +0,0 @@ -//===--- ASTScriptConfiguration.h - AST script configuration ----*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 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 -// -//===----------------------------------------------------------------------===// -// -// Types for configuring an AST script invocation. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SCRIPTING_ASTSCRIPTCONFIGURATION_H -#define SWIFT_SCRIPTING_ASTSCRIPTCONFIGURATION_H - -#include "swift/Basic/LLVM.h" -#include "llvm/ADT/StringRef.h" - -namespace swift { -class CompilerInstance; - -namespace scripting { - -/// A configuration for working with an ASTScript. -class ASTScriptConfiguration { - ASTScriptConfiguration(CompilerInstance &compiler) : Compiler(compiler) {} -public: - CompilerInstance &Compiler; - StringRef ScriptFile; - - /// Attempt to parse this configuration. - /// - /// Returns null if there's a problem. - static std::unique_ptr - parse(CompilerInstance &compiler, ArrayRef args); -}; - -} -} - -#endif diff --git a/tools/swift-ast-script/ASTScriptEvaluator.cpp b/tools/swift-ast-script/ASTScriptEvaluator.cpp deleted file mode 100644 index 5229259d3e68c..0000000000000 --- a/tools/swift-ast-script/ASTScriptEvaluator.cpp +++ /dev/null @@ -1,148 +0,0 @@ -//===--- ASTScriptEvaluator.cpp -------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 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 -// -//===----------------------------------------------------------------------===// -/// -/// AST script evaluation. -/// -//===----------------------------------------------------------------------===// - -#include "ASTScript.h" -#include "ASTScriptConfiguration.h" - -#include "swift/AST/ASTMangler.h" -#include "swift/AST/ASTWalker.h" -#include "swift/AST/Decl.h" -#include "swift/AST/NameLookup.h" -#include "swift/AST/NameLookupRequests.h" -#include "swift/Frontend/Frontend.h" - -using namespace swift; -using namespace scripting; - -namespace { - -class ASTScriptWalker : public ASTWalker { - const ASTScript &Script; - ProtocolDecl *ViewProtocol; - -public: - ASTScriptWalker(const ASTScript &script, ProtocolDecl *viewProtocol) - : Script(script), ViewProtocol(viewProtocol) {} - - MacroWalking getMacroWalkingBehavior() const override { - return MacroWalking::Expansion; - } - - PreWalkAction walkToDeclPre(Decl *D) override { - visit(D); - return Action::Continue(); - } - - void visit(const Decl *D) { - auto fn = dyn_cast(D); - if (!fn) return; - - // Suppress warnings. - (void) Script; - - for (auto param : *fn->getParameters()) { - // The parameter must have function type. - auto paramType = param->getInterfaceType(); - auto paramFnType = paramType->getAs(); - if (!paramFnType) continue; - - // The parameter function must return a type parameter that - // conforms to SwiftUI.View. - auto paramResultType = paramFnType->getResult(); - if (!paramResultType->isTypeParameter()) continue; - auto sig = fn->getGenericSignature(); - if (!sig->requiresProtocol(paramResultType, ViewProtocol)) continue; - - // The parameter must not be a @ViewBuilder parameter. - if (param->getResultBuilderType()) continue; - - // Print the function. - printDecl(fn); - } - } - - void printDecl(const ValueDecl *decl) { - // FIXME: there's got to be some better way to print an exact reference - // to a declaration, including its context. - printDecl(llvm::outs(), decl); - llvm::outs() << "\n"; - } - - void printDecl(llvm::raw_ostream &out, const ValueDecl *decl) { - if (auto accessor = dyn_cast(decl)) { - printDecl(out, accessor->getStorage()); - out << ".(accessor)"; - } else { - printDeclContext(out, decl->getDeclContext()); - out << decl->getName(); - } - } - - void printDeclContext(llvm::raw_ostream &out, const DeclContext *dc) { - if (!dc) return; - if (auto module = dyn_cast(dc)) { - out << module->getName() << "."; - } else if (auto extension = dyn_cast(dc)) { - auto *extended = extension->getExtendedNominal(); - if (extended) { - printDecl(out, extended); - out << "."; - } - } else if (auto decl = dyn_cast_or_null(dc->getAsDecl())) { - printDecl(out, decl); - out << "."; - } else { - printDeclContext(out, dc->getParent()); - } - } -}; - -} - -bool ASTScript::execute() const { - // Hardcode the actual query we want to execute here. - - auto &ctx = Config.Compiler.getASTContext(); - auto swiftUI = ctx.getLoadedModule(ctx.getIdentifier("SwiftUI")); - if (!swiftUI) { - llvm::errs() << "error: SwiftUI module not loaded\n"; - return true; - } - - auto descriptor = - UnqualifiedLookupDescriptor(DeclNameRef(ctx.getIdentifier("View")), - swiftUI); - auto viewLookup = evaluateOrDefault(ctx.evaluator, - UnqualifiedLookupRequest{descriptor}, {}); - auto viewProtocol = - dyn_cast_or_null(viewLookup.getSingleTypeResult()); - if (!viewProtocol) { - llvm::errs() << "error: couldn't find SwiftUI.View protocol\n"; - return true; - } - - SmallVector topLevelDecls; - swiftUI->getTopLevelDecls(topLevelDecls); - - llvm::errs() << "found " << topLevelDecls.size() << " top-level declarations\n"; - - ASTScriptWalker walker(*this, viewProtocol); - for (auto decl : topLevelDecls) { - decl->walk(walker); - } - - return false; -} diff --git a/tools/swift-ast-script/ASTScriptParser.cpp b/tools/swift-ast-script/ASTScriptParser.cpp deleted file mode 100644 index 83092c9db3e34..0000000000000 --- a/tools/swift-ast-script/ASTScriptParser.cpp +++ /dev/null @@ -1,119 +0,0 @@ -//===--- ASTScriptParser.cpp ----------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 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 -// -//===----------------------------------------------------------------------===// -/// -/// AST script parsing. -/// -//===----------------------------------------------------------------------===// - -#include "swift/Basic/QuotedString.h" -#include "swift/Frontend/Frontend.h" -#include "swift/Parse/Lexer.h" -#include "swift/Parse/Token.h" -#include "llvm/Support/MemoryBuffer.h" - -#include "ASTScript.h" -#include "ASTScriptConfiguration.h" - -using namespace swift; -using namespace scripting; - -namespace { - -class ASTScriptParser { - ASTScriptConfiguration &Config; - ASTContext &Context; - DiagnosticEngine &Diags; - std::unique_ptr Buffer; - std::optional TheLexer; - Token Tok; - -public: - ASTScriptParser(ASTScriptConfiguration &config) - : Config(config), Context(config.Compiler.getASTContext()), - Diags(config.Compiler.getDiags()) { - - auto &compiler = config.Compiler; - - // Open the file and give it to the source manager. - auto bufferOrErr = llvm::MemoryBuffer::getFile(config.ScriptFile); - if (!bufferOrErr) { - llvm::errs() << "error opening file " << QuotedString(config.ScriptFile) - << ": " << bufferOrErr.getError().message() << "\n"; - return; - } - auto &sourceManager = compiler.getSourceMgr(); - auto bufferID = sourceManager.addNewSourceBuffer(std::move(*bufferOrErr)); - - // Build and prime the lexer. - TheLexer.emplace(Context.LangOpts, sourceManager, bufferID, - &Diags, LexerMode::Swift); - TheLexer->lex(Tok); - } - - std::unique_ptr parseFile() { - if (!TheLexer) return nullptr; - return parseTopLevel(); - } - -private: - /***************************************************************************/ - /*** Parsing primitives ****************************************************/ - /***************************************************************************/ - - void consume(tok kind) { - assert(Tok.is(kind)); - TheLexer->lex(Tok); - } - - bool consumeIf(tok kind) { - if (Tok.isNot(kind)) return false; - consume(kind); - return true; - } - - bool consumeIfExactly(StringRef literal) { - if (Tok.isNot(tok::identifier) || Tok.getText() != literal) - return false; - consume(tok::identifier); - return true; - } - - bool consumeIfIdentifier(StringRef &ident) { - if (Tok.isNot(tok::identifier)) return false; - ident = Tok.getText(); - consume(tok::identifier); - return true; - } - - std::optional consumeIfIdentifier() { - StringRef ident; - return consumeIfIdentifier(ident) ? std::optional(ident) - : std::nullopt; - } - - /***************************************************************************/ - /*** ASTScript parsing *****************************************************/ - /***************************************************************************/ - - std::unique_ptr parseTopLevel(); -}; - -} // end anonymous namespace - -/// ast-script ::= ??? -std::unique_ptr ASTScriptParser::parseTopLevel() { - return std::unique_ptr(new ASTScript(Config)); -} - -std::unique_ptr ASTScript::parse(ASTScriptConfiguration &config) { - return ASTScriptParser(config).parseFile(); -} diff --git a/tools/swift-ast-script/CMakeLists.txt b/tools/swift-ast-script/CMakeLists.txt deleted file mode 100644 index 0b68c96baaf3e..0000000000000 --- a/tools/swift-ast-script/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -add_swift_host_tool(swift-ast-script - ASTScriptConfiguration.cpp - ASTScriptParser.cpp - ASTScriptEvaluator.cpp - swift-ast-script.cpp - SWIFT_COMPONENT tools - THINLTO_LD64_ADD_FLTO_CODEGEN_ONLY -) -target_link_libraries(swift-ast-script - PRIVATE - swiftAST - swiftFrontendTool) diff --git a/tools/swift-ast-script/swift-ast-script.cpp b/tools/swift-ast-script/swift-ast-script.cpp deleted file mode 100644 index 2fd133bffd6c6..0000000000000 --- a/tools/swift-ast-script/swift-ast-script.cpp +++ /dev/null @@ -1,98 +0,0 @@ -//===--- swift-ast-script.cpp ---------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 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 -// -//===----------------------------------------------------------------------===// -/// -/// This utility is a command line tool that searches Swift code for -/// declarations matching the given requirements. -/// -//===----------------------------------------------------------------------===// - -#include "swift/Frontend/Frontend.h" -#include "swift/FrontendTool/FrontendTool.h" -#include "swift/Basic/LLVMInitialize.h" -#include "ASTScript.h" -#include "ASTScriptConfiguration.h" - -using namespace swift; -using namespace scripting; - -namespace { - -class Observer : public FrontendObserver { - ArrayRef Args; - std::unique_ptr Config; - std::unique_ptr Script; - bool HadError = false; - -public: - Observer(ArrayRef args) : Args(args) {} - - void configuredCompiler(CompilerInstance &instance) override { - Config = ASTScriptConfiguration::parse(instance, Args); - if (!Config) return flagError(); - - Script = ASTScript::parse(*Config); - if (!Script) return flagError(); - } - - void performedSemanticAnalysis(CompilerInstance &instance) override { - if (Script) { - if (Script->execute()) - return flagError(); - } - } - - bool hadError() const { - return HadError; - } - -private: - void flagError() { - HadError = true; - } -}; - -} - -// ISO C++ does not allow 'main' to be used by a program [-Wmain] -int main2(int argc, const char *argv[]) { - PROGRAM_START(argc, argv); - - // Look for the first "--" in the arguments. - auto argBegin = argv + 1; - auto argEnd = argv + argc; - auto dashDash = std::find(argBegin, argEnd, StringRef("--")); - if (dashDash == argEnd) { - llvm::errs() << "error: missing '--' in arguments to separate " - "script configuration from compiler arguments\n" - "usage:\n" - " swift-grep -- \n"; - return 1; - } - - Observer observer(llvm::ArrayRef(argBegin, dashDash)); - - // Set up the frontend arguments. - unsigned numFrontendArgs = argEnd - (dashDash + 1); - SmallVector frontendArgs; - frontendArgs.reserve(numFrontendArgs + 1); - frontendArgs.append(dashDash + 1, argEnd); - frontendArgs.push_back("-typecheck"); - - int frontendResult = - performFrontend(frontendArgs, argv[0], (void*) &main2, &observer); - - return (observer.hadError() ? 1 : frontendResult); -} - -int main(int argc, const char *argv[]) { - return main2(argc, argv); -}