From dc9fb65c4ffedc983c29bb0cddebf6fc4e9146e6 Mon Sep 17 00:00:00 2001 From: River Riddle Date: Mon, 9 May 2022 15:05:03 -0700 Subject: [PATCH] [mlir][Tablegen-LSP] Add support for a compilation database This provides a format for externally specifying the include directories for a source file. The format of the tablegen database is exactly the same as that for PDLL, namely it includes the absolute source file name and the set of include directories. The database format is shared to simplify the infra, and also because the format itself is general enough to share. Even if we desire to expand in the future to contain the actual compilation command, nothing there is specific enough that we would need two different formats. As with PDLL, support for generating the database is added to our mlir_tablegen cmake command. Differential Revision: https://reviews.llvm.org/D125441 --- mlir/cmake/modules/AddMLIR.cmake | 26 ++++++++++ .../Tools/lsp-server-support/CMakeLists.txt | 1 + .../CompilationDatabase.cpp | 47 +++++++++++++---- .../CompilationDatabase.h | 30 +++++++---- .../Tools/mlir-pdll-lsp-server/CMakeLists.txt | 1 - .../Tools/mlir-pdll-lsp-server/PDLLServer.cpp | 7 +-- .../TableGenLspServerMain.cpp | 10 +++- .../tblgen-lsp-server/TableGenServer.cpp | 37 +++++++++++--- .../Tools/tblgen-lsp-server/TableGenServer.h | 15 +++++- .../compilation_database.test | 21 ++++++++ .../tblgen-lsp-server/include/included.td | 3 ++ mlir/test/tblgen-lsp-server/lit.local.cfg | 1 + mlir/utils/vscode/package.json | 5 ++ mlir/utils/vscode/src/config.ts | 6 ++- mlir/utils/vscode/src/mlirContext.ts | 51 +++++++++++++++---- 15 files changed, 216 insertions(+), 45 deletions(-) rename mlir/lib/Tools/{mlir-pdll-lsp-server => lsp-server-support}/CompilationDatabase.cpp (61%) rename mlir/lib/Tools/{mlir-pdll-lsp-server => lsp-server-support}/CompilationDatabase.h (61%) create mode 100644 mlir/test/tblgen-lsp-server/compilation_database.test create mode 100644 mlir/test/tblgen-lsp-server/include/included.td create mode 100644 mlir/test/tblgen-lsp-server/lit.local.cfg diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake index a372832e39d3..c6eebfaac40c 100644 --- a/mlir/cmake/modules/AddMLIR.cmake +++ b/mlir/cmake/modules/AddMLIR.cmake @@ -1,10 +1,36 @@ include(GNUInstallDirs) include(LLVMDistributionSupport) +# Clear out any pre-existing compile_commands file before processing. This +# allows for generating a clean compile_commands on each configure. +file(REMOVE ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml) + function(mlir_tablegen ofn) tablegen(MLIR ${ARGV}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) + + # Get the current set of include paths for this td file. + cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN}) + get_directory_property(tblgen_includes INCLUDE_DIRECTORIES) + list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES}) + # Filter out any empty include items. + list(REMOVE_ITEM tblgen_includes "") + + # Build the absolute path for the current input file. + if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) + set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) + else() + set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS}) + endif() + + # Append the includes used for this file to the tablegen_compile_commands + # file. + file(APPEND ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml + "--- !FileInfo:\n" + " filepath: \"${LLVM_TARGET_DEFINITIONS_ABSOLUTE}\"\n" + " includes: \"${CMAKE_CURRENT_SOURCE_DIR};${tblgen_includes}\"\n" + ) endfunction() # Clear out any pre-existing compile_commands file before processing. This diff --git a/mlir/lib/Tools/lsp-server-support/CMakeLists.txt b/mlir/lib/Tools/lsp-server-support/CMakeLists.txt index b4c09a4e4f09..d71ecfaa6b52 100644 --- a/mlir/lib/Tools/lsp-server-support/CMakeLists.txt +++ b/mlir/lib/Tools/lsp-server-support/CMakeLists.txt @@ -1,4 +1,5 @@ add_mlir_library(MLIRLspServerSupportLib + CompilationDatabase.cpp Logging.cpp Protocol.cpp SourceMgrUtils.cpp diff --git a/mlir/lib/Tools/mlir-pdll-lsp-server/CompilationDatabase.cpp b/mlir/lib/Tools/lsp-server-support/CompilationDatabase.cpp similarity index 61% rename from mlir/lib/Tools/mlir-pdll-lsp-server/CompilationDatabase.cpp rename to mlir/lib/Tools/lsp-server-support/CompilationDatabase.cpp index 678d7dcf458e..31a6a3082529 100644 --- a/mlir/lib/Tools/mlir-pdll-lsp-server/CompilationDatabase.cpp +++ b/mlir/lib/Tools/lsp-server-support/CompilationDatabase.cpp @@ -1,4 +1,4 @@ -//===- CompilationDatabase.cpp - PDLL Compilation Database ----------------===// +//===- CompilationDatabase.cpp - LSP Compilation Database -----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,23 +10,37 @@ #include "../lsp-server-support/Logging.h" #include "../lsp-server-support/Protocol.h" #include "mlir/Support/FileUtilities.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/YAMLTraits.h" using namespace mlir; using namespace mlir::lsp; +//===----------------------------------------------------------------------===// +// YamlFileInfo +//===----------------------------------------------------------------------===// + +namespace { +struct YamlFileInfo { + /// The absolute path to the file. + std::string filename; + /// The include directories available for the file. + std::vector includeDirs; +}; +} // namespace + //===----------------------------------------------------------------------===// // CompilationDatabase //===----------------------------------------------------------------------===// -LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(CompilationDatabase::FileInfo) +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlFileInfo) namespace llvm { namespace yaml { template <> -struct MappingTraits { - static void mapping(IO &io, CompilationDatabase::FileInfo &info) { +struct MappingTraits { + static void mapping(IO &io, YamlFileInfo &info) { // Parse the filename and normalize it to the form we will expect from // incoming URIs. io.mapRequired("filepath", info.filename); @@ -54,10 +68,10 @@ CompilationDatabase::CompilationDatabase(ArrayRef databases) { loadDatabase(filename); } -const CompilationDatabase::FileInfo * +const CompilationDatabase::FileInfo & CompilationDatabase::getFileInfo(StringRef filename) const { auto it = files.find(filename); - return it == files.end() ? nullptr : &it->second; + return it == files.end() ? defaultFileInfo : it->second; } void CompilationDatabase::loadDatabase(StringRef filename) { @@ -75,15 +89,30 @@ void CompilationDatabase::loadDatabase(StringRef filename) { llvm::yaml::Input yaml(inputFile->getBuffer()); // Parse the yaml description and add any new files to the database. - std::vector parsedFiles; + std::vector parsedFiles; yaml >> parsedFiles; + + SetVector knownIncludes; for (auto &file : parsedFiles) { - auto it = files.try_emplace(file.filename, std::move(file)); + auto it = files.try_emplace(file.filename, std::move(file.includeDirs)); // If we encounter a duplicate file, log a warning and ignore it. if (!it.second) { - Logger::info("Duplicate .pdll file in compilation database: {0}", + Logger::info("Duplicate file in compilation database: {0}", file.filename); + continue; } + + // Track the includes for the file. + for (StringRef include : it.first->second.includeDirs) + knownIncludes.insert(include); } + + // Add all of the known includes to the default file info. We don't know any + // information about how to treat these files, but these may be project files + // that we just don't yet have information for. In these cases, providing some + // heuristic information provides a better user experience, and generally + // shouldn't lead to any negative side effects. + for (StringRef include : knownIncludes) + defaultFileInfo.includeDirs.push_back(include.str()); } diff --git a/mlir/lib/Tools/mlir-pdll-lsp-server/CompilationDatabase.h b/mlir/lib/Tools/lsp-server-support/CompilationDatabase.h similarity index 61% rename from mlir/lib/Tools/mlir-pdll-lsp-server/CompilationDatabase.h rename to mlir/lib/Tools/lsp-server-support/CompilationDatabase.h index 13a5f13c977f..56a3d5126739 100644 --- a/mlir/lib/Tools/mlir-pdll-lsp-server/CompilationDatabase.h +++ b/mlir/lib/Tools/lsp-server-support/CompilationDatabase.h @@ -1,13 +1,20 @@ -//===- CompilationDatabase.h - PDLL Compilation Database --------*- C++ -*-===// +//===- CompilationDatabase.h - LSP Compilation Database ---------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// This file contains a definition of a generic compilation database that can be +// used to provide information about the compilation of a given source file. It +// contains generic components, leaving more complex interpretation to the +// specific language servers that consume it. +// +//===----------------------------------------------------------------------===// -#ifndef LIB_MLIR_TOOLS_MLIRPDLLSPSERVER_COMPILATIONDATABASE_H_ -#define LIB_MLIR_TOOLS_MLIRPDLLSPSERVER_COMPILATIONDATABASE_H_ +#ifndef LIB_MLIR_TOOLS_LSPSERVERSUPPORT_COMPILATIONDATABASE_H_ +#define LIB_MLIR_TOOLS_LSPSERVERSUPPORT_COMPILATIONDATABASE_H_ #include "mlir/Support/LLVM.h" #include "llvm/ADT/StringMap.h" @@ -30,8 +37,10 @@ class CompilationDatabase { public: /// Compilation information for a specific file within the database. struct FileInfo { - /// The absolute path to the file. - std::string filename; + FileInfo() = default; + FileInfo(std::vector &&includeDirs) + : includeDirs(std::move(includeDirs)) {} + /// The include directories available for the file. std::vector includeDirs; }; @@ -40,9 +49,8 @@ public: /// descriptions of the database. CompilationDatabase(ArrayRef databases); - /// Get the compilation information for the provided file, or nullptr if the - /// database doesn't include information for `filename`. - const FileInfo *getFileInfo(StringRef filename) const; + /// Get the compilation information for the provided file. + const FileInfo &getFileInfo(StringRef filename) const; private: /// Load the given database file into this database. @@ -51,8 +59,12 @@ private: /// A map of filename to file information for each known file within the /// databases. llvm::StringMap files; + + /// A default file info that contains basic information for use by files that + /// weren't explicitly in the database. + FileInfo defaultFileInfo; }; } // namespace lsp } // namespace mlir -#endif // LIB_MLIR_TOOLS_MLIRPDLLSPSERVER_COMPILATIONDATABASE_H_ +#endif // LIB_MLIR_TOOLS_LSPSERVERSUPPORT_COMPILATIONDATABASE_H_ diff --git a/mlir/lib/Tools/mlir-pdll-lsp-server/CMakeLists.txt b/mlir/lib/Tools/mlir-pdll-lsp-server/CMakeLists.txt index 125b62325fed..f9ff5470eca0 100644 --- a/mlir/lib/Tools/mlir-pdll-lsp-server/CMakeLists.txt +++ b/mlir/lib/Tools/mlir-pdll-lsp-server/CMakeLists.txt @@ -1,5 +1,4 @@ llvm_add_library(MLIRPdllLspServerLib - CompilationDatabase.cpp LSPServer.cpp PDLLServer.cpp MlirPdllLspServerMain.cpp diff --git a/mlir/lib/Tools/mlir-pdll-lsp-server/PDLLServer.cpp b/mlir/lib/Tools/mlir-pdll-lsp-server/PDLLServer.cpp index 7ff7f8d8264d..dca2af0580b0 100644 --- a/mlir/lib/Tools/mlir-pdll-lsp-server/PDLLServer.cpp +++ b/mlir/lib/Tools/mlir-pdll-lsp-server/PDLLServer.cpp @@ -8,9 +8,9 @@ #include "PDLLServer.h" +#include "../lsp-server-support/CompilationDatabase.h" #include "../lsp-server-support/Logging.h" #include "../lsp-server-support/Protocol.h" -#include "CompilationDatabase.h" #include "mlir/Tools/PDLL/AST/Context.h" #include "mlir/Tools/PDLL/AST/Nodes.h" #include "mlir/Tools/PDLL/AST/Types.h" @@ -1422,9 +1422,10 @@ lsp::PDLLServer::~PDLLServer() = default; void lsp::PDLLServer::addOrUpdateDocument( const URIForFile &uri, StringRef contents, int64_t version, std::vector &diagnostics) { + // Build the set of additional include directories. std::vector additionalIncludeDirs = impl->options.extraDirs; - if (auto *fileInfo = impl->compilationDatabase.getFileInfo(uri.file())) - llvm::append_range(additionalIncludeDirs, fileInfo->includeDirs); + const auto &fileInfo = impl->compilationDatabase.getFileInfo(uri.file()); + llvm::append_range(additionalIncludeDirs, fileInfo.includeDirs); impl->files[uri.file()] = std::make_unique( uri, contents, version, additionalIncludeDirs, diagnostics); diff --git a/mlir/lib/Tools/tblgen-lsp-server/TableGenLspServerMain.cpp b/mlir/lib/Tools/tblgen-lsp-server/TableGenLspServerMain.cpp index 30f39eb83475..9f47a791f3ff 100644 --- a/mlir/lib/Tools/tblgen-lsp-server/TableGenLspServerMain.cpp +++ b/mlir/lib/Tools/tblgen-lsp-server/TableGenLspServerMain.cpp @@ -51,6 +51,13 @@ LogicalResult mlir::TableGenLspServerMain(int argc, char **argv) { llvm::cl::desc("Pretty-print JSON output"), llvm::cl::init(false), }; + llvm::cl::list extraIncludeDirs( + "tablegen-extra-dir", llvm::cl::desc("Extra directory of include files"), + llvm::cl::value_desc("directory"), llvm::cl::Prefix); + llvm::cl::list compilationDatabases( + "tablegen-compilation-database", + llvm::cl::desc("Compilation YAML databases containing additional " + "compilation information for .td files")); llvm::cl::ParseCommandLineOptions(argc, argv, "TableGen LSP Language Server"); @@ -68,6 +75,7 @@ LogicalResult mlir::TableGenLspServerMain(int argc, char **argv) { JSONTransport transport(stdin, llvm::outs(), inputStyle, prettyPrint); // Configure the servers and start the main language server. - TableGenServer server; + TableGenServer::Options options(compilationDatabases, extraIncludeDirs); + TableGenServer server(options); return runTableGenLSPServer(server, transport); } diff --git a/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp b/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp index de0508feca68..973097e0c847 100644 --- a/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp +++ b/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp @@ -8,6 +8,7 @@ #include "TableGenServer.h" +#include "../lsp-server-support/CompilationDatabase.h" #include "../lsp-server-support/Logging.h" #include "../lsp-server-support/Protocol.h" #include "../lsp-server-support/SourceMgrUtils.h" @@ -95,7 +96,9 @@ namespace { class TableGenTextFile { public: TableGenTextFile(const lsp::URIForFile &uri, StringRef fileContents, - int64_t version, std::vector &diagnostics); + int64_t version, + const std::vector &extraIncludeDirs, + std::vector &diagnostics); /// Return the current version of this text file. int64_t getVersion() const { return version; } @@ -118,9 +121,10 @@ private: }; } // namespace -TableGenTextFile::TableGenTextFile(const lsp::URIForFile &uri, - StringRef fileContents, int64_t version, - std::vector &diagnostics) +TableGenTextFile::TableGenTextFile( + const lsp::URIForFile &uri, StringRef fileContents, int64_t version, + const std::vector &extraIncludeDirs, + std::vector &diagnostics) : contents(fileContents.str()), version(version) { auto memBuffer = llvm::MemoryBuffer::getMemBufferCopy(contents, uri.file()); if (!memBuffer) { @@ -129,10 +133,11 @@ TableGenTextFile::TableGenTextFile(const lsp::URIForFile &uri, } // Build the set of include directories for this file. - // TODO: Setup external include directories. llvm::SmallString<32> uriDirectory(uri.file()); llvm::sys::path::remove_filename(uriDirectory); includeDirs.push_back(uriDirectory.str().str()); + includeDirs.insert(includeDirs.end(), extraIncludeDirs.begin(), + extraIncludeDirs.end()); sourceMgr.setIncludeDirs(includeDirs); sourceMgr.AddNewSourceBuffer(std::move(memBuffer), SMLoc()); @@ -161,6 +166,16 @@ TableGenTextFile::TableGenTextFile(const lsp::URIForFile &uri, //===----------------------------------------------------------------------===// struct lsp::TableGenServer::Impl { + explicit Impl(const Options &options) + : options(options), compilationDatabase(options.compilationDatabases) {} + + /// TableGen LSP options. + const Options &options; + + /// The compilation database containing additional information for files + /// passed to the server. + lsp::CompilationDatabase compilationDatabase; + /// The files held by the server, mapped by their URI file name. llvm::StringMap> files; }; @@ -169,14 +184,20 @@ struct lsp::TableGenServer::Impl { // TableGenServer //===----------------------------------------------------------------------===// -lsp::TableGenServer::TableGenServer() : impl(std::make_unique()) {} +lsp::TableGenServer::TableGenServer(const Options &options) + : impl(std::make_unique(options)) {} lsp::TableGenServer::~TableGenServer() = default; void lsp::TableGenServer::addOrUpdateDocument( const URIForFile &uri, StringRef contents, int64_t version, std::vector &diagnostics) { - impl->files[uri.file()] = - std::make_unique(uri, contents, version, diagnostics); + // Build the set of additional include directories. + std::vector additionalIncludeDirs = impl->options.extraDirs; + const auto &fileInfo = impl->compilationDatabase.getFileInfo(uri.file()); + llvm::append_range(additionalIncludeDirs, fileInfo.includeDirs); + + impl->files[uri.file()] = std::make_unique( + uri, contents, version, additionalIncludeDirs, diagnostics); } Optional lsp::TableGenServer::removeDocument(const URIForFile &uri) { diff --git a/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.h b/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.h index 925e450784f0..d7a88fd47dbd 100644 --- a/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.h +++ b/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.h @@ -24,7 +24,20 @@ class URIForFile; /// logic separate from the logic that involves LSP server/client communication. class TableGenServer { public: - TableGenServer(); + struct Options { + Options(const std::vector &compilationDatabases, + const std::vector &extraDirs) + : compilationDatabases(compilationDatabases), extraDirs(extraDirs) {} + + /// The filenames for databases containing compilation commands for TableGen + /// files passed to the server. + const std::vector &compilationDatabases; + + /// Additional list of include directories to search. + const std::vector &extraDirs; + }; + + TableGenServer(const Options &options); ~TableGenServer(); /// Add or update the document, with the provided `version`, at the given URI. diff --git a/mlir/test/tblgen-lsp-server/compilation_database.test b/mlir/test/tblgen-lsp-server/compilation_database.test new file mode 100644 index 000000000000..d1a9412af61c --- /dev/null +++ b/mlir/test/tblgen-lsp-server/compilation_database.test @@ -0,0 +1,21 @@ +// RUN: echo -e '--- !FileInfo:\n filepath: "/foo.td"\n includes: "%/S;%/S/../../include"' > %t.yml +// RUN: tblgen-lsp-server -tablegen-compilation-database=%t.yml -lit-test < %s | FileCheck %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"tablegen","capabilities":{},"trace":"off"}} +// ----- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{ + "uri":"test:///foo.td", + "languageId":"tablegen", + "version":1, + "text":"include \"include/included.td\"" +}}} +// Check that we can properly process the includes without errors. +// CHECK: "method": "textDocument/publishDiagnostics", +// CHECK-NEXT: "params": { +// CHECK-NEXT: "diagnostics": [], +// CHECK-NEXT: "uri": "test:///foo.td", +// CHECK-NEXT: "version": 1 +// CHECK-NEXT: } +// ----- +{"jsonrpc":"2.0","id":7,"method":"shutdown"} +// ----- +{"jsonrpc":"2.0","method":"exit"} diff --git a/mlir/test/tblgen-lsp-server/include/included.td b/mlir/test/tblgen-lsp-server/include/included.td new file mode 100644 index 000000000000..0507300c7bc3 --- /dev/null +++ b/mlir/test/tblgen-lsp-server/include/included.td @@ -0,0 +1,3 @@ + +// This file is merely to test the processing of includes, it has +// no other purpose or contents. diff --git a/mlir/test/tblgen-lsp-server/lit.local.cfg b/mlir/test/tblgen-lsp-server/lit.local.cfg new file mode 100644 index 000000000000..25d08c7aba30 --- /dev/null +++ b/mlir/test/tblgen-lsp-server/lit.local.cfg @@ -0,0 +1 @@ +config.excludes = ['include'] diff --git a/mlir/utils/vscode/package.json b/mlir/utils/vscode/package.json index 55033c3304ba..cca2ba1ace03 100644 --- a/mlir/utils/vscode/package.json +++ b/mlir/utils/vscode/package.json @@ -156,6 +156,11 @@ "type": "string", "description": "The file path of the tblgen-lsp-server executable." }, + "mlir.tablegen_compilation_databases": { + "scope": "resource", + "type": "array", + "description": "A list of `tablegen_compile_commands.yml` database files containing information about .td files processed by the server." + }, "mlir.onSettingsChanged": { "type": "string", "default": "prompt", diff --git a/mlir/utils/vscode/src/config.ts b/mlir/utils/vscode/src/config.ts index d7dd5bfb5454..04ff8f53c9e5 100644 --- a/mlir/utils/vscode/src/config.ts +++ b/mlir/utils/vscode/src/config.ts @@ -4,8 +4,10 @@ import * as vscode from 'vscode'; * Gets the config value `mlir.`, with an optional workspace folder. */ export function get(key: string, - workspaceFolder: vscode.WorkspaceFolder = null): T { - return vscode.workspace.getConfiguration('mlir', workspaceFolder).get(key); + workspaceFolder: vscode.WorkspaceFolder = null, + defaultValue: T = undefined): T { + return vscode.workspace.getConfiguration('mlir', workspaceFolder) + .get(key, defaultValue); } /** diff --git a/mlir/utils/vscode/src/mlirContext.ts b/mlir/utils/vscode/src/mlirContext.ts index c8d4f78818a0..c0c2b53edbaf 100644 --- a/mlir/utils/vscode/src/mlirContext.ts +++ b/mlir/utils/vscode/src/mlirContext.ts @@ -90,23 +90,22 @@ export class MLIRContext implements vscode.Disposable { } /** - * Prepare the server options for a PDLL server, e.g. populating any - * accessible compilation databases. + * Prepare a compilation database option for a server. */ - async preparePDLLServerOptions(workspaceFolder: vscode.WorkspaceFolder, - configsToWatch: string[], - pathsToWatch: string[], - additionalServerArgs: string[]) { + async prepareCompilationDatabaseServerOptions( + languageName: string, workspaceFolder: vscode.WorkspaceFolder, + configsToWatch: string[], pathsToWatch: string[], + additionalServerArgs: string[]) { // Process the compilation databases attached for the workspace folder. - let databases = - config.get('pdll_compilation_databases', workspaceFolder); + let databases = config.get( + `${languageName}_compilation_databases`, workspaceFolder, []); // If no databases were explicitly specified, default to a database in the // 'build' directory within the current workspace. if (databases.length === 0) { if (workspaceFolder) { databases.push(workspaceFolder.uri.fsPath + - '/build/pdll_compile_commands.yml'); + `/build/${languageName}_compile_commands.yml`); } // Otherwise, try to resolve each of the paths. @@ -116,14 +115,40 @@ export class MLIRContext implements vscode.Disposable { } } - configsToWatch.push('pdll_compilation_databases'); + configsToWatch.push(`${languageName}_compilation_databases`); pathsToWatch.push(...databases); // Setup the compilation databases as additional arguments to pass to the // server. databases.filter(database => database !== ''); additionalServerArgs.push(...databases.map( - (database) => `--pdll-compilation-database=${database}`)); + (database) => `--${languageName}-compilation-database=${database}`)); + } + + /** + * Prepare the server options for a PDLL server, e.g. populating any + * accessible compilation databases. + */ + async preparePDLLServerOptions(workspaceFolder: vscode.WorkspaceFolder, + configsToWatch: string[], + pathsToWatch: string[], + additionalServerArgs: string[]) { + await this.prepareCompilationDatabaseServerOptions( + 'pdll', workspaceFolder, configsToWatch, pathsToWatch, + additionalServerArgs); + } + + /** + * Prepare the server options for a TableGen server, e.g. populating any + * accessible compilation databases. + */ + async prepareTableGenServerOptions(workspaceFolder: vscode.WorkspaceFolder, + configsToWatch: string[], + pathsToWatch: string[], + additionalServerArgs: string[]) { + await this.prepareCompilationDatabaseServerOptions( + 'tablegen', workspaceFolder, configsToWatch, pathsToWatch, + additionalServerArgs); } /** @@ -143,6 +168,10 @@ export class MLIRContext implements vscode.Disposable { await this.preparePDLLServerOptions(workspaceFolder, configsToWatch, filepathsToWatch, additionalServerArgs); + } else if (languageName == 'tablegen') { + await this.prepareTableGenServerOptions(workspaceFolder, configsToWatch, + filepathsToWatch, + additionalServerArgs); } // Try to activate the language client.