19 Commits
0.0.9 ... main

Author SHA1 Message Date
68843eac17 delimiter, not sep 2025-11-26 18:15:32 +01:00
2c4ff6e237 Update version 2025-11-26 18:14:27 +01:00
c9d878cf30 Fix path delimiter for windows 2025-11-26 18:12:53 +01:00
75943a8d95 Resolve file paths in emacs client 2025-11-12 13:24:26 +01:00
53e6d94180 README 2025-10-29 13:34:53 +01:00
d6db2d70e7 Move file 2025-10-22 11:41:30 +02:00
3bc2340a0c Add emacs mode and fix some incompatibilities 2025-10-22 11:40:32 +02:00
b691d6e0e3 Resolve path 2025-10-09 17:48:00 +02:00
6917c43c33 Specify compiler path in extension settings 2025-10-02 18:10:50 +02:00
Vic Nightfall
1a0596ca71 Version bump 2025-09-28 14:20:59 +02:00
RubenKraft
a9bbe834cc Update README.md 2025-09-24 14:43:07 +00:00
Ruben
4fbf9133a5 fix: bump version 2025-09-23 18:38:31 +02:00
Ruben
972d9014ba fix: bump version 2025-09-23 18:38:01 +02:00
Ruben
4f4404d366 fix: cleanup and fixes 2025-09-23 18:37:37 +02:00
Ruben
2dfbef6d7f fix: except VerifyError in Catch Clause 2025-09-23 18:26:58 +02:00
Ruben
7e6e968b0f feat: do not show 100 times the insert 2025-09-22 18:22:05 +02:00
Ruben
dded453ba3 feat: update jar and Version 2025-09-22 15:42:25 +02:00
Ruben
254edf25af feat: update jar and Version 2025-09-19 19:20:16 +02:00
RubenKraft
fc628f7547 Update README.md 2025-09-18 16:05:45 +00:00
17 changed files with 2738 additions and 770 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
"name": "java-tx-language-extension", "name": "java-tx-language-extension",
"displayName": "Java-TX Language Extension", "displayName": "Java-TX Language Extension",
"description": "The Language Extension for Java-TX with Typehints and Syntax Checks", "description": "The Language Extension for Java-TX with Typehints and Syntax Checks",
"version": "0.0.9", "version": "0.0.19",
"engines": { "engines": {
"vscode": "^1.94.0" "vscode": "^1.94.0"
}, },
@@ -20,6 +20,18 @@
"command": "tx.restartLanguageServer", "command": "tx.restartLanguageServer",
"title": "TX: Restart Language Server" "title": "TX: Restart Language Server"
} }
],
"configuration": [
{
"title": "JavaTX Language Server Plugin",
"properties": {
"tx.compilerLocation": {
"type": "string",
"format": "file",
"description": "JavaTX Compiler Location"
}
}
}
] ]
}, },
"scripts": { "scripts": {
@@ -42,6 +54,7 @@
"typescript": "^5.6.2" "typescript": "^5.6.2"
}, },
"dependencies": { "dependencies": {
"@vscode/vsce": "^3.6.1",
"vscode-languageclient": "^9.0.1" "vscode-languageclient": "^9.0.1"
} }
} }

View File

