13 Commits

15 changed files with 395 additions and 154 deletions

View File

@@ -9,3 +9,7 @@ vsc-extension-quickstart.md
**/*.map
**/*.ts
**/.vscode-test.*
!JavaTXLanguageServer-1.0-SNAPSHOT-jar-with-dependencies.jar
!JavaTXLanguageServer-1.0-SNAPSHOT-jar-with-dependencies.jar

View File

@@ -1,71 +1,3 @@
# lspclient README
This is the README for your extension "lspclient". After writing up a brief description, we recommend including the following sections.
## Features
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file.
For example if there is an image subfolder under your extension project workspace:
\!\[feature X\]\(images/feature-x.png\)
> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow.
## Requirements
If you have any requirements or dependencies, add a section describing those and how to install and configure them.
## Extension Settings
Include if your extension adds any VS Code settings through the `contributes.configuration` extension point.
For example:
This extension contributes the following settings:
* `myExtension.enable`: Enable/disable this extension.
* `myExtension.thing`: Set to `blah` to do something.
## Known Issues
Calling out known issues can help limit users opening duplicate issues against your extension.
## Release Notes
Users appreciate release notes as you update your extension.
### 1.0.0
Initial release of ...
### 1.0.1
Fixed issue #.
### 1.1.0
Added features X, Y, and Z.
---
## Following extension guidelines
Ensure that you've read through the extensions guidelines and follow the best practices for creating your extension.
* [Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines)
## Working with Markdown
You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts:
* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux).
* Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux).
* Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets.
## For more information
* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown)
* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/)
**Enjoy!**
This is the README for the Java-TX LSP Client.

View File

