Compare commits
3 Commits
9d42e829e2
...
0.0.5
Author | SHA1 | Date | |
---|---|---|---|
|
1b84b77677 | ||
|
6b40ce7e64 | ||
|
3fe253ae63 |
@@ -289,7 +289,7 @@ public class JavaTXTextDocumentService implements org.eclipse.lsp4j.services.Tex
|
||||
logService.log("Code-Action Context was: " + params.getContext().getTriggerKind().name(), MessageType.Info);
|
||||
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
return codeActionHandler.handleCodeAction(params);
|
||||
return codeActionHandler.handleNewCodeAction(params);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -37,10 +38,32 @@ public class ChangeHandler {
|
||||
this.logService = logService;
|
||||
}
|
||||
|
||||
|
||||
public static String findAddedWord(String str1, String str2) {
|
||||
String[] words1 = str1.split("\\s+");
|
||||
String[] words2 = str2.split("\\s+");
|
||||
|
||||
int i = 0, j = 0;
|
||||
while (i < words1.length && j < words2.length) {
|
||||
if (words1[i].equals(words2[j])) {
|
||||
i++;
|
||||
j++;
|
||||
} else {
|
||||
return words2[j]; // Unterschied gefunden
|
||||
}
|
||||
}
|
||||
|
||||
// Falls das neue Wort am Ende steht
|
||||
if (j < words2.length) {
|
||||
return words2[j];
|
||||
}
|
||||
|
||||
return null; // Kein Unterschied gefunden
|
||||
}
|
||||
|
||||
public void didChange(DidChangeTextDocumentParams params) {
|
||||
String currentText = textDocumentService.getFileOfUri(params.getTextDocument().getUri());
|
||||
|
||||
|
||||
AtomicReference<String> summedUp = new AtomicReference<>("");
|
||||
params.getContentChanges().forEach(el -> summedUp.set(summedUp.get() + el.getText()));
|
||||
textDocumentService.saveFileWithUri(params.getTextDocument().getUri(), summedUp.get());
|
||||
@@ -50,6 +73,9 @@ public class ChangeHandler {
|
||||
HashMap<Integer, List<String>> textChanges;
|
||||
|
||||
|
||||
String type = findAddedWord(currentText, summedUp.get());
|
||||
logService.log("ADDED TYPE IS: " + type);
|
||||
|
||||
//Have to check of old saved Input because the result set and Inlay Hints will be updated according to the old AST which contains the old Positions
|
||||
if (cacheService.getLastSavedFiles().containsKey(params.getTextDocument().getUri())) {
|
||||
DocumentChanges changesFromOldSave = textDocumentService.calculateDifference(cacheService.getLastSavedFiles().get(params.getTextDocument().getUri()), summedUp.get());
|
||||
@@ -65,6 +91,17 @@ public class ChangeHandler {
|
||||
String input = summedUp.get();
|
||||
|
||||
|
||||
logService.log("Variables are: " + cacheService.getVariables().size());
|
||||
|
||||
|
||||
AtomicBoolean needToCalculate = new AtomicBoolean(false);
|
||||
|
||||
cacheService.getVariables().forEach(
|
||||
el -> el.getPossibleTypes().forEach(pos -> needToCalculate.set(needToCalculate.get() || pos.getType().equalsIgnoreCase(type)))
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (false) {
|
||||
typeResolver.reduceCurrent(preciseChanges, cacheService.getVariables());
|
||||
try {
|
||||
@@ -167,7 +204,7 @@ public class ChangeHandler {
|
||||
logService.log("[didSave] Input of Text Document is null in TextDocument-Hashmap.", MessageType.Error);
|
||||
}
|
||||
|
||||
ArrayList<LSPVariable> variables = typeResolver.infereInput(tempFile2.toURI().toString());
|
||||
ArrayList<LSPVariable> variables = typeResolver.infereInput(tempFile2.toURI().toString(), fileInput, false);
|
||||
cacheService.setVariables(variables);
|
||||
|
||||
DiagnosticsAndTypehints diagnosticsAndTypehints = conversionHelper.variablesToDiagnosticsAndTypehintsWithInput(variables, input);
|
||||
|
@@ -5,6 +5,7 @@ import de.dhbw.helper.TypeResolver;
|
||||
import de.dhbw.service.CacheService;
|
||||
import de.dhbw.service.LogService;
|
||||
import de.dhbw.service.TextDocumentService;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsert;
|
||||
import org.eclipse.lsp4j.*;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
|
||||
@@ -12,6 +13,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CodeActionHandler {
|
||||
|
||||
@@ -29,6 +31,117 @@ public class CodeActionHandler {
|
||||
this.logService = logService;
|
||||
}
|
||||
|
||||
public static Range wholeDocumentRange(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return new Range(new Position(0, 0), new Position(0, 0));
|
||||
}
|
||||
|
||||
int lastLine = 0;
|
||||
int lastBreak = -1; // Index des letzten Zeilenumbruchszeichens, das zum Zeilenende gehört
|
||||
|
||||
final int n = text.length();
|
||||
for (int i = 0; i < n; i++) {
|
||||
char c = text.charAt(i);
|
||||
if (c == '\n') {
|
||||
lastLine++;
|
||||
lastBreak = i;
|
||||
} else if (c == '\r') {
|
||||
// Unterscheide \r\n von alleine stehendem \r
|
||||
if (i + 1 < n && text.charAt(i + 1) == '\n') {
|
||||
lastLine++;
|
||||
lastBreak = i + 1;
|
||||
i++; // \n überspringen
|
||||
} else {
|
||||
lastLine++;
|
||||
lastBreak = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int lastLineStart = lastBreak + 1;
|
||||
int endChar = n - lastLineStart; // Länge der letzten Zeile in UTF-16 Code Units
|
||||
|
||||
return new Range(new Position(0, 0), new Position(lastLine, endChar));
|
||||
}
|
||||
|
||||
|
||||
public static <V> Map<String, V> getOverlapping(
|
||||
Map<String, V> map,
|
||||
int line,
|
||||
int startChar,
|
||||
int endChar
|
||||
) {
|
||||
if (startChar > endChar) {
|
||||
int t = startChar;
|
||||
startChar = endChar;
|
||||
endChar = t;
|
||||
}
|
||||
|
||||
final int s = startChar, e = endChar;
|
||||
|
||||
return map.entrySet().stream()
|
||||
.filter(entry -> {
|
||||
String key = entry.getKey();
|
||||
String[] parts = key.split("\\s+");
|
||||
if (parts.length != 2) return false;
|
||||
try {
|
||||
int kLine = Integer.parseInt(parts[0]);
|
||||
int kChar = Integer.parseInt(parts[1]);
|
||||
return kLine == line && kChar >= s && kChar <= e;
|
||||
} catch (NumberFormatException ex) {
|
||||
// Key nicht im erwarteten Format
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
|
||||
public List<Either<Command, CodeAction>> handleNewCodeAction(CodeActionParams params) {
|
||||
|
||||
String documentUri = params.getTextDocument().getUri();
|
||||
|
||||
|
||||
List<Diagnostic> diagnosticInCurrentDocument = params.getContext().getDiagnostics();
|
||||
Range rangeOfInsert = params.getRange();
|
||||
|
||||
//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<TypeInsert>> typeInsertsOverlapping = getOverlapping(typeResolver.getInserts(), rangeOfInsert.getStart().getLine()+1, rangeOfInsert.getStart().getCharacter(), rangeOfInsert.getEnd().getCharacter());
|
||||
logService.log("Inserts are:");
|
||||
typeResolver.getInserts().forEach((key, value) -> logService.log(key));
|
||||
logService.log("Size is: " + typeInsertsOverlapping.size());
|
||||
logService.log("Range is: " + rangeOfInsert.getStart().getLine() + " -> " + rangeOfInsert.getStart().getCharacter() + " - " + rangeOfInsert.getEnd().getCharacter());
|
||||
List<Either<Command, CodeAction>> actions = new ArrayList<>();
|
||||
|
||||
for (var typeInsertList : typeInsertsOverlapping.values()) {
|
||||
for (var typeInsert : typeInsertList) {
|
||||
try {
|
||||
String typeWithReplacedVariable = typeInsert.insert(textDocumentService.getFileOfUri(documentUri));
|
||||
|
||||
ArrayList<TextEdit> listOfChanges = new ArrayList<>();
|
||||
|
||||
listOfChanges.add(new TextEdit(wholeDocumentRange(textDocumentService.getFileOfUri(documentUri)), typeWithReplacedVariable));
|
||||
|
||||
var isTypeImported = false;
|
||||
|
||||
Map<String, List<TextEdit>> changes = new HashMap<>();
|
||||
changes.put(documentUri, listOfChanges);
|
||||
|
||||
WorkspaceEdit edit = new WorkspaceEdit();
|
||||
edit.setChanges(changes);
|
||||
|
||||
CodeAction action = new CodeAction("Insert " + typeInsert.getInsertString());
|
||||
action.setKind(CodeActionKind.QuickFix);
|
||||
action.setEdit(edit);
|
||||
actions.add(Either.forRight(action));
|
||||
} catch (Exception e) {
|
||||
logService.log("Error creating Actions, returning empty List. The Error was: " + e.getMessage(), MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
public List<Either<Command, CodeAction>> handleCodeAction(CodeActionParams params) {
|
||||
|
||||
String documentUri = params.getTextDocument().getUri();
|
||||
|
@@ -50,7 +50,7 @@ public class SaveHandler {
|
||||
logService.log("[didSave] Input of Text Document is null in TextDocument-Hashmap.", MessageType.Error);
|
||||
}
|
||||
|
||||
ArrayList<LSPVariable> variables = typeResolver.infereInput(didSaveTextDocumentParams.getTextDocument().getUri());
|
||||
ArrayList<LSPVariable> variables = typeResolver.infereInput(didSaveTextDocumentParams.getTextDocument().getUri(), fileInput, false);
|
||||
cacheService.setVariables(variables);
|
||||
|
||||
DiagnosticsAndTypehints diagnosticsAndTypehints = conversionHelper.variablesToDiagnosticsAndTypehints(variables, didSaveTextDocumentParams.getTextDocument().getUri());
|
||||
|
@@ -57,7 +57,7 @@ public class TextHelper {
|
||||
|
||||
if(lines.length < line){
|
||||
log.warn("Returning hardcoded Value because the requested Line [" + line + "] does not exist in Text Document.");
|
||||
return startChar+3;
|
||||
return startChar;
|
||||
}
|
||||
|
||||
String[] linesInChar = lines[line].split("");
|
||||
|
@@ -38,8 +38,13 @@ public class TypeResolver {
|
||||
private final DuplicationUtils duplicationUtils;
|
||||
private final boolean ENABLE_GENERICS = true;
|
||||
private List<GenericsResult> generatedGenerics = null;
|
||||
private HashMap<String, List<TypeInsert>> inserts;
|
||||
|
||||
|
||||
public HashMap<String, List<TypeInsert>> getInserts() {
|
||||
return inserts;
|
||||
}
|
||||
|
||||
//Somehow you have to reset to the Letter N to keep the naming of the TPHs consistent
|
||||
private final String RESET_TO_LETTER = "A";
|
||||
|
||||
@@ -121,7 +126,7 @@ public class TypeResolver {
|
||||
return variables;
|
||||
}
|
||||
|
||||
public ArrayList<LSPVariable> infereInput(String pathString) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||
public ArrayList<LSPVariable> infereInput(String pathString, String input, boolean a) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||
|
||||
var uri = new URI(pathString);
|
||||
@@ -150,7 +155,6 @@ public class TypeResolver {
|
||||
System.setOut(System.out);
|
||||
this.current = new LanguageServerTransferObject(tiResults, parsedSource, "", compiler.getGeneratedGenerics());
|
||||
|
||||
|
||||
HashMap<String, List<TypeInsert>> insertsOnLines = new HashMap<>();
|
||||
|
||||
for (TypeInsert insert : tips) {
|
||||
@@ -161,8 +165,13 @@ public class TypeResolver {
|
||||
}
|
||||
}
|
||||
|
||||
inserts = insertsOnLines;
|
||||
|
||||
insertsOnLines.forEach((key, value) -> value.forEach(type -> logger.info(type.insert(input))));
|
||||
|
||||
ArrayList<LSPVariable> variables = new ArrayList<>(insertsOnLines.entrySet().stream().map(el -> new LSPVariable("test", new ArrayList<>(el.getValue().stream().map(typeinsert -> new Type(typeinsert.getInsertString(), typeinsert.point.isGenericClassInsertPoint())).toList()), el.getValue().getFirst().point.point.getLine(), el.getValue().getFirst().point.point.getCharPositionInLine(), el.getValue().get(0).point.point.getStopIndex(), el.getValue().get(0).getResultPair().getLeft())).toList());
|
||||
|
||||
|
||||
for (var variable : variables) {
|
||||
Set<Type> set = new HashSet<>(variable.getPossibleTypes().stream().map(el -> new Type(el.getType().replaceAll(" ", ""), el.isGeneric())).toList());
|
||||
variable.getPossibleTypes().clear();
|
||||
|
@@ -4,6 +4,7 @@ import de.dhbw.helper.CodeSnippetOptions;
|
||||
import de.dhbw.helper.TextHelper;
|
||||
import de.dhbw.helper.TypeResolver;
|
||||
import de.dhbw.model.LSPVariable;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsert;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.eclipse.lsp4j.InlayHint;
|
||||
|
||||
@@ -25,6 +26,15 @@ public class CacheService {
|
||||
private Path fileRoot = null;
|
||||
private Boolean singleFileOpened = false;
|
||||
private List<LSPVariable> variables = new ArrayList<>();
|
||||
private List<TypeInsert> typeInserts;
|
||||
|
||||
public List<TypeInsert> getTypeInserts() {
|
||||
return typeInserts;
|
||||
}
|
||||
|
||||
public void setTypeInserts(List<TypeInsert> typeInserts) {
|
||||
this.typeInserts = typeInserts;
|
||||
}
|
||||
|
||||
public void updateGlobalMaps(List<Diagnostic> diagnostics, List<InlayHint> typeHint, String uri) {
|
||||
globalDiagnosticsMap.put(uri, diagnostics);
|
||||
|
Reference in New Issue
Block a user