From 68e06e4cde8782f912ffaea0c5be8d4168d21c0d Mon Sep 17 00:00:00 2001 From: s1n7ax Date: Sun, 3 Dec 2023 01:13:46 +0530 Subject: [PATCH 1/2] refactor!: move dap APIs to nvim-dap --- lua/java-core/adapters/init.lua | 2 +- lua/java-core/api/test.lua | 38 +++--- lua/java-core/dap/adapters.lua | 26 ---- lua/java-core/dap/init.lua | 112 ------------------ lua/java-core/dap/runner.lua | 75 ------------ .../ls/clients/java-debug-client.lua | 31 +++-- lua/java-core/ls/clients/java-test-client.lua | 56 +++++---- lua/java-core/ls/clients/jdtls-client.lua | 23 ++-- 8 files changed, 81 insertions(+), 282 deletions(-) delete mode 100644 lua/java-core/dap/adapters.lua delete mode 100644 lua/java-core/dap/init.lua delete mode 100644 lua/java-core/dap/runner.lua diff --git a/lua/java-core/adapters/init.lua b/lua/java-core/adapters/init.lua index f14161b..459b4e0 100644 --- a/lua/java-core/adapters/init.lua +++ b/lua/java-core/adapters/init.lua @@ -8,7 +8,7 @@ local M = {} ---@param launch_args JavaCoreTestJunitLaunchArguments ---@param java_exec string ---@param config { debug: boolean, label: string } ----@return java_core.DapLauncherConfig +---@return java-core.DapLauncherConfig function M.get_dap_launcher_config(launch_args, java_exec, config) return { name = config.label, diff --git a/lua/java-core/api/test.lua b/lua/java-core/api/test.lua index c95ba0a..9386fca 100644 --- a/lua/java-core/api/test.lua +++ b/lua/java-core/api/test.lua @@ -1,32 +1,26 @@ local log = require('java-core.utils.log') local data_adapters = require('java-core.adapters') -local JavaDebug = require('java-core.ls.clients.java-debug-client') -local JavaTest = require('java-core.ls.clients.java-test-client') +local DebugClient = require('java-core.ls.clients.java-debug-client') +local TestClient = require('java-core.ls.clients.java-test-client') ---@class java_core.TestApi ----@field private client java_core.JdtlsClient ----@field private debug_client JavaCoreDebugClient ----@field private test_client java_core.TestClient ----@field private runner java_core.DapRunner +---@field private client java-core.JdtlsClient +---@field private debug_client java-core.DebugClient +---@field private test_client java-core.TestClient +---@field private runner java-dap.DapRunner local M = {} ---Returns a new test helper client ----@param args { client: LspClient, runner: java_core.DapRunner } +---@param args { client: LspClient, runner: java-dap.DapRunner } ---@return java_core.TestApi function M:new(args) local o = { client = args.client, } - o.debug_client = JavaDebug:new({ - client = args.client, - }) - - o.test_client = JavaTest:new({ - client = args.client, - }) - + o.debug_client = DebugClient(args.client) + o.test_client = TestClient(args.client) o.runner = args.runner setmetatable(o, self) @@ -37,7 +31,7 @@ end ---Returns a list of test methods ---@param file_uri string uri of the class ----@return java_core.TestDetailsWithRange[] # list of test methods +---@return java-core.TestDetailsWithRange[] # list of test methods function M:get_test_methods(file_uri) local classes = self.test_client:find_test_types_and_methods(file_uri) local methods = {} @@ -53,14 +47,10 @@ function M:get_test_methods(file_uri) return methods end ----Runs the test class in the given buffer ----@param buffer integer ----@param config JavaCoreDapLauncherConfigOverridable - ---comment ---@param buffer number ---@param report java_test.JUnitTestReport ----@param config? JavaCoreDapLauncherConfigOverridable config to override the default values in test launcher config +---@param config? java-dap.DapLauncherConfigOverridable config to override the default values in test launcher config function M:run_class_by_buffer(buffer, report, config) local tests = self:get_test_class_by_buffer(buffer) self:run_test(tests, report, config) @@ -69,7 +59,7 @@ end ---Returns test classes in the given buffer ---@priate ---@param buffer integer ----@return java_core.TestDetailsWithChildrenAndRange # get test class details +---@return java-core.TestDetailsWithChildrenAndRange # get test class details function M:get_test_class_by_buffer(buffer) log.debug('finding test class by buffer') @@ -78,9 +68,9 @@ function M:get_test_class_by_buffer(buffer) end ---Run the given test ----@param tests java_core.TestDetails[] +---@param tests java-core.TestDetails[] ---@param report java_test.JUnitTestReport ----@param config? JavaCoreDapLauncherConfigOverridable config to override the default values in test launcher config +---@param config? java-dap.DapLauncherConfigOverridable config to override the default values in test launcher config function M:run_test(tests, report, config) local launch_args = self.test_client:resolve_junit_launch_arguments( data_adapters.get_junit_launch_argument_params(tests) diff --git a/lua/java-core/dap/adapters.lua b/lua/java-core/dap/adapters.lua deleted file mode 100644 index 47c17f7..0000000 --- a/lua/java-core/dap/adapters.lua +++ /dev/null @@ -1,26 +0,0 @@ -local M = {} - ----Returns the dap config record ----@param main JavaDebugResolveMainClassRecord ----@param classpath string[][] ----@param java_exec string ----@return java_core.DapLauncherConfig -function M.get_dap_config(main, classpath, java_exec) - local project_name = main.projectName - local main_class = main.mainClass - local module_paths = classpath[1] - local class_paths = classpath[2] - - return { - request = 'launch', - type = 'java', - name = string.format('%s -> %s', project_name, main_class), - projectName = project_name, - mainClass = main_class, - javaExec = java_exec, - modulePaths = module_paths, - classPaths = class_paths, - } -end - -return M diff --git a/lua/java-core/dap/init.lua b/lua/java-core/dap/init.lua deleted file mode 100644 index 5a8e910..0000000 --- a/lua/java-core/dap/init.lua +++ /dev/null @@ -1,112 +0,0 @@ -local log = require('java-core.utils.log') -local adapters = require('java-core.dap.adapters') -local JavaDebug = require('java-core.ls.clients.java-debug-client') - ----@class JavaCoreDap ----@field client LspClient ----@field java_debug JavaCoreDebugClient -local M = {} - ----Returns a new dap instance ----@param args { client: LspClient } ----@return JavaCoreDap -function M:new(args) - local o = { - client = args.client, - } - - o.java_debug = JavaDebug:new({ - client = args.client, - }) - - setmetatable(o, self) - self.__index = self - return o -end - ----@class JavaCoreDapAdapter ----@field type string ----@field host string ----@field port integer - ----Returns the dap adapter config ----@return JavaCoreDapAdapter # dap adapter details -function M:get_dap_adapter() - log.debug('creating dap adapter for java') - - local port = self.java_debug:start_debug_session() - - return { - type = 'server', - host = '127.0.0.1', - port = port, - } -end - ----Returns the dap configuration for the current project ----@return java_core.DapLauncherConfig[] # dap configuration details -function M:get_dap_config() - log.info('creating dap configuration for java') - - local mains = self.java_debug:resolve_main_class() - local config = {} - - for _, main in ipairs(mains) do - table.insert(config, self:get_dap_config_record(main)) - end - - return config -end - ----Returns the dap config for the given main class ----@param main JavaDebugResolveMainClassRecord ----@return java_core.DapLauncherConfig # dap launch configuration record -function M:get_dap_config_record(main) - local classpaths = - self.java_debug:resolve_classpath(main.mainClass, main.projectName) - - local java_exec = - self.java_debug:resolve_java_executable(main.mainClass, main.projectName) - - return adapters.get_dap_config(main, classpaths, java_exec) -end - -return M - ----@class JavaCoreDapLauncherConfigOverridable ----@field name? string ----@field type? string ----@field request? string ----@field mainClass? string ----@field projectName? string ----@field cwd? string ----@field classPaths? string[] ----@field modulePaths? string[] ----@field vmArgs? string ----@field noDebug? boolean ----@field javaExec? string ----@field args? string ----@field env? { [string]: string; } ----@field envFile? string ----@field sourcePaths? string[] ----@field preLaunchTask? string ----@field postDebugTask? string - ----@class java_core.DapLauncherConfig ----@field name string ----@field type string ----@field request string ----@field mainClass string ----@field projectName string ----@field cwd string ----@field classPaths string[] ----@field modulePaths string[] ----@field vmArgs string ----@field noDebug boolean ----@field javaExec string ----@field args string ----@field env? { [string]: string; } ----@field envFile? string ----@field sourcePaths string[] ----@field preLaunchTask? string ----@field postDebugTask? string diff --git a/lua/java-core/dap/runner.lua b/lua/java-core/dap/runner.lua deleted file mode 100644 index cdade71..0000000 --- a/lua/java-core/dap/runner.lua +++ /dev/null @@ -1,75 +0,0 @@ -local log = require('java-core.utils.log') - ----@class java_core.DapRunner ----@field private server uv_tcp_t -local M = {} - ----@return java_core.DapRunner -function M:new() - local o = { - server = nil, - } - - setmetatable(o, self) - self.__index = self - return o -end - ----Dap run with given config ----@param config java_core.DapLauncherConfig ----@param report java_test.JUnitTestReport -function M:run_by_config(config, report) - log.debug('running dap with config: ', config) - - require('dap').run(config --[[@as Configuration]], { - before = function(conf) - return self:before(conf, report) - end, - - after = function() - return self:after() - end, - }) -end - ----Runs before the dap run ----@private ----@param conf java_core.DapLauncherConfig ----@param report java_test.JUnitTestReport ----@return java_core.DapLauncherConfig -function M:before(conf, report) - log.debug('running "before" callback') - - self.server = assert(vim.loop.new_tcp(), 'uv.new_tcp() must return handle') - self.server:bind('127.0.0.1', 0) - self.server:listen(128, function(err) - assert(not err, err) - - local sock = assert(vim.loop.new_tcp(), 'uv.new_tcp must return handle') - self.server:accept(sock) - local success = sock:read_start(report:get_stream_reader(sock)) - assert(success == 0, 'failed to listen to reader') - end) - - -- replace the port number in the generated args - conf.args = - conf.args:gsub('-port ([0-9]+)', '-port ' .. self.server:getsockname().port) - - return conf -end - ----Runs aafter the dap run ----@private -function M:after() - vim.debug('running "after" callback') - - if self.server then - self.server:shutdown() - self.server:close() - end -end - -return M - ----@class java_core.DapRunReport ----@field get_stream_reader fun(self: java_core.DapRunReport, conn: uv_tcp_t): fun(err: string|nil, buffer: string|nil) diff --git a/lua/java-core/ls/clients/java-debug-client.lua b/lua/java-core/ls/clients/java-debug-client.lua index 807c872..1e635da 100644 --- a/lua/java-core/ls/clients/java-debug-client.lua +++ b/lua/java-core/ls/clients/java-debug-client.lua @@ -1,7 +1,13 @@ +local class = require('java-core.utils.class') + local JdtlsClient = require('java-core.ls.clients.jdtls-client') ----@class JavaCoreDebugClient: java_core.JdtlsClient -local M = JdtlsClient:new() +---@class java-core.DebugClient: java-core.JdtlsClient +local DebugClient = class(JdtlsClient) + +function DebugClient:_init(client) + self:super(client) +end ---@class JavaDebugResolveMainClassRecord ---@field mainClass string @@ -10,7 +16,7 @@ local M = JdtlsClient:new() ---Returns a list of main classes in the current workspace ---@return JavaDebugResolveMainClassRecord[] # resolved main class -function M:resolve_main_class() +function DebugClient:resolve_main_class() return self:execute_command('vscode.java.resolveMainClass') end @@ -18,7 +24,7 @@ end ---@param project_name string ---@param main_class string ---@return string[][] # resolved class and module paths -function M:resolve_classpath(main_class, project_name) +function DebugClient:resolve_classpath(main_class, project_name) return self:execute_command( 'vscode.java.resolveClasspath', { main_class, project_name } @@ -29,7 +35,7 @@ end ---@param project_name string ---@param main_class string ---@return string # path to java executable -function M:resolve_java_executable(main_class, project_name) +function DebugClient:resolve_java_executable(main_class, project_name) return self:execute_command('vscode.java.resolveJavaExecutable', { main_class, project_name, @@ -42,7 +48,7 @@ end ---@param inheritedOptions boolean ---@param expectedOptions { [string]: any } ---@return boolean # true if the setting is the expected setting -function M:check_project_settings( +function DebugClient:check_project_settings( main_class, project_name, inheritedOptions, @@ -61,12 +67,12 @@ end ---Starts a debug session and returns the port number ---@return integer # port number of the debug session -function M:start_debug_session() +function DebugClient:start_debug_session() return self:execute_command('vscode.java.startDebugSession') end ---@enum CompileWorkspaceStatus -M.CompileWorkspaceStatus = { +DebugClient.CompileWorkspaceStatus = { FAILED = 0, SUCCEED = 1, WITHERROR = 2, @@ -79,7 +85,12 @@ M.CompileWorkspaceStatus = { ---@param file_path? string ---@param is_full_build boolean ---@return CompileWorkspaceStatus # compiled status -function M:build_workspace(main_class, project_name, file_path, is_full_build) +function DebugClient:build_workspace( + main_class, + project_name, + file_path, + is_full_build +) return self:execute_command( 'vscode.java.buildWorkspace', vim.fn.json_encode({ @@ -91,4 +102,4 @@ function M:build_workspace(main_class, project_name, file_path, is_full_build) ) end -return M +return DebugClient diff --git a/lua/java-core/ls/clients/java-test-client.lua b/lua/java-core/ls/clients/java-test-client.lua index 7b09228..c58d3bb 100644 --- a/lua/java-core/ls/clients/java-test-client.lua +++ b/lua/java-core/ls/clients/java-test-client.lua @@ -1,7 +1,9 @@ local log = require('java-core.utils.log') +local class = require('java-core.utils.class') + local JdtlsClient = require('java-core.ls.clients.jdtls-client') ----@class java_core.TestDetails: Configuration +---@class java-core.TestDetails: Configuration ---@field fullName string ---@field id string ---@field jdtHandler string @@ -11,17 +13,17 @@ local JdtlsClient = require('java-core.ls.clients.jdtls-client') ---@field testLevel integer ---@field uri string ----@class java_core.TestDetailsWithRange: java_core.TestDetails ----@field range java_core.TestRange +---@class java-core.TestDetailsWithRange: java-core.TestDetails +---@field range java-core.TestRange ----@class java_core.TestDetailsWithChildren: java_core.TestDetails ----@field children java_core.TestDetailsWithRange[] +---@class java-core.TestDetailsWithChildren: java-core.TestDetails +---@field children java-core.TestDetailsWithRange[] ----@class java_core.TestDetailsWithChildrenAndRange: java_core.TestDetails ----@field range java_core.TestRange ----@field children java_core.TestDetailsWithRange[] +---@class java-core.TestDetailsWithChildrenAndRange: java-core.TestDetails +---@field range java-core.TestRange +---@field children java-core.TestDetailsWithRange[] ----@class java_core.TestRange +---@class java-core.TestRange ---@field start CursorPoint ---@field end CursorPoint @@ -29,12 +31,16 @@ local JdtlsClient = require('java-core.ls.clients.jdtls-client') ---@field line integer ---@field character integer ----@class java_core.TestClient: java_core.JdtlsClient -local M = JdtlsClient:new() +---@class java-core.TestClient: java-core.JdtlsClient +local TestClient = class(JdtlsClient) + +function TestClient:_init(client) + self:super(client) +end ---Returns a list of project details in the current root ----@return java_core.TestDetails[] # test details of the projects -function M:find_java_projects() +---@return java-core.TestDetails[] # test details of the projects +function TestClient:find_java_projects() return self:execute_command( 'vscode.java.test.findJavaProjects', { vim.uri_from_fname(self.client.config.root_dir) } @@ -44,8 +50,8 @@ end ---Returns a list of test package details ---@param handler string ---@param token? string ----@return java_core.TestDetailsWithChildren[] # test package details -function M:find_test_packages_and_types(handler, token) +---@return java-core.TestDetailsWithChildren[] # test package details +function TestClient:find_test_packages_and_types(handler, token) return self:execute_command( 'vscode.java.test.findTestPackagesAndTypes', { handler, token } @@ -55,8 +61,8 @@ end ---Returns test informations in a given file ---@param file_uri string ---@param token? string ----@return java_core.TestDetailsWithChildrenAndRange[] # test details -function M:find_test_types_and_methods(file_uri, token) +---@return java-core.TestDetailsWithChildrenAndRange[] # test details +function TestClient:find_test_types_and_methods(file_uri, token) return self:execute_command( 'vscode.java.test.findTestTypesAndMethods', { file_uri, token } @@ -75,13 +81,13 @@ end ---@class JavaCoreTestResolveJUnitLaunchArgumentsParams ---@field project_name string ---@field test_names string[] ----@field test_level java_core.TestLevel ----@field test_kind java_core.TestKind +---@field test_level java-core.TestLevel +---@field test_kind java-core.TestKind ---Returns junit launch arguments ---@param args JavaCoreTestResolveJUnitLaunchArgumentsParams ---@return JavaCoreTestJunitLaunchArguments # junit launch arguments -function M:resolve_junit_launch_arguments(args) +function TestClient:resolve_junit_launch_arguments(args) local launch_args = self:execute_command( 'vscode.java.test.junit.argument', vim.fn.json_encode(args) @@ -97,16 +103,16 @@ function M:resolve_junit_launch_arguments(args) return launch_args.body end ----@enum java_core.TestKind -M.TestKind = { +---@enum java-core.TestKind +TestClient.TestKind = { JUnit5 = 0, JUnit = 1, TestNG = 2, None = 100, } ----@enum java_core.TestLevel -M.TestLevel = { +---@enum java-core.TestLevel +TestClient.TestLevel = { Root = 0, Workspace = 1, WorkspaceFolder = 2, @@ -117,4 +123,4 @@ M.TestLevel = { Invocation = 7, } -return M +return TestClient diff --git a/lua/java-core/ls/clients/jdtls-client.lua b/lua/java-core/ls/clients/jdtls-client.lua index 738d0cf..32b2e2c 100644 --- a/lua/java-core/ls/clients/jdtls-client.lua +++ b/lua/java-core/ls/clients/jdtls-client.lua @@ -1,14 +1,19 @@ local log = require('java-core.utils.log') +local class = require('java-core.utils.class') local async = require('java-core.utils.async') local await = async.wait_handle_error ----@class java_core.JdtlsClient +---@class java-core.JdtlsClient ---@field client LspClient -local M = {} +local JdtlsClient = class() + +function JdtlsClient:_init(client) + self.client = client +end ---@param args? { client: LspClient } ----@return java_core.JdtlsClient -function M:new(args) +---@return java-core.JdtlsClient +function JdtlsClient:new(args) local o = { client = (args or {}).client, } @@ -23,7 +28,7 @@ end ---@param arguments? string | string[] ---@param buffer? integer ---@return any -function M:execute_command(command, arguments, buffer) +function JdtlsClient:execute_command(command, arguments, buffer) log.debug('executing: workspace/executeCommand - ' .. command) local cmd_info = { @@ -54,11 +59,11 @@ end ---Returns the decompiled class file content ---@param uri string uri of the class file ---@return string # decompiled file content -function M:java_decompile(uri) +function JdtlsClient:java_decompile(uri) return self:execute_command('java.decompile', { uri }) end -function M:get_capability(...) +function JdtlsClient:get_capability(...) local capability = self.client.server_capabilities for _, value in ipairs({ ... }) do @@ -76,7 +81,7 @@ end ---Returns true if the LS supports the given command ---@param command_name string name of the command ---@return boolean # true if the command is supported -function M:has_command(command_name) +function JdtlsClient:has_command(command_name) local commands = self:get_capability('executeCommandProvider', 'commands') if not commands then @@ -86,4 +91,4 @@ function M:has_command(command_name) return vim.tbl_contains(commands, command_name) end -return M +return JdtlsClient From 03062dd5385b703913860ce50ae33f7fca8188ed Mon Sep 17 00:00:00 2001 From: s1n7ax Date: Sun, 3 Dec 2023 01:17:38 +0530 Subject: [PATCH 2/2] fix(test): fix tests after dap API transfer --- Makefile | 4 ++-- tests/java/java_spec.lua | 2 +- tests/{prepare_config.lua => prepare-config.lua} | 0 tests/{test_config.lua => test-config.lua} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename tests/{prepare_config.lua => prepare-config.lua} (100%) rename tests/{test_config.lua => test-config.lua} (100%) diff --git a/Makefile b/Makefile index 24b3186..d5bb4c0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -PREPARE_CONFIG=tests/prepare_config.lua -TEST_CONFIG=tests/test_config.lua +PREPARE_CONFIG=tests/prepare-config.lua +TEST_CONFIG=tests/test-config.lua TESTS_DIR=tests/ .PHONY: test diff --git a/tests/java/java_spec.lua b/tests/java/java_spec.lua index a041c5f..e3f6b9c 100644 --- a/tests/java/java_spec.lua +++ b/tests/java/java_spec.lua @@ -1,5 +1,5 @@ describe('setup', function() it('get_config API is available', function() - assert(require('java-core.dap'), 'dap module is available') + assert(require('java-core.ls.servers.jdtls'), 'dap module is available') end) end) diff --git a/tests/prepare_config.lua b/tests/prepare-config.lua similarity index 100% rename from tests/prepare_config.lua rename to tests/prepare-config.lua diff --git a/tests/test_config.lua b/tests/test-config.lua similarity index 100% rename from tests/test_config.lua rename to tests/test-config.lua