@@ -1,12 +1,12 @@
{
"name": "lspclient",
"version": "0.0.1",
"version": "0.0.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "lspclient",
"version": "0.0.1",
"version": "0.0.2",
"dependencies": {
"vscode-languageclient": "^9.0.1"
},

View File

@@ -42,10 +42,11 @@ export function activate(context: vscode.ExtensionContext) {
revealOutputChannelOn: 4
};
// Language Client erstellen und starten
const client = new LanguageClient(
'javaLanguageServer', // ID des Clients
'Java Language Server', // Name des Clients
'javaTxLanguageServer', // ID des Clients
'Java-TX Language Server', // Name des Clients
serverOptions,
clientOptions
);

View File

@@ -5,6 +5,7 @@ import de.dhbw.helper.CodeSnippetOptions;
import de.dhbw.helper.TextHelper;
import de.dhbw.helper.TypeResolver;
import de.dhbw.model.LSPVariable;
import de.dhbw.model.LineCharPosition;
import de.dhbw.model.SnippetWithName;
import de.dhbw.model.Type;
import de.dhbwstuttgart.languageServerInterface.LanguageServerInterface;
@@ -14,6 +15,7 @@ import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.eclipse.lsp4j.*;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.lsp4j.jsonrpc.messages.Message;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.TextDocumentService;
@@ -26,6 +28,7 @@ import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -42,8 +45,11 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
HashMap<String, String> textDocuments = new HashMap<>();
CodeSnippetOptions codeSnippetOptions = new CodeSnippetOptions();
TextHelper textHelper = new TextHelper();
Boolean dontShowHints = false;
TypeResolver typeResolver = new TypeResolver();
Path fileRoot = null;
Boolean singleFileOpened = false;
List<LSPVariable> variables = new ArrayList<>();
public void setClient(LanguageClient client) {
this.client = client;
@@ -51,6 +57,9 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
public void setFileRoot(List<WorkspaceFolder> root) {
if (root == null) {
singleFileOpened = true;
}
//TODO: Nicht nur das erste Element nehmen sondern alle beachten
fileRoot = Path.of(URI.create(root.get(0).getUri()));
}
@@ -91,6 +100,68 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
textDocuments.put(params.getTextDocument().getUri(), params.getTextDocument().getText());
}
public ArrayList<String> difference(String first, String second) {
ArrayList<String> result = new ArrayList<>();
int i = 0, j = 0;
int startDiff = -1;
while (j < second.length()) {
if (i < first.length() && first.charAt(i) == second.charAt(j)) {
if (startDiff != -1) {
result.add(second.substring(startDiff, j));
startDiff = -1;
}
i++;
j++;
} else {
if (startDiff == -1) {
startDiff = j;
}
j++;
}
}
if (startDiff != -1) {
result.add(second.substring(startDiff));
}
return result;
}
public Map<LineCharPosition, String> differenceLinePos(String first, String second, int line) {
Map<LineCharPosition, String> result = new HashMap<>();
int i = 0, j = 0;
int startDiff = -1;
while (j < second.length()) {
if (i < first.length() && first.charAt(i) == second.charAt(j)) {
if (startDiff != -1) {
String diff = second.substring(startDiff, j);
result.put(new LineCharPosition(line, startDiff), diff);
startDiff = -1;
}
i++;
j++;
} else {
if (startDiff == -1) {
startDiff = j;
}
j++;
}
}
if (startDiff != -1) {
String diff = second.substring(startDiff);
result.put(new LineCharPosition(line, startDiff), diff);
}
return result;
}
/**
* Handles didChange-Event.
* updates textDocument-State on Server and run Syntax-Check. If an Error is found it will get displayed as a Diagnostic.
@@ -101,6 +172,35 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
public void didChange(DidChangeTextDocumentParams params) {
log("[didChange] Client triggered didChange Event.", MessageType.Info);
//TODO: Regenerate if Line-Count does not match -> Return new AST and see where the Positions are instead of calculating them from changes in Text-Document. Even possible?
String currentText = textDocuments.get(params.getTextDocument().getUri());
ArrayList<String> currentTextLines = new ArrayList<>(Arrays.stream(currentText.split("\n")).toList());
HashMap<LineCharPosition, String> preciseChanges = new HashMap<>();
String newText = params.getContentChanges().getFirst().getText();
ArrayList<String> newTextLines = new ArrayList<>(Arrays.stream(newText.split("\n")).toList());
ArrayList<Integer> offsetPerLine = new ArrayList<>();
HashMap<Integer, List<String>> textChanges = new HashMap<>();
int index = 0;
for (String newTextLine : newTextLines) {
if (!(currentTextLines.size() > index)) {
offsetPerLine.add(0);
} else {
Map<LineCharPosition, String> lineDiffs = differenceLinePos(currentTextLines.get(index), newTextLine, index);
preciseChanges.putAll(lineDiffs);
textChanges.put(index, difference(currentTextLines.get(index), newTextLine).stream().map(el -> el.replaceAll(" ", "")).toList());
offsetPerLine.add(newTextLine.length() - currentTextLines.get(index).length());
}
index++;
}
AtomicReference<String> summedUp = new AtomicReference<>("");
params.getContentChanges().forEach(el -> summedUp.set(summedUp.get() + el.getText()));
textDocuments.put(params.getTextDocument().getUri(), summedUp.get());
@@ -111,7 +211,7 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
List<ParserError> parserErrors = parserInterface.getParseErrors(input);
List<Diagnostic> diagnostics = parserErrors.stream().map(el -> {
List<Diagnostic> diagnosticsList = parserErrors.stream().map(el -> {
Range errorRange = new Range(
new Position(el.getLine() - 1, el.getCharPositionInLine()), // Startposition
new Position(el.getLine() - 1, el.getEndCharPosition()) // Endposition
@@ -125,9 +225,89 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
}).toList();
PublishDiagnosticsParams diagnosticsParams = new PublishDiagnosticsParams(params.getTextDocument().getUri(), diagnostics);
client.publishDiagnostics(diagnosticsParams);
// PublishDiagnosticsParams diagnosticsParams = new PublishDiagnosticsParams(params.getTextDocument().getUri(), diagnostics);
// client.publishDiagnostics(diagnosticsParams);
List<String> combinedList = new ArrayList<>();
for (List<String> list : textChanges.values()) {
combinedList.addAll(list);
}
typeResolver.reduceCurrent(preciseChanges, variables, client);
//Reduce and display Typehints and Diagnostics
if (!currentlyCalculating) {
currentlyCalculating = true;
ArrayList<Diagnostic> diagnostics = new ArrayList<>();
var sWatch = Stopwatch.createUnstarted();
sWatch.start();
try {
if (textDocuments.get(params.getTextDocument().getUri()) == null) {
log("[didSave] Input of Text Document is null in TextDocument-Hashmap.", MessageType.Error);
}
ArrayList<LSPVariable> typesOfMethodAndParameters = typeResolver.infereInput(textDocuments.get(params.getTextDocument().getUri()), params.getTextDocument().getUri());
List<InlayHint> typeHint = new ArrayList<>();
for (var variable : typesOfMethodAndParameters) {
InlayHint inlayHint = getInlayHint(variable);
typeHint.add(inlayHint);
//Diagnostics of Types
for (var type : variable.getPossibleTypes()) {
Diagnostic diagnostic = getDiagnostic(variable, params.getTextDocument().getUri(), type);
diagnostics.add(diagnostic);
}
}
updateGlobalMaps(diagnostics, typeHint, params.getTextDocument().getUri());
} catch (Exception e) {
log("[didSave] Error trying to get Inlay-Hints and Diagnostics for Client: " + e.getMessage(), MessageType.Error);
client.showMessage(new MessageParams(MessageType.Error, e.getMessage()));
updateGlobalMaps(new ArrayList<>(), new ArrayList<>(), params.getTextDocument().getUri());
} finally {
currentlyCalculating = false;
sWatch.stop();
log("[didSave] Finished Calculating in [" + sWatch.elapsed().toSeconds() + "s]", MessageType.Info);
}
}
for (var inlayHint : globalInlayHintMap.get(params.getTextDocument().getUri())) {
inlayHint.getPosition().setCharacter(inlayHint.getPosition().getCharacter() + offsetPerLine.get(inlayHint.getPosition().getLine()));
}
for (var inlayHint : globalDiagnosticsMap.get(params.getTextDocument().getUri())) {
inlayHint.getRange().getStart().setCharacter(inlayHint.getRange().getStart().getCharacter() + offsetPerLine.get(inlayHint.getRange().getStart().getLine()));
inlayHint.getRange().getEnd().setCharacter(inlayHint.getRange().getEnd().getCharacter() + offsetPerLine.get(inlayHint.getRange().getEnd().getLine()));
}
for (var textChangeLine : textChanges.entrySet()) {
log(textChangeLine.getKey() + " - " + String.join(",", textChangeLine.getValue()), MessageType.Info);
}
globalInlayHintMap.put(params.getTextDocument().getUri(), globalInlayHintMap.get(params.getTextDocument().getUri()).stream().filter(el -> {
//TODO: Hier das Label aufspalten an | weil die Typehints immer mit und getrennt sind und so jeder Typhint für sich durchlaufen werden kann.
log(el.getLabel().getLeft().replaceAll(" ", "") + "<>" + String.join(",", textChanges.get(el.getPosition().getLine())) + ": " + (!textChanges.get(el.getPosition().getLine()).contains(el.getLabel().getLeft().replaceAll(" ", "")) ? "true" : "false"), MessageType.Info);
return !textChanges.get(el.getPosition().getLine()).contains(el.getLabel().getLeft().replaceAll(" ", ""));
}).toList());
globalDiagnosticsMap.put(params.getTextDocument().getUri(), globalDiagnosticsMap.get(params.getTextDocument().getUri()).stream().filter(el -> {
log(el.getMessage().replaceAll(" ", "") + "<>" + String.join(",", textChanges.get(el.getRange().getStart().getLine())) + ": " + (!textChanges.get(el.getRange().getStart().getLine()).contains(el.getMessage().replaceAll(" ", "")) ? "true" : "false"), MessageType.Info);
return !textChanges.get(el.getRange().getStart().getLine()).contains(el.getMessage().replaceAll(" ", ""));
}).toList());
updateClient(client);
client.publishDiagnostics(new PublishDiagnosticsParams(params.getTextDocument().getUri(), globalDiagnosticsMap.get(params.getTextDocument().getUri())));
}
/**
@@ -244,8 +424,6 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
startLoading("compile-task", "Inferring types...", client);
LanguageServerInterface languageServerInterface = new LanguageServerInterface();
if (!currentlyCalculating) {
currentlyCalculating = true;
@@ -254,12 +432,13 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
sWatch.start();
try {
typeResolver.getCompilerInput(didSaveTextDocumentParams.getTextDocument().getUri(), textDocuments.get(didSaveTextDocumentParams.getTextDocument().getUri()));
if (textDocuments.get(didSaveTextDocumentParams.getTextDocument().getUri()) == null) {
log("[didSave] Input of Text Document is null in TextDocument-Hashmap.", MessageType.Error);
}
ArrayList<LSPVariable> typesOfMethodAndParameters = typeResolver.infereInput(textDocuments.get(didSaveTextDocumentParams.getTextDocument().getUri()), didSaveTextDocumentParams.getTextDocument().getUri());
variables = typesOfMethodAndParameters;
List<InlayHint> typeHint = new ArrayList<>();
for (var variable : typesOfMethodAndParameters) {
@@ -283,6 +462,8 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
} catch (Exception e) {
log("[didSave] Error trying to get Inlay-Hints and Diagnostics for Client: " + e.getMessage(), MessageType.Error);
client.showMessage(new MessageParams(MessageType.Error, e.getMessage()));
updateGlobalMaps(new ArrayList<>(), new ArrayList<>(), didSaveTextDocumentParams.getTextDocument().getUri());
} finally {
currentlyCalculating = false;
@@ -295,21 +476,24 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
stopLoading("compile-task", "Types successfully inferred", client);
dontShowHints = false;
updateClient(client);
ArrayList<File> files = new ArrayList<>();
if (fileRoot != null) {
try (Stream<Path> stream = Files.walk(Paths.get(fileRoot.toUri()))) {
stream.filter(Files::isRegularFile)
.forEach(el -> files.add(el.toFile()));
} catch (IOException e) {
}
}
}
@Override
public CompletableFuture<List<InlayHint>> inlayHint(InlayHintParams params) {
log("[inlayHint] The Client requested Inlay-Hints.", MessageType.Info);
return CompletableFuture.supplyAsync(() -> globalInlayHintMap.get(params.getTextDocument().getUri()) == null ? Collections.emptyList() : globalInlayHintMap.get(params.getTextDocument().getUri()));
return CompletableFuture.supplyAsync(() -> dontShowHints ? Collections.emptyList() : globalInlayHintMap.get(params.getTextDocument().getUri()) == null ? Collections.emptyList() : globalInlayHintMap.get(params.getTextDocument().getUri()));
}
@Override
@@ -441,7 +625,11 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
@Override
public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActionParams params) {
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);
log("Code-Action Context was: " + params.getContext().getTriggerKind().name(), MessageType.Info);
List<Either<Command, CodeAction>> actions = new ArrayList<>();
@@ -453,6 +641,8 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
.filter(diagnostic -> rangesOverlap(diagnostic.getRange(), requestedRange)).toList();
Range rangeOfInsert = params.getRange();
String documentUri = params.getTextDocument().getUri();
@@ -515,7 +705,9 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
}
}
return CompletableFuture.completedFuture(actions);
return CompletableFuture.supplyAsync(() -> {
return actions;
});
}

View File

@@ -12,11 +12,15 @@ import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.MessageType;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
import org.eclipse.lsp4j.services.LanguageClient;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@@ -29,6 +33,17 @@ public class TypeResolver {
private static final Logger logger = LogManager.getLogger(TypeResolver.class);
private final boolean ENABLE_GENERICS = false;
private LanguageServerTransferObject current;
public LanguageServerTransferObject getCurrent() {
return current;
}
public void reduceCurrent() {
current.getResultSets().removeFirst();
}
private List<ResultSet> currentResults = new ArrayList<>();
@@ -186,18 +201,35 @@ public class TypeResolver {
return genericTypes;
}
public void getCompilerInput(String path, String input) throws IOException, URISyntaxException, ClassNotFoundException {
LanguageServerInterface languageServer = new LanguageServerInterface();
var transferObj = languageServer.getResultSetAndAbstractSyntax(path, input);
current = transferObj;
}
/**
* Zum Erhalt für sowohl Parameter als auch Methoden.
*/
public ArrayList<LSPVariable> infereInput(String input, String path) throws IOException, ClassNotFoundException, URISyntaxException {
logger.info("Infering Types for Input.");
LanguageServerTransferObject transferObj;
if (current == null) {
LanguageServerInterface languageServer = new LanguageServerInterface();
var transferObj = languageServer.getResultSetAndAbstractSyntax(path, input);
transferObj = languageServer.getResultSetAndAbstractSyntax(path, input);
current = transferObj;
} else {
transferObj = current;
}
ArrayList<LSPVariable> methodsWithParametersLSPVariableList = new ArrayList<>();
if (!transferObj.getResultSets().isEmpty()) {
//TODO: Hier noch irgendwie die Klasse rausfinden oder durchgehen.
if (ENABLE_GENERICS) {
//GENERICS OF CLASS
for (var method : transferObj.getAst().getAllMethods()) {
@@ -206,25 +238,30 @@ public class TypeResolver {
ArrayList<Type> genericTypes = getClassGenerics(transferObj.getGeneratedGenerics(), method, clazz);
TextHelper helper = new TextHelper();
if (!genericTypes.isEmpty()) {
methodsWithParametersLSPVariableList.add(new LSPClass("test", genericTypes, clazz.getOffset().getLine(), helper.getClassPositionForGeneric(clazz.getOffset().getLine() - 1, input, clazz.getOffset().getStopIndex()), clazz.getOffset().getStopIndex()));
methodsWithParametersLSPVariableList.add(new LSPClass("test", genericTypes, clazz.getOffset().getLine(), helper.getClassPositionForGeneric(clazz.getOffset().getLine() - 1, input, clazz.getOffset().getStopIndex()), clazz.getOffset().getStopIndex(), clazz.getReturnType()));
}
}
}
}
for (var method : transferObj.getAst().getAllMethods()) {
var types = getAvailableTypes(transferObj.getResultSets(), method);
var generics = getAvailableGenericTypes(transferObj.getGeneratedGenerics().values().stream().flatMap(List::stream).collect(Collectors.toList()), method);
if (!filterOutDuplicates(types).isEmpty()) {
methodsWithParametersLSPVariableList.add(new LSPMethod(method.name, filterOutDuplicates(types), method.getOffset().getLine(), method.getOffset().getCharPositionInLine(), method.getOffset().getStopIndex()));
methodsWithParametersLSPVariableList.add(new LSPMethod(method.name, filterOutDuplicates(types), method.getOffset().getLine(), method.getOffset().getCharPositionInLine(), method.getOffset().getStopIndex(), method.getReturnType()));
}
if (ENABLE_GENERICS) {
if (!generics.isEmpty()) {
ArrayList<Type> typesThatAreGeneric = filterOutDuplicates(generics, types);
typesThatAreGeneric.forEach(el -> el.setType("<" + el.getType() + "> " + el.getType()));
//TODO: Muss Global und wird mehrmals so gemacht. Das if hier ist eigentlich falsch wegen unnötiger Berechnungszeit
if (!filterOutDuplicates(typesThatAreGeneric).isEmpty()) {
methodsWithParametersLSPVariableList.add(new LSPMethod(method.name, filterOutDuplicates(typesThatAreGeneric), method.getOffset().getLine(), method.getOffset().getCharPositionInLine(), method.getOffset().getStopIndex()));
methodsWithParametersLSPVariableList.add(new LSPMethod(method.name, filterOutDuplicates(typesThatAreGeneric), method.getOffset().getLine(), method.getOffset().getCharPositionInLine(), method.getOffset().getStopIndex(), method.getReturnType()));
}
}
}
@@ -233,16 +270,19 @@ public class TypeResolver {
ArrayList<Type> genericParam = getAvailableGenericTypes(transferObj.getGeneratedGenerics().values().stream().flatMap(List::stream).collect(Collectors.toList()), param.getType());
if (!typeParam.isEmpty()) {
methodsWithParametersLSPVariableList.add(new LSPParameter(method.name, filterOutDuplicates(typeParam), param.getOffset().getLine(), param.getOffset().getCharPositionInLine(), param.getOffset().getStopIndex()));
methodsWithParametersLSPVariableList.add(new LSPParameter(method.name, filterOutDuplicates(typeParam), param.getOffset().getLine(), param.getOffset().getCharPositionInLine(), param.getOffset().getStopIndex(), param.getType()));
}
if (ENABLE_GENERICS) {
if (!genericParam.isEmpty()) {
ArrayList<Type> typesThatAreGeneric = filterOutDuplicates(genericParam, typeParam);
if (!filterOutDuplicates(typesThatAreGeneric).isEmpty()) {
methodsWithParametersLSPVariableList.add(new LSPParameter(method.name, filterOutDuplicates(typesThatAreGeneric), method.getOffset().getLine(), param.getOffset().getCharPositionInLine(), param.getOffset().getStopIndex()));
methodsWithParametersLSPVariableList.add(new LSPParameter(method.name, new ArrayList<>(filterOutDuplicates(typesThatAreGeneric).stream().map(el -> new Type("<" + el.getType() + ">", true)).toList()), method.getOffset().getLine(), method.getOffset().getCharPositionInLine(), method.getOffset().getStopIndex()));
methodsWithParametersLSPVariableList.add(new LSPParameter(method.name, filterOutDuplicates(typesThatAreGeneric), method.getOffset().getLine(), param.getOffset().getCharPositionInLine(), param.getOffset().getStopIndex(), param.getType()));
methodsWithParametersLSPVariableList.add(new LSPParameter(method.name, new ArrayList<>(filterOutDuplicates(typesThatAreGeneric).stream().map(el -> new Type("<" + el.getType() + ">", true)).toList()), method.getOffset().getLine(), method.getOffset().getCharPositionInLine(), method.getOffset().getStopIndex(), method.getReturnType()));
}
}
}
}
}
@@ -252,4 +292,22 @@ public class TypeResolver {
}
public void reduceCurrent(HashMap<LineCharPosition, String> combinedList, List<LSPVariable> variables, LanguageClient client) {
client.logMessage(new MessageParams(MessageType.Info, "Lenght is: " + combinedList.size()));
for (var lines : combinedList.entrySet()) {
var contentChange = lines.getValue();
for (LSPVariable variable : variables) {
for (Type typeOfVariable : variable.getPossibleTypes()) {
client.logMessage(new MessageParams(MessageType.Info, "\"" + typeOfVariable.getType() + " : " + variable.getLine() + "\"< > \"" + contentChange + " : " + lines.getKey() + "\""));
if (typeOfVariable.getType().equalsIgnoreCase(contentChange.replaceAll(" ", ""))) {
if (variable.getLine() - 1 == lines.getKey().line && variable.getCharPosition() == lines.getKey().charPosition) {
current.getResultSets().removeIf(el -> !el.resolveType(variable.getOriginalTphName()).resolvedType.toString().equalsIgnoreCase(contentChange.replaceAll(" ", "")));
client.logMessage(new MessageParams(MessageType.Info, "Removing Resultset"));
return;
}
}
}
}
}
}
}

View File

@@ -1,9 +1,11 @@
package de.dhbw.model;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.ArrayList;
public class LSPClass extends LSPVariable{
public LSPClass(String name, ArrayList<Type> possibleTypes, int line, int charPosition, int endPosition) {
super(name, possibleTypes, line, charPosition, endPosition);
public LSPClass(String name, ArrayList<Type> possibleTypes, int line, int charPosition, int endPosition, RefTypeOrTPHOrWildcardOrGeneric originalTphName) {
super(name, possibleTypes, line, charPosition, endPosition, originalTphName);
}
}

View File

@@ -1,9 +1,11 @@
package de.dhbw.model;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.ArrayList;
public class LSPMethod extends LSPVariable {
public LSPMethod(String name, ArrayList<Type> type, int line, int charPosition, int endPosition) {
super(name, type, line, charPosition, endPosition);
public LSPMethod(String name, ArrayList<Type> type, int line, int charPosition, int endPosition, RefTypeOrTPHOrWildcardOrGeneric originalTphName) {
super(name, type, line, charPosition, endPosition, originalTphName);
}
}

View File

@@ -1,10 +1,12 @@
package de.dhbw.model;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.ArrayList;
public class LSPParameter extends LSPMethod {
public class LSPParameter extends LSPVariable {
public LSPParameter(String name, ArrayList<Type> type, int line, int charPosition, int endPosition) {
super(name, type, line, charPosition, endPosition);
public LSPParameter(String name, ArrayList<Type> type, int line, int charPosition, int endPosition, RefTypeOrTPHOrWildcardOrGeneric originalTphName) {
super(name, type, line, charPosition, endPosition, originalTphName);
}
}

View File

@@ -1,20 +1,33 @@
package de.dhbw.model;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.ArrayList;
public class LSPVariable { String name;
public class LSPVariable {
String name;
ArrayList<Type> possibleTypes;
int line;
int charPosition;
int endPosition;
boolean needsInference;
RefTypeOrTPHOrWildcardOrGeneric originalTphName;
public LSPVariable(String name, ArrayList<Type> possibleTypes, int line, int charPosition, int endPosition) {
public LSPVariable(String name, ArrayList<Type> possibleTypes, int line, int charPosition, int endPosition, RefTypeOrTPHOrWildcardOrGeneric originalTphName) {
this.name = name;
this.possibleTypes = possibleTypes;
this.line = line;
this.charPosition = charPosition;
this.endPosition = endPosition;
this.originalTphName = originalTphName;
}
public RefTypeOrTPHOrWildcardOrGeneric getOriginalTphName() {
return originalTphName;
}
public void setOriginalTphName(RefTypeOrTPHOrWildcardOrGeneric originalTphName) {
this.originalTphName = originalTphName;
}
public int getEndPosition() {

View File

@@ -0,0 +1,25 @@
package de.dhbw.model;
public class LineCharPosition {
public final int line;
public final int charPosition;
public LineCharPosition(int line, int charPosition) {
this.line = line;
this.charPosition = charPosition;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof LineCharPosition)) return false;
LineCharPosition that = (LineCharPosition) o;
return line == that.line && charPosition == that.charPosition;
}
@Override
public String toString() {
return "Line " + line + ", Char " + charPosition;
}
}

View File

@@ -1,30 +1,39 @@
import de.dhbw.helper.TextHelper;
import de.dhbw.helper.TypeResolver;
import de.dhbwstuttgart.languageServerInterface.LanguageServerInterface;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.net.URISyntaxException;
public class CompilerInterfaceTest {
@Test
public void testAbstractSyntaxAsString() throws IOException, ClassNotFoundException {
// LanguageServerInterface languageServer = new LanguageServerInterface();
// var res = languageServer.getResultSetAndAbstractSyntax("import java.lang.Integer;\n import java.lang.String;\n" +
// "public class test{\n" +
// "public main(test){" +
// "if(0>1){" +
// "return \"w\";" +
// "}" +
// "Integer i = 0;" +
// "return i;" +
// "}" +
// "}", "TEST");
//
// System.out.println("TEST OUTPUT:");
public void testAbstractSyntaxAsString() throws IOException, ClassNotFoundException, URISyntaxException {
TypeResolver typeResolver = new TypeResolver();
var res = typeResolver.infereInput("import java.lang.Integer;\n import java.lang.String;\n" +
"public class test{\n" +
"public main(test){" +
"if(0>1){" +
"return \"w\";" +
"}" +
"Integer i = 0;" +
"return i;" +
"}" +
"}", "c%3A/Users/ruben/Neuer%20Ordner%20%282%29/LSP-Vortrag/images/test.jav");
var res2 = typeResolver.infereInput("import java.lang.Integer;\n import java.lang.String;\n" +
"public class test{\n" +
"public main(test){" +
"if(0>1){" +
"return \"w\";" +
"}" +
"Integer i = 0;" +
"return i;" +
"}" +
"}", "c%3A/Users/ruben/Neuer%20Ordner%20%282%29/LSP-Vortrag/images/test.jav");
System.out.println("TEST OUTPUT:");
//
// ArrayList<String> allTypes = new ArrayList<>();
//

View File

@@ -11,6 +11,7 @@ public class JavaTXLanguageDocumentServiceTest {
@Test
@Ignore
public void testWordExtraction() {
JavaTXTextDocumentService service = new JavaTXTextDocumentService();
// JavaTXTextDocumentService service = new JavaTXTextDocumentService();
// service.didSave(new DidSaveTextDocumentParams(new TextDocumentIdentifier("file:///c%3A/Users/ruben/Neuer%20Ordner%20%282%29/LSP-Vortrag/images/test.jav")));
}
}