@@ -1,28 +1,67 @@
import path from 'path';
import os from "os";
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { import {
Executable,
LanguageClient, LanguageClient,
LanguageClientOptions, LanguageClientOptions,
ServerOptions ServerOptions
} from 'vscode-languageclient/node'; } from 'vscode-languageclient/node';
let homeDirectory: string;
let currentUser: string;
function untildify(pathWithTilde: string) {
if (homeDirectory === undefined) {
homeDirectory = os.homedir();
}
// Handle regular ~ expansion (current user)
if (homeDirectory && /^~(?=$|\/|\\)/.test(pathWithTilde)) {
return pathWithTilde.replace(/^~/, homeDirectory);
}
// Handle ~username expansion (only for current user)
const userMatch = pathWithTilde.match(/^~([^/\\]+)(.*)/);
if (userMatch) {
if (currentUser === undefined) {
currentUser = os.userInfo().username;
}
if (currentUser) {
const username = userMatch[1];
const rest = userMatch[2];
if (username === currentUser) {
return homeDirectory + rest;
}
}
}
// Return unchanged if no expansion occurred
return pathWithTilde;
}
let client: LanguageClient | undefined; // <— global, damit wir neu starten können let client: LanguageClient | undefined; // <— global, damit wir neu starten können
function createClient(context: vscode.ExtensionContext): LanguageClient { function createClient(context: vscode.ExtensionContext): LanguageClient | null {
const workspaceFolder = context.extensionPath; const workspaceFolder = context.extensionPath;
const config = vscode.workspace.getConfiguration("tx");
let compiler = config.get<string>("compilerLocation");
if (!compiler || compiler.trim() === "") {
vscode.window.showErrorMessage("Bitte konfiguriere den Pfad des Java-TX Compilers in den Einstellungen!");
return null;
}
compiler = path.resolve(untildify(compiler));
const cmd: Executable = {
command: 'java',
args: ['-Xss10m', '-cp', `${compiler}${path.delimiter}${workspaceFolder}/JavaTXLanguageServer-1.0-SNAPSHOT-jar-with-dependencies.jar`, "de.dhbw.JavaTXLanguageServerLauncher"],
};
const serverOptions: ServerOptions = { const serverOptions: ServerOptions = {
run: { run: cmd,
command: 'java', debug: cmd
args: ['-Xss10m', '-jar', workspaceFolder + "/JavaTXLanguageServer-1.0-SNAPSHOT-jar-with-dependencies.jar"],
},
debug: {
command: 'java',
args: [
'-Xss10m',
'-jar',
workspaceFolder + '/JavaTXLanguageServer-1.0-SNAPSHOT-jar-with-dependencies.jar',
],
}
}; };
const clientOptions: LanguageClientOptions = { const clientOptions: LanguageClientOptions = {
@@ -42,7 +81,9 @@ function createClient(context: vscode.ExtensionContext): LanguageClient {
} }
export async function activate(context: vscode.ExtensionContext) { export async function activate(context: vscode.ExtensionContext) {
client = createClient(context); const c = createClient(context);
if (!c) return;
client = c;
client.start() client.start()
.then(() => console.log("Language Client erfolgreich gestartet")) .then(() => console.log("Language Client erfolgreich gestartet"))
@@ -50,12 +91,6 @@ export async function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "tx" is now active!'); console.log('Congratulations, your extension "tx" is now active!');
// Beispiel-Command aus deinem Code bleibt
const hello = vscode.commands.registerCommand('lspclient.helloWorld', () => {
vscode.window.showInformationMessage('Hello World from TX!');
});
context.subscriptions.push(hello);
// *** NEU: Restart-Command *** // *** NEU: Restart-Command ***
const restart = vscode.commands.registerCommand('tx.restartLanguageServer', async () => { const restart = vscode.commands.registerCommand('tx.restartLanguageServer', async () => {
if (!client) { if (!client) {
@@ -68,7 +103,9 @@ export async function activate(context: vscode.ExtensionContext) {
} catch (e) { } catch (e) {
console.error('Fehler beim Stoppen des Language Clients:', e); console.error('Fehler beim Stoppen des Language Clients:', e);
} }
client = createClient(context); // komplett neu erzeugen const c = createClient(context); // komplett neu erzeugen
if (!c) return;
client = c;
try { try {
await client.start(); await client.start();
vscode.window.showInformationMessage('Java-TX Language Server neu gestartet.'); vscode.window.showInformationMessage('Java-TX Language Server neu gestartet.');

11
Clients/emacs/README.md Normal file
View File

@@ -0,0 +1,11 @@
## Install emacs plugin:
Edit your .emacs file and add the following:
```
(use-package javatx-mode
:custom
(javatx-compiler-path "$PATH_TO_COMPILER$")
(javatx-lsp-server-path "$PATH_TO_LSP$")
:load-path "~/.emacs.d/lisp")
```

View File

@@ -0,0 +1,84 @@
;;; javatx-mode.el --- Major mode for .jav files -*- lexical-binding: t; -*-
(defvar javatx-mode-hook nil
"Hook called when entering `javatx-mode`.")
;; Define the mode
(define-derived-mode javatx-mode java-mode "Javatx"
"Major mode for editing `.jav` files.")
;; Automatically use javatx-mode for .jav files
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.jav\\'" . javatx-mode))
(provide 'javatx-mode)
;;; javatx-mode.el ends here
;; Initialize package sources
(require 'package)
(setq package-archives
'(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")))
(package-initialize)
;; Refresh package contents if needed
(unless package-archive-contents
(package-refresh-contents))
;; Install use-package if not installed
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t) ;; automatically install packages if missing
(use-package lsp-mode
:hook (prog-mode . lsp)
:commands lsp
:config
(setq lsp-prefer-flymake nil)) ;; use flycheck instead of flymake
(use-package lsp-ui
:commands lsp-ui-mode
:hook (lsp-mode . lsp-ui-mode)
:config
(setq lsp-ui-sideline-show-hover t
lsp-ui-sideline-show-code-actions t
lsp-ui-sideline-show-diagnostics t))
(defcustom javatx-compiler-path nil
"Path to the JavaTX Compiler jar."
:type 'string
:group 'javatx)
(defcustom javatx-lsp-server-path nil
"Path to the JavaTX Language Server jar."
:type 'string
:group 'javatx)
;;register javatx-mode lsp
(with-eval-after-load 'lsp-mode
(message "Compiler path: %s" javatx-compiler-path)
(message "Server path: %s" javatx-lsp-server-path)
(add-to-list 'lsp-language-id-configuration '(javatx-mode . "Java-TX"))
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection (lambda () `("java" "-cp" ,(format "%s:%s" (expand-file-name javatx-compiler-path) (expand-file-name javatx-lsp-server-path)) "de.dhbw.JavaTXLanguageServerLauncher")))
:major-modes '(javatx-mode)
:server-id 'javatx-lsp-proxy)))
(add-hook 'javatx-mode-hook #'lsp) ;; start LSP automatically for .jav files
;; Automatically enable inlay hints for javatx-mode
(add-hook 'javatx-mode-hook
(lambda ()
;; Replace 'lsp-inlay-hints-mode' with whatever inlay hints function you use
(when (fboundp 'lsp-inlay-hints-mode)
(lsp-inlay-hints-mode 1))))
(setq lsp-log-io t) ;; enable logging of LSP messages
(with-eval-after-load 'lsp-mode
(define-key lsp-mode-map (kbd "C-c a") 'lsp-execute-code-action))

View File

@@ -14,61 +14,17 @@
<version>4.11</version> <version>4.11</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
<version>4.11.1</version>
</dependency>
<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.12</version>
</dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>log4j</groupId>
<artifactId>log4j</artifactId> <artifactId>log4j</artifactId>
<version>1.2.17</version> <version>1.2.17</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>5.10.0</version> <version>5.14.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>4.8.172</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.0-jre</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>9.5</version>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.lsp4j</groupId> <groupId>org.eclipse.lsp4j</groupId>
<artifactId>org.eclipse.lsp4j</artifactId> <artifactId>org.eclipse.lsp4j</artifactId>
@@ -78,6 +34,7 @@
<groupId>de.dhbwstuttgart</groupId> <groupId>de.dhbwstuttgart</groupId>
<artifactId>JavaTXcompiler</artifactId> <artifactId>JavaTXcompiler</artifactId>
<version>0.1</version> <version>0.1</version>
<scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<properties> <properties>

View File

@@ -17,6 +17,7 @@ import java.util.concurrent.CompletableFuture;
* */ * */
public class JavaTXLanguageServer implements LanguageServer { public class JavaTXLanguageServer implements LanguageServer {
private static final Logger logger = LogManager.getLogger(JavaTXLanguageServer.class); private static final Logger logger = LogManager.getLogger(JavaTXLanguageServer.class);
public static ClientCapabilities capabilities;
private LanguageClient client; private LanguageClient client;
public void connect(LanguageClient client) { public void connect(LanguageClient client) {
@@ -48,6 +49,7 @@ public class JavaTXLanguageServer implements LanguageServer {
if(params.getWorkspaceFolders() != null && !params.getWorkspaceFolders().isEmpty()) { if(params.getWorkspaceFolders() != null && !params.getWorkspaceFolders().isEmpty()) {
textDocumentService.setFileRoot(params.getWorkspaceFolders()); textDocumentService.setFileRoot(params.getWorkspaceFolders());
} }
JavaTXLanguageServer.capabilities = params.getCapabilities();
return CompletableFuture.supplyAsync(() -> new InitializeResult(capabilities)); return CompletableFuture.supplyAsync(() -> new InitializeResult(capabilities));
} }

View File

@@ -113,8 +113,7 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
if (!syntaxErrors.isEmpty()) { if (!syntaxErrors.isEmpty()) {
clientService.publishDiagnostics(params.getTextDocument().getUri(), syntaxErrors); clientService.publishDiagnostics(params.getTextDocument().getUri(), syntaxErrors);
} }
client.refreshDiagnostics(); clientService.updateClient();
client.refreshInlayHints();
textDocuments.put(params.getTextDocument().getUri(), params.getTextDocument().getText()); textDocuments.put(params.getTextDocument().getUri(), params.getTextDocument().getText());
textDocumentService.saveFileWithUri(params.getTextDocument().getUri(), params.getTextDocument().getText()); textDocumentService.saveFileWithUri(params.getTextDocument().getUri(), params.getTextDocument().getText());
} }
@@ -154,10 +153,10 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
@Override @Override
public void didSave(DidSaveTextDocumentParams didSaveTextDocumentParams) { public void didSave(DidSaveTextDocumentParams didSaveTextDocumentParams) {
logService.log("[didSave] Client triggered didSave-Event."); logService.log("[didSave] Client triggered didSave-Event.");
clientService.startLoading("compile-task", "Inferring types...", client); clientService.startLoading("compile-task", "Inferring types...");
saveHandler.handleSave(didSaveTextDocumentParams); saveHandler.handleSave(didSaveTextDocumentParams);
clientService.stopLoading("compile-task", "Types successfully inferred", client); clientService.stopLoading("compile-task", "Types successfully inferred");
clientService.updateClient(client); clientService.updateClient();
} }
@Override @Override
@@ -298,7 +297,9 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
logService.log("[codeAction] Client requested Insert at Line [" + params.getRange().getStart().getLine() + "] and from Char [" + params.getRange().getStart().getCharacter() + "] to [" + params.getRange().getEnd().getCharacter() + "].", MessageType.Info); logService.log("[codeAction] Client requested Insert at Line [" + params.getRange().getStart().getLine() + "] and from Char [" + params.getRange().getStart().getCharacter() + "] to [" + params.getRange().getEnd().getCharacter() + "].", MessageType.Info);
logService.log("Code-Action Context was: " + params.getContext().getTriggerKind().name(), MessageType.Info); var triggerKind = params.getContext().getTriggerKind();
if (triggerKind != null)
logService.log("Code-Action Context was: " + triggerKind.name(), MessageType.Info);
return CompletableFuture.supplyAsync(() -> { return CompletableFuture.supplyAsync(() -> {
return codeActionHandler.handleNewCodeAction(params); return codeActionHandler.handleNewCodeAction(params);

View File

@@ -13,6 +13,8 @@ import org.eclipse.lsp4j.*;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.net.URI;
import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@@ -78,6 +80,8 @@ public class ChangeHandler {
if (!syntaxErrors.isEmpty()) { if (!syntaxErrors.isEmpty()) {
clientService.publishDiagnostics(params.getTextDocument().getUri(), syntaxErrors); clientService.publishDiagnostics(params.getTextDocument().getUri(), syntaxErrors);
}else {
clientService.updateClient();
} }
logService.log("Found [" + syntaxErrors.size() + "] Syntax Errors in Document."); logService.log("Found [" + syntaxErrors.size() + "] Syntax Errors in Document.");
@@ -93,7 +97,7 @@ public class ChangeHandler {
logService.log("Type is here: " + type); logService.log("Type is here: " + type);
for (LSPVariable variable : cacheService.getVariables()) { for (LSPVariable variable : cacheService.getVariables()) {
for (Type variableType : variable.getPossibleTypes()) { for (Type variableType : variable.getPossibleTypes()) {
logService.log(variableType.getType() + " <> "+ type.replaceAll(" ", "") + ": " + type.replaceAll(" ", "").contains(variableType.getType().replaceAll(" ", ""))); logService.log(variableType.getType() + " <> " + type.replaceAll(" ", "") + ": " + type.replaceAll(" ", "").contains(variableType.getType().replaceAll(" ", "")));
shouldCalculate = shouldCalculate || type.replaceAll(" ", "").contains(variableType.getType().replaceAll(" ", "")); shouldCalculate = shouldCalculate || type.replaceAll(" ", "").contains(variableType.getType().replaceAll(" ", ""));
if (shouldCalculate) { if (shouldCalculate) {
break; break;
@@ -154,14 +158,15 @@ public class ChangeHandler {
try { try {
try { try {
File tempDir2 = new File(System.getProperty("java.io.tmpdir")); File tempDir2 = Path.of(new URI(params.getTextDocument().getUri())).getParent().toFile();
File tempFile2 = File.createTempFile("newText", ".tmp", tempDir2); File tempFile2 = File.createTempFile("jtx_temp", ".tmp", tempDir2);
FileWriter fileWriter = new FileWriter(tempFile2, true); FileWriter fileWriter = new FileWriter(tempFile2, true);
BufferedWriter bw = new BufferedWriter(fileWriter); BufferedWriter bw = new BufferedWriter(fileWriter);
bw.write(input); bw.write(input);
bw.close(); bw.close();
ArrayList<LSPVariable> variables = typeResolver.infereInput(tempFile2.toURI().toString(), input, false); try {
ArrayList<LSPVariable> variables = typeResolver.infereInput(tempFile2.toURI().toString(), input);
cacheService.setVariables(variables); cacheService.setVariables(variables);
DiagnosticsAndTypehints diagnosticsAndTypehints = conversionHelper.variablesToDiagnosticsAndTypehintsWithInput(variables, input); DiagnosticsAndTypehints diagnosticsAndTypehints = conversionHelper.variablesToDiagnosticsAndTypehintsWithInput(variables, input);
@@ -172,17 +177,20 @@ public class ChangeHandler {
cacheService.updateGlobalMaps(diagnostics, typeHint, params.getTextDocument().getUri()); cacheService.updateGlobalMaps(diagnostics, typeHint, params.getTextDocument().getUri());
List<Diagnostic> allDiagnostics = new ArrayList<>(diagnostics); List<Diagnostic> allDiagnostics = new ArrayList<>(diagnostics);
allDiagnostics.addAll(parserService.getDiagnosticsOfErrors(input, params.getTextDocument().getUri()));
clientService.publishDiagnostics(params.getTextDocument().getUri(), allDiagnostics); clientService.publishDiagnostics(params.getTextDocument().getUri(), allDiagnostics);
} catch (Exception | VerifyError f) {
logService.log("[didSave] Error trying to get Inlay-Hints and Diagnostics for Client: " + f.getMessage(), MessageType.Error);
for (StackTraceElement elem : f.getStackTrace()) {
logService.log(elem.toString());
}
clientService.showMessage(MessageType.Error, f.getMessage() == null ? "null" : f.getMessage());
cacheService.updateGlobalMaps(new ArrayList<>(), new ArrayList<>(), params.getTextDocument().getUri());
}
tempFile2.delete(); tempFile2.delete();
} catch (Exception e) { } catch (Exception e) {
logService.log("[didSave] Error trying to get Inlay-Hints and Diagnostics for Client: " + e.getMessage(), MessageType.Error); logService.log("[didSave] Error trying to get Inlay-Hints and Diagnostics for Client: " + e.getMessage(), MessageType.Error);
for (StackTraceElement elem : e.getStackTrace()) {
logService.log(elem.toString());
}
clientService.showMessage(MessageType.Error, e.getMessage() == null ? "null" : e.getMessage()); clientService.showMessage(MessageType.Error, e.getMessage() == null ? "null" : e.getMessage());
cacheService.updateGlobalMaps(new ArrayList<>(), new ArrayList<>(), params.getTextDocument().getUri()); cacheService.updateGlobalMaps(new ArrayList<>(), new ArrayList<>(), params.getTextDocument().getUri());

View File

@@ -105,6 +105,7 @@ public class CodeActionHandler {
String documentUri = params.getTextDocument().getUri(); String documentUri = params.getTextDocument().getUri();
Range rangeOfInsert = params.getRange(); Range rangeOfInsert = params.getRange();
if (typeResolver.getInserts() != null) {
//All Diagnostics that are in range of the hover -> All Diagnostics of the selected Variable and thus all Types of the Variable //All Diagnostics that are in range of the hover -> All Diagnostics of the selected Variable and thus all Types of the Variable
Map<String, List<PlaceholderVariable>> typeInsertsOverlapping = getOverlapping(typeResolver.getInserts(), rangeOfInsert.getStart().getLine() + 1, rangeOfInsert.getStart().getCharacter(), rangeOfInsert.getEnd().getCharacter()); Map<String, List<PlaceholderVariable>> typeInsertsOverlapping = getOverlapping(typeResolver.getInserts(), rangeOfInsert.getStart().getLine() + 1, rangeOfInsert.getStart().getCharacter(), rangeOfInsert.getEnd().getCharacter());
logService.log("Inserts are:"); logService.log("Inserts are:");
@@ -135,7 +136,10 @@ public class CodeActionHandler {
CodeAction action = new CodeAction("Insert " + conversionHelper.cleanType(typeInsert.getInsertString())); CodeAction action = new CodeAction("Insert " + conversionHelper.cleanType(typeInsert.getInsertString()));
action.setKind(CodeActionKind.QuickFix); action.setKind(CodeActionKind.QuickFix);
action.setEdit(edit); action.setEdit(edit);
if(!actions.stream().map(el -> el.getRight().getTitle()).toList().contains(action.getTitle())){
actions.add(Either.forRight(action)); actions.add(Either.forRight(action));
}
} catch (Exception e) { } catch (Exception e) {
logService.log("Error creating Actions, returning empty List. The Error was: " + e.getMessage(), MessageType.Error); logService.log("Error creating Actions, returning empty List. The Error was: " + e.getMessage(), MessageType.Error);
} }
@@ -144,6 +148,9 @@ public class CodeActionHandler {
return actions; return actions;
} }
return new ArrayList<>();
}
public List<Either<Command, CodeAction>> handleCodeAction(CodeActionParams params) { public List<Either<Command, CodeAction>> handleCodeAction(CodeActionParams params) {
String documentUri = params.getTextDocument().getUri(); String documentUri = params.getTextDocument().getUri();

View File

@@ -1,6 +1,7 @@
package de.dhbw.handler; package de.dhbw.handler;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import com.google.common.base.Verify;
import de.dhbw.model.DiagnosticsAndTypehints; import de.dhbw.model.DiagnosticsAndTypehints;
import de.dhbw.service.*; import de.dhbw.service.*;
import de.dhbw.helper.ConversionHelper; import de.dhbw.helper.ConversionHelper;
@@ -51,19 +52,20 @@ public class SaveHandler {
List<Diagnostic> syntaxErrors = parserService.getDiagnosticsOfErrors(fileInput, didSaveTextDocumentParams.getTextDocument().getUri()); List<Diagnostic> syntaxErrors = parserService.getDiagnosticsOfErrors(fileInput, didSaveTextDocumentParams.getTextDocument().getUri());
if (!syntaxErrors.isEmpty()) { if (!syntaxErrors.isEmpty()) {
clientService.publishDiagnostics(didSaveTextDocumentParams.getTextDocument().getUri(), syntaxErrors); clientService.publishDiagnostics(didSaveTextDocumentParams.getTextDocument().getUri(), syntaxErrors);
}else {
clientService.updateClient();
} }
logService.log("Found [" + syntaxErrors.size() + "] Syntax Errors in Document."); logService.log("Found [" + syntaxErrors.size() + "] Syntax Errors in Document.");
if (syntaxErrors.isEmpty()) { if (syntaxErrors.isEmpty()) {
cacheService.getLastSavedFiles().put(didSaveTextDocumentParams.getTextDocument().getUri(), fileInput); cacheService.getLastSavedFiles().put(didSaveTextDocumentParams.getTextDocument().getUri(), fileInput);
//typeResolver.getCompilerInput(didSaveTextDocumentParams.getTextDocument().getUri(), fileInput);
if (fileInput == null) { if (fileInput == null) {
logService.log("[didSave] Input of Text Document is null in TextDocument-Hashmap.", MessageType.Error); logService.log("[didSave] Input of Text Document is null in TextDocument-Hashmap.", MessageType.Error);
} }
ArrayList<LSPVariable> variables = typeResolver.infereInput(didSaveTextDocumentParams.getTextDocument().getUri(), fileInput, false); ArrayList<LSPVariable> variables = typeResolver.infereInput(didSaveTextDocumentParams.getTextDocument().getUri(), fileInput);
cacheService.setVariables(variables); cacheService.setVariables(variables);
DiagnosticsAndTypehints diagnosticsAndTypehints = conversionHelper.variablesToDiagnosticsAndTypehints(variables, didSaveTextDocumentParams.getTextDocument().getUri()); DiagnosticsAndTypehints diagnosticsAndTypehints = conversionHelper.variablesToDiagnosticsAndTypehints(variables, didSaveTextDocumentParams.getTextDocument().getUri());
@@ -79,16 +81,13 @@ public class SaveHandler {
} }
} catch (Exception e) { } catch (Exception | VerifyError e) {
logService.log("[didSave] Error trying to get Inlay-Hints and Diagnostics for Client: " + e.getMessage(), MessageType.Error); logService.log("[didSave] Error trying to get Inlay-Hints and Diagnostics for Client: " + e.getMessage(), MessageType.Error);
for (StackTraceElement elem : e.getStackTrace()) {
logService.log(elem.toString());
}
clientService.showMessage(MessageType.Error, e.getMessage() == null ? "null" : e.getMessage()); clientService.showMessage(MessageType.Error, e.getMessage() == null ? "null" : e.getMessage());
cacheService.updateGlobalMaps(new ArrayList<>(), new ArrayList<>(), didSaveTextDocumentParams.getTextDocument().getUri()); cacheService.updateGlobalMaps(new ArrayList<>(), new ArrayList<>(), didSaveTextDocumentParams.getTextDocument().getUri());
}
} finally { finally {
sWatch.stop(); sWatch.stop();
logService.log("[didSave] Finished Calculating in [" + sWatch.elapsed().toSeconds() + "s]", MessageType.Info); logService.log("[didSave] Finished Calculating in [" + sWatch.elapsed().toSeconds() + "s]", MessageType.Info);
} }

View File

@@ -140,7 +140,7 @@ public class TypeResolver {
return variables; return variables;
} }
public ArrayList<LSPVariable> infereInput(String pathString, String input, boolean a) throws IOException, ClassNotFoundException, URISyntaxException { public ArrayList<LSPVariable> infereInput(String pathString, String input) throws IOException, ClassNotFoundException, URISyntaxException {
System.setOut(new PrintStream(OutputStream.nullOutputStream())); System.setOut(new PrintStream(OutputStream.nullOutputStream()));
LanguageServerInterface languageServerInterface = new LanguageServerInterface(); LanguageServerInterface languageServerInterface = new LanguageServerInterface();

View File

@@ -42,6 +42,11 @@ public class PlaceholderPoint {
return point.getStartIndex() + extraOffset; return point.getStartIndex() + extraOffset;
} }
public PlaceholderType getKind() {
return kind;
}
public boolean equals(Object obj) { public boolean equals(Object obj) {
return this == obj; return this == obj;
/* /*

View File

@@ -13,7 +13,6 @@ public class PlaceholderVariable {
ResultPair<?, ?> resultPair; ResultPair<?, ?> resultPair;
public PlaceholderVariable(PlaceholderPoint point, Set<PlaceholderPoint> additionalPoints, ResultPair<?, ?> resultPair) { public PlaceholderVariable(PlaceholderPoint point, Set<PlaceholderPoint> additionalPoints, ResultPair<?, ?> resultPair) {
this.point = point; this.point = point;
inserts = additionalPoints; inserts = additionalPoints;
@@ -26,7 +25,10 @@ public class PlaceholderVariable {
List<PlaceholderPoint> insertsSorted = new ArrayList<>(); List<PlaceholderPoint> insertsSorted = new ArrayList<>();
insertsSorted.add(point); insertsSorted.add(point);
if (!point.getInsertString().contains("void")) {
insertsSorted.addAll(inserts); insertsSorted.addAll(inserts);
}
Collections.sort(insertsSorted, new PlaceholderPoint.TypeInsertPointPositionComparator().reversed()); Collections.sort(insertsSorted, new PlaceholderPoint.TypeInsertPointPositionComparator().reversed());
for (PlaceholderPoint insertPoint : insertsSorted) { for (PlaceholderPoint insertPoint : insertsSorted) {
@@ -40,7 +42,8 @@ public class PlaceholderVariable {
return point.getInsertString(); return point.getInsertString();
} }
public void reducePackage(){point.setInsertString(point.getInsertString().replaceAll("java\\.lang\\.", "").replaceAll("java\\.util\\.", "")); public void reducePackage() {
point.setInsertString(point.getInsertString().replaceAll("java\\.lang\\.", "").replaceAll("java\\.util\\.", ""));
} }
public ResultPair<?, ?> getResultPair() { public ResultPair<?, ?> getResultPair() {

View File

@@ -3,8 +3,12 @@ package de.dhbw.service;
import org.eclipse.lsp4j.*; import org.eclipse.lsp4j.*;
import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.lsp4j.services.LanguageClient; import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageServer;
import de.dhbw.JavaTXLanguageServer;
import java.util.List; import java.util.List;
import java.util.Map;
public class ClientService { public class ClientService {
@@ -39,13 +43,10 @@ public class ClientService {
this.client = client; this.client = client;
} }
public void updateClient(LanguageClient client) {
client.refreshInlayHints();
client.refreshDiagnostics();
}
public void updateClient() { public void updateClient() {
if (JavaTXLanguageServer.capabilities.getWorkspace().getInlayHint() != null)
client.refreshInlayHints(); client.refreshInlayHints();
if (JavaTXLanguageServer.capabilities.getWorkspace().getDiagnostics() != null)
client.refreshDiagnostics(); client.refreshDiagnostics();
} }
@@ -53,7 +54,7 @@ public class ClientService {
return client; return client;
} }
public void startLoading(String taskName, String title, LanguageClient client) { public void startLoading(String taskName, String title) {
Either<String, Integer> token = Either.forLeft(taskName); Either<String, Integer> token = Either.forLeft(taskName);
client.createProgress(new WorkDoneProgressCreateParams(token)); client.createProgress(new WorkDoneProgressCreateParams(token));
@@ -67,7 +68,7 @@ public class ClientService {
} }
public void stopLoading(String taskName, String title, LanguageClient client) { public void stopLoading(String taskName, String title) {
Either<String, Integer> token = Either.forLeft(taskName); Either<String, Integer> token = Either.forLeft(taskName);
WorkDoneProgressEnd end = new WorkDoneProgressEnd(); WorkDoneProgressEnd end = new WorkDoneProgressEnd();
end.setMessage(title); end.setMessage(title);

View File

@@ -55,11 +55,16 @@ The Language Server in itself can be used for any Client. The Clients task is to
![Diagram](docs/diagram.png) ![Diagram](docs/diagram.png)
## Additional Information
- Uses the [LSP-Interface](https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore/src/branch/LSP-Interface) Branch of the Java-TX Compiler Repository
## Update JavaTX Compiler Dependency as Maven Package ## Update JavaTX Compiler Dependency as Maven Package
If you make changes in the Compiler Interface, you have to change the jar and therefore the Dependency in the Java TX Language Server If you make changes in the Compiler Interface, you have to change the jar and therefore the Dependency in the Java TX Language Server
You can follow this steps: You can follow this steps:
1. package the JavaTX Compiler 1. package the JavaTX Compiler
2. take the Jar-File and copy it into the /lib Folder 2. create a lib Folder at ./LangaugeServer -> ./LanguageServer/lib
2. take the Jar-File and copy it into the /lib Folder at
3. execute this Maven command to add the Jar in your local Repository: ```mvn install:install-file -Dfile=lib/JavaTXcompiler-0.1-jar-with-dependencies.jar -DgroupId=de.dhbwstuttgart -DartifactId=JavaTXcompiler -Dversion=0.1 -Dpackaging=jar``` 3. execute this Maven command to add the Jar in your local Repository: ```mvn install:install-file -Dfile=lib/JavaTXcompiler-0.1-jar-with-dependencies.jar -DgroupId=de.dhbwstuttgart -DartifactId=JavaTXcompiler -Dversion=0.1 -Dpackaging=jar```
4. run ```maven clean```, ```validate``` and ```install``` to load the new Dependency 4. run ```maven clean```, ```validate``` and ```install``` to load the new Dependency
5. you can now package the Language Server or change the code accordingly. 5. you can now package the Language Server or change the code accordingly.