Skip to content

Commit 0b0716b

Browse files
authored
refactor!: improvements in project structure & architecture (#21)
1 parent f7c80ca commit 0b0716b

File tree

18 files changed

+480
-425
lines changed

18 files changed

+480
-425
lines changed

lua/java-core/adapters/init.lua

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
local List = require('java-core.utils.list')
2+
local Set = require('java-core.utils.set')
3+
local JavaTestClient = require('java-core.ls.clients.java-test-client')
4+
5+
local M = {}
6+
7+
---Returns the launcher config
8+
---@param launch_args JavaCoreTestJunitLaunchArguments
9+
---@param java_exec string
10+
---@param config { debug: boolean, label: string }
11+
---@return JavaCoreDapLauncherConfig
12+
function M.get_dap_launcher_config(launch_args, java_exec, config)
13+
return {
14+
name = config.label,
15+
type = 'java',
16+
request = 'launch',
17+
mainClass = launch_args.mainClass,
18+
projectName = launch_args.projectName,
19+
noDebug = not config.debug,
20+
javaExec = java_exec,
21+
cwd = launch_args.workingDirectory,
22+
classPaths = Set:new(launch_args.classpath),
23+
modulePaths = Set:new(launch_args.modulepath),
24+
vmArgs = List:new(launch_args.vmArguments):join(' '),
25+
args = List:new(launch_args.programArguments):join(' '),
26+
-- env: config?.env,
27+
-- envFile: config?.envFile,
28+
-- sourcePaths: config?.sourcePaths,
29+
-- preLaunchTask: config?.preLaunchTask,
30+
-- postDebugTask: config?.postDebugTask,
31+
}
32+
33+
-- if test_details.testKind == TestKind.TestNG then
34+
-- path.join(extensionContext.extensionPath, 'server', 'com.microsoft.java.test.runner-jar-with-dependencies.jar'),
35+
-- end
36+
end
37+
38+
---Ruterns the launch argument parameters for given test or tests
39+
---@param tests JavaCoreTestDetails | JavaCoreTestDetails[]
40+
---@return JavaCoreTestResolveJUnitLaunchArgumentsParams
41+
function M.get_junit_launch_argument_params(tests)
42+
if not vim.tbl_islist(tests) then
43+
return {
44+
projectName = tests.projectName,
45+
testLevel = tests.testLevel,
46+
testKind = tests.testKind,
47+
testNames = M.get_test_names({ tests }),
48+
}
49+
end
50+
51+
local first_test = tests[1]
52+
53+
return {
54+
projectName = first_test.projectName,
55+
testLevel = first_test.testLevel,
56+
testKind = first_test.testKind,
57+
testNames = M.get_test_names(tests),
58+
}
59+
end
60+
61+
---Returns a list of test names to be passed to test launch arguments resolver
62+
---@param tests JavaCoreTestDetails[]
63+
---@return List
64+
function M.get_test_names(tests)
65+
return List:new(tests):map(function(test)
66+
if
67+
test.testKind == JavaTestClient.TestKind.TestNG
68+
or test.testLevel == JavaTestClient.TestLevel.Class
69+
then
70+
return test.fullName
71+
end
72+
73+
return test.jdtHandler
74+
end)
75+
end
76+
77+
return M

lua/java-core/api/test.lua

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
local log = require('java-core.utils.log')
2+
local data_adapters = require('java-core.adapters')
3+
4+
local Promise = require('java-core.utils.promise')
5+
local TestReport = require('java-core.dap.test-report')
6+
local JavaDapRunner = require('java-core.dap.runner')
7+
local JavaDebug = require('java-core.ls.clients.java-debug-client')
8+
local JavaTest = require('java-core.ls.clients.java-test-client')
9+
10+
---@class JavaCoreTestApi
11+
---@field private client JavaCoreJdtlsClient
12+
---@field private debug_client JavaCoreDebugClient
13+
---@field private test_client JavaCoreTestClient
14+
---@field private runner JavaCoreDapRunner
15+
local M = {}
16+
17+
---Returns a new test helper client
18+
---@param args { client: LspClient }
19+
---@return JavaCoreTestApi
20+
function M:new(args)
21+
local o = {
22+
client = args.client,
23+
}
24+
25+
o.debug_client = JavaDebug:new({
26+
client = args.client,
27+
})
28+
29+
o.test_client = JavaTest:new({
30+
client = args.client,
31+
})
32+
33+
o.runner = JavaDapRunner:new({
34+
reporter = TestReport:new(),
35+
})
36+
37+
setmetatable(o, self)
38+
self.__index = self
39+
40+
return o
41+
end
42+
43+
---Runs the test class in the given buffer
44+
---@param buffer integer
45+
---@param config JavaCoreDapLauncherConfigOverridable
46+
---@return Promise
47+
function M:run_class_by_buffer(buffer, config)
48+
return self:get_test_class_by_buffer(buffer):thenCall(function(tests)
49+
return self:run_test(tests, config)
50+
end)
51+
end
52+
53+
---Returns test classes in the given buffer
54+
---@priate
55+
---@param buffer integer
56+
---@return Promise # Promise<JavaCoreTestDetailsWithChildrenAndRange>
57+
function M:get_test_class_by_buffer(buffer)
58+
log.debug('finding test class by buffer')
59+
60+
return Promise.resolve():thenCall(function()
61+
if not vim.api.nvim_buf_is_valid(buffer) then
62+
local msg = 'passed buffer' .. tostring(buffer) .. ' is not valid'
63+
log.error(msg)
64+
error(msg)
65+
end
66+
67+
local uri = vim.uri_from_bufnr(buffer)
68+
return self.test_client:find_test_types_and_methods(uri)
69+
end)
70+
end
71+
72+
---Run the given test
73+
---@private
74+
---@param tests JavaCoreTestDetails[]
75+
---@param config? JavaCoreDapLauncherConfigOverridable config to override the default values in test launcher config
76+
---@return Promise #
77+
function M:run_test(tests, config)
78+
---@type JavaCoreTestJunitLaunchArguments
79+
local launch_args
80+
81+
return self.test_client
82+
:resolve_junit_launch_arguments(
83+
data_adapters.get_junit_launch_argument_params(tests)
84+
)
85+
:thenCall(
86+
---@param _launch_args JavaCoreTestJunitLaunchArguments
87+
function(_launch_args)
88+
launch_args = _launch_args
89+
90+
return self.debug_client:resolve_java_executable(
91+
launch_args.mainClass,
92+
launch_args.projectName
93+
)
94+
end
95+
)
96+
:thenCall(
97+
---@param java_exec string
98+
function(java_exec)
99+
local dap_launcher_config =
100+
--@TODO I don't know why the hell debug is hard coded here
101+
data_adapters.get_dap_launcher_config(launch_args, java_exec, {
102+
debug = true,
103+
label = 'Launch All Java Tests',
104+
})
105+
106+
log.debug('dap launcher config is: ', dap_launcher_config)
107+
108+
dap_launcher_config =
109+
vim.tbl_deep_extend('force', dap_launcher_config, config or {})
110+
111+
return self.runner:run_by_config(dap_launcher_config)
112+
end
113+
)
114+
end
115+
116+
return M

lua/java-core/dap/adapters.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
local M = {}
2+
3+
---Returns the dap config record
4+
---@param main JavaDebugResolveMainClassRecord
5+
---@param classpath string[][]
6+
---@param java_exec string
7+
---@return JavaCoreDapLauncherConfig
8+
function M.get_dap_config(main, classpath, java_exec)
9+
local project_name = main.projectName
10+
local main_class = main.mainClass
11+
local module_paths = classpath[1]
12+
local class_paths = classpath[2]
13+
14+
return {
15+
request = 'launch',
16+
type = 'java',
17+
name = string.format('%s -> %s', project_name, main_class),
18+
projectName = project_name,
19+
mainClass = main_class,
20+
javaExec = java_exec,
21+
modulePaths = module_paths,
22+
classPaths = class_paths,
23+
}
24+
end
25+
26+
return M
Lines changed: 49 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
local log = require('java-core.utils.log')
2-
local adapters = require('java-core.ls.adapters.test-adapter')
2+
local adapters = require('java-core.dap.adapters')
33
local List = require('java-core.utils.list')
44
local JavaDebug = require('java-core.ls.clients.java-debug-client')
55
local Promise = require('java-core.utils.promise')
66

77
---@class JavaCoreDap
8-
---@field client LSPClient
8+
---@field client LspClient
99
---@field java_debug JavaCoreDebugClient
1010
local M = {}
1111

1212
---Returns a new dap instance
13-
---@param args { client: LSPClient }
13+
---@param args { client: LspClient }
1414
---@return JavaCoreDap
1515
function M:new(args)
1616
local o = {
@@ -26,18 +26,18 @@ function M:new(args)
2626
return o
2727
end
2828

29-
---@class JavaDapAdapter
29+
---@class JavaCoreDapAdapter
3030
---@field type string
3131
---@field host string
3232
---@field port integer
3333

3434
---Returns the dap adapter config
35-
---@return Promise
35+
---@return Promise # Promise<JavaCoreDapAdapter>
3636
function M:get_dap_adapter()
3737
log.info('creating dap adapter for java')
3838

3939
return self.java_debug:start_debug_session():thenCall(
40-
---@param port JavaDebugStartDebugSessionResponse
40+
---@param port integer
4141
function(port)
4242
return {
4343
type = 'server',
@@ -48,15 +48,13 @@ function M:get_dap_adapter()
4848
)
4949
end
5050

51-
---@alias JavaDapConfigurationList JavaDapConfiguration[]
52-
5351
---Returns the dap configuration for the current project
54-
---@return Promise
52+
---@return Promise # Promise<JavaDapConfiguration[]>
5553
function M:get_dap_config()
5654
log.info('creating dap configuration for java')
5755

5856
return self.java_debug:resolve_main_class():thenCall(
59-
---@param mains JavaDebugResolveMainClassResponse
57+
---@param mains JavaDebugResolveMainClassRecord[]
6058
function(mains)
6159
local config_promises = List:new(mains):map(function(main)
6260
return self:get_dap_config_record(main)
@@ -69,71 +67,58 @@ end
6967

7068
---Returns the dap config for the given main class
7169
---@param main JavaDebugResolveMainClassRecord
72-
---@return Promise
70+
---@return Promise # Promise<JavaCoreDapLauncherConfig>
7371
function M:get_dap_config_record(main)
7472
return Promise.all({
7573
self.java_debug:resolve_classpath(main.mainClass, main.projectName),
7674
self.java_debug:resolve_java_executable(main.mainClass, main.projectName),
7775
}):thenCall(function(res)
78-
---@type JavaDebugResolveClasspathResponse
76+
---@type string[][]
7977
local classpaths = res[1]
8078

81-
---@type JavaDebugResolveJavaExecutableResponse
79+
---@type string
8280
local java_exec = res[2]
8381

8482
return adapters.get_dap_config(main, classpaths, java_exec)
8583
end)
8684
end
8785

88-
---Dap run with given config
89-
---@param config JavaDapConfiguration
90-
function M.dap_run(config)
91-
log.info('running dap with config: ', config)
92-
93-
local function get_stream_reader(conn)
94-
return vim.schedule_wrap(function(err, buffer)
95-
assert(not err, err)
96-
97-
if buffer then
98-
vim.print(buffer)
99-
else
100-
conn:close()
101-
end
102-
end)
103-
end
104-
105-
---@type uv_tcp_t
106-
local server
107-
108-
require('dap').run(config --[[@as Configuration]], {
109-
before = function(conf)
110-
log.debug('running before dap callback')
111-
112-
server = assert(vim.loop.new_tcp(), 'uv.new_tcp() must return handle')
113-
server:bind('127.0.0.1', 0)
114-
server:listen(128, function(err)
115-
assert(not err, err)
116-
117-
local sock = assert(vim.loop.new_tcp(), 'uv.new_tcp must return handle')
118-
server:accept(sock)
119-
sock:read_start(get_stream_reader(sock))
120-
end)
121-
122-
conf.args =
123-
conf.args:gsub('-port ([0-9]+)', '-port ' .. server:getsockname().port)
124-
125-
return conf
126-
end,
127-
128-
after = function()
129-
vim.debug('running after dap callback')
130-
131-
if server then
132-
server:shutdown()
133-
server:close()
134-
end
135-
end,
136-
})
137-
end
138-
13986
return M
87+
88+
---@class JavaCoreDapLauncherConfigOverridable
89+
---@field name? string
90+
---@field type? string
91+
---@field request? string
92+
---@field mainClass? string
93+
---@field projectName? string
94+
---@field cwd? string
95+
---@field classPaths? string[]
96+
---@field modulePaths? string[]
97+
---@field vmArgs? string
98+
---@field noDebug? boolean
99+
---@field javaExec? string
100+
---@field args? string
101+
---@field env? { [string]: string; }
102+
---@field envFile? string
103+
---@field sourcePaths? string[]
104+
---@field preLaunchTask? string
105+
---@field postDebugTask? string
106+
107+
---@class JavaCoreDapLauncherConfig
108+
---@field name string
109+
---@field type string
110+
---@field request string
111+
---@field mainClass string
112+
---@field projectName string
113+
---@field cwd string
114+
---@field classPaths string[]
115+
---@field modulePaths string[]
116+
---@field vmArgs string
117+
---@field noDebug boolean
118+
---@field javaExec string
119+
---@field args string
120+
---@field env? { [string]: string; }
121+
---@field envFile? string
122+
---@field sourcePaths string[]
123+
---@field preLaunchTask? string
124+
---@field postDebugTask? string

0 commit comments

Comments
 (0)