129 lines
4.5 KiB
Python
129 lines
4.5 KiB
Python
import os
|
|
import sys
|
|
|
|
import tarfile
|
|
from urllib import request
|
|
|
|
from .lsp import LspServer, command, get_data_home
|
|
|
|
FILE_URI = "file://"
|
|
|
|
VERSION = "1.3.0"
|
|
DOWNLOADS_URI = "http://download.eclipse.org/jdtls/milestones/{version}/{file}"
|
|
LATEST = "latest.txt"
|
|
|
|
def locate_product_directory (jdt_ls_path):
|
|
if os.path.isdir(os.path.join(jdt_ls_path, "plugins")):
|
|
return jdt_ls_path
|
|
|
|
return os.path.join(jdt_ls_path, "org.eclipse.jdt.ls.product/target/repository")
|
|
|
|
def locate_launcher_jar (jdt_ls_path):
|
|
plugins_directory = os.path.join(jdt_ls_path, "plugins")
|
|
return os.path.join(plugins_directory, [jar for jar in os.listdir(plugins_directory) if jar.startswith("org.eclipse.equinox.launcher_")][0])
|
|
|
|
def locate_launcher_configuration (jdt_ls_path):
|
|
return os.path.join(jdt_ls_path, "config_linux")
|
|
|
|
def log (message, *args, **kwargs):
|
|
print(message.format(*args, **kwargs), file=sys.stderr)
|
|
|
|
def download_jdt_ls (version, destination):
|
|
if not os.path.isdir(destination):
|
|
os.makedirs(destination)
|
|
|
|
current_version = None
|
|
current_version_file = os.path.join(destination, LATEST)
|
|
if os.path.isfile(current_version_file):
|
|
with open(current_version_file) as f:
|
|
current_version = f.read().strip()
|
|
log("Currently downloaded version is {version}:", version=current_version)
|
|
|
|
latest_version = None
|
|
with request.urlopen(DOWNLOADS_URI.format(version=version, file=LATEST)) as f:
|
|
latest_version = f.read().decode().strip()
|
|
log("Latest available version is {version}:", version=latest_version)
|
|
|
|
if not latest_version == current_version:
|
|
latest_uri = DOWNLOADS_URI.format(version=version, file=latest_version)
|
|
log("Downloading latest version from: {uri}:", uri=latest_uri)
|
|
with request.urlopen(latest_uri) as f:
|
|
with tarfile.open(fileobj=f, mode="r|gz") as tar:
|
|
tar.extractall(destination)
|
|
print(tar)
|
|
|
|
with open(current_version_file, "w") as cvf:
|
|
cvf.write(latest_version)
|
|
|
|
return destination
|
|
|
|
# TODO
|
|
def locate_lombok ():
|
|
return os.path.join(os.environ['HOME'], ".m2/repository/org/projectlombok/lombok/1.18.16/lombok-1.18.16.jar")
|
|
|
|
def get_argument (arguments, arg_name):
|
|
if not arg_name in args:
|
|
return
|
|
|
|
value = arguments.pop(arguments.index(arg_name) + 1)
|
|
arguments.remove(arg_name)
|
|
return value
|
|
|
|
class Java(LspServer):
|
|
def __init__ (self, arguments):
|
|
self.path = arguments[0] if arguments else None
|
|
|
|
if self.path is None or not os.path.exists(self.path):
|
|
version = VERSION
|
|
|
|
if "--version" in arguments:
|
|
version = get_argument(arguments, "--version")
|
|
|
|
self.path = download_jdt_ls(version, os.path.join(get_data_home(), "java", "jdt.ls", version))
|
|
else:
|
|
self.path = locate_product_directory(self.path)
|
|
|
|
command = ["java"]
|
|
if "--enable-lombok" in arguments:
|
|
arguments.remove("--enable-lombok")
|
|
command.append(f"-javaagent:{locate_lombok()}")
|
|
|
|
data_directory = None
|
|
if "--data" in arguments:
|
|
data_directory = get_argument(arguments, "--data")
|
|
else:
|
|
data_directory = os.path.join(get_data_home(), "java", "data")
|
|
|
|
if "--enable-debugger" in arguments:
|
|
arguments.remove("--enable-debugger")
|
|
command.append("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044")
|
|
|
|
command = command + [
|
|
"-Declipse.application=org.eclipse.jdt.ls.core.id1",
|
|
"-Dosgi.bundles.defaultStartLevel=4",
|
|
"-Declipse.product=org.eclipse.jdt.ls.core.product",
|
|
"-noverify",
|
|
"-Xmx1G",
|
|
"-jar", locate_launcher_jar(self.path),
|
|
"-configuration", locate_launcher_configuration(self.path),
|
|
"-data", data_directory,
|
|
"--add-modules=ALL-SYSTEM",
|
|
"--add-opens", "java.base/java.util=ALL-UNNAMED",
|
|
"--add-opens", "java.base/java.lang=ALL-UNNAMED"
|
|
] + arguments[1:]
|
|
|
|
super().__init__(command)
|
|
|
|
@command("java.apply.workspaceEdit")
|
|
def workspaceEdit (self, arguments):
|
|
for argument in arguments:
|
|
self.send_to_client({
|
|
"id": -1,
|
|
"method": "workspace/applyEdit",
|
|
"params": {
|
|
"edit": {
|
|
"changes": argument['changes']
|
|
}
|
|
}
|
|
})
|