aboutsummaryrefslogtreecommitdiff
path: root/Common/nvim/lsp/jdt-language-server/bin/jdtls.py
blob: 43e098097c6c91891fdcbc55e5ff195bd47613a2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
###############################################################################
# Copyright (c) 2022 Marc Schreiber and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Marc Schreiber - initial API and implementation
###############################################################################
import argparse
import os
import platform
import re
import subprocess
from pathlib import Path

def get_java_executable(validate_java_version):
	java_executable = 'java'

	if 'JAVA_HOME' in os.environ:
		java_exec_to_test = Path(os.environ['JAVA_HOME']) / 'bin' / 'java'
		if java_exec_to_test.is_file():
			java_executable = java_exec_to_test.resolve()

	if not validate_java_version:
		return java_executable

	out = subprocess.check_output([java_executable, '-version'], stderr = subprocess.STDOUT, universal_newlines=True)

	matches = re.finditer(r"(?P<major>\d+)\.\d+\.\d+", out)
	for match in matches:
		java_major_version = int(match.group("major"))

		if java_major_version < 11:
			raise Exception("jdtls requires at least Java 11")

		return java_executable

	raise Exception("Could not determine Java version")

def find_equinox_launcher(jdtls_base_directory):
	plugins_dir = jdtls_base_directory / "plugins"
	launchers = plugins_dir.glob('org.eclipse.equinox.launcher_*.jar')
	for launcher in launchers:
		return plugins_dir / launcher

	raise Exception("Cannot find equinox launcher")

def get_shared_config_path(jdtls_base_path):
	system = platform.system()

	if system == 'Linux':
		config_dir = 'config_linux'
	elif system == 'Darwin':
		config_dir = 'config_mac'
	elif system == 'Windows':
		config_dir = 'config_win'
	else:
		raise Exception("Unknown platform {} detected".format(platform))

	return jdtls_base_path / config_dir

def main(args):
	parser = argparse.ArgumentParser()
	parser.add_argument("--validate-java-version", default=True, action=argparse.BooleanOptionalAction)
	parser.add_argument("--jvm-arg",
			default=[],
			action="append",
			help="An additional JVM option (can be used multiple times. Note, use with equal sign. For example: --jvm-arg=-Dlog.level=ALL")

	known_args, args = parser.parse_known_args(args)
	java_executable = get_java_executable(known_args.validate_java_version)

	jdtls_base_path = Path(__file__).parent.parent
	shared_config_path = get_shared_config_path(jdtls_base_path)
	jar_path = find_equinox_launcher(jdtls_base_path)

	os.system(("{java_exec}"
		" -Declipse.application=org.eclipse.jdt.ls.core.id1"
		" -Dosgi.bundles.defaultStartLevel=4"
		" -Declipse.product=org.eclipse.jdt.ls.core.product"
		" -Dosgi.checkConfiguration=true"
		" -Dosgi.sharedConfiguration.area='{shared_config_path}'"
		" -Dosgi.sharedConfiguration.area.readOnly=true"
		" -Dosgi.configuration.cascaded=true"
		" -noverify"
		" -Xms1G"
		" --add-modules=ALL-SYSTEM"
		" --add-opens java.base/java.util=ALL-UNNAMED"
		" --add-opens java.base/java.lang=ALL-UNNAMED"
		" {jvm_options}"
		" -jar '{jar_path}'"
		" {args}").format(
			java_exec = java_executable,
			shared_config_path = shared_config_path,
			jar_path = jar_path,
			jvm_options = " ".join(f"'{w}'" for w in known_args.jvm_arg),
			args = " ".join(f"'{w}'" for w in args)))