Bug 171: Marker werden beim Insert verschoben, ohne Compileraufruf.

This commit is contained in:
michael 2020-04-02 22:22:38 +02:00
parent 96ffe4fa79
commit b29d86e091
5 changed files with 180 additions and 69 deletions

View File

@ -10,7 +10,7 @@ import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import typinferenzplugin.editor.JavEditor;
public class TypeReplaceMarker extends JavMarker {
public class TypeReplaceMarker extends JavMarker implements Comparable {
private JavEditor editor;
private CodePoint point;
@ -109,10 +109,21 @@ public class TypeReplaceMarker extends JavMarker {
return false;
}
else {
return ((TypeReplaceMarker)obj).tip.equals(this.tip);
TypeReplaceMarker other = (TypeReplaceMarker)obj;
boolean samePos = this.getPositionInCode() == other.getPositionInCode();
boolean sameInsert = this.getInsertPoint().getInsertString().equals(other.getInsertPoint().getInsertString());
return samePos && sameInsert;
}
}
@Override
public int hashCode() {
return getPositionInCode() * 37 + getInsertPoint().getInsertString().hashCode();
}
public void adjustResultSet(TypeReplaceMarker typeReplaceMarker) {
resultSets.removeIf(rs -> {
boolean result = true;
@ -125,4 +136,20 @@ public class TypeReplaceMarker extends JavMarker {
});
}
@Override
public int compareTo(Object o) {
if (o instanceof TypeReplaceMarker) {
TypeReplaceMarker other = (TypeReplaceMarker)o;
if (this.getPositionInCode() == other.getPositionInCode()) {
return 0;
} else if (this.getPositionInCode() > other.getPositionInCode()) {
return 1;
} else {
return -1;
}
}
return -1;
}
}

View File

@ -23,6 +23,8 @@ import org.apache.commons.io.output.NullOutputStream;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.Status;
import com.google.common.base.Strings;
import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
@ -33,9 +35,11 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typedeployment.TypeInsert;
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import typinferenzplugin.editor.JavEditor;
import typinferenzplugin.error.ErrorOutput;
@ -63,6 +67,11 @@ public class Typinferenz {
this.parsedSource = parsedSourceOrNull;
}
// Keine Exception bei leerem Editor
if (Strings.isNullOrEmpty(editor.getSourceCode())) {
return new UnifyResultModel(new ConstraintSet<>(), new FiniteClosure(new HashSet<>(), new OutputStreamWriter(new NullOutputStream())));
}
return compiler.typeInferenceAsync(resultListener, new OutputStreamWriter(new NullOutputStream()));
} catch (ClassNotFoundException e) {
LOG.log(new Status(ERROR, PLUGIN_ID, e.getMessage(), e));

View File

@ -7,8 +7,15 @@ import static typinferenzplugin.Activator.PLUGIN_ID;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
@ -288,90 +295,88 @@ public class JavEditor extends TextEditor implements UnifyResultListener {
IDocument document = this.getDocumentProvider().getDocument(this.getEditorInput());
document.set(typeReplaceMarker.insertType(document.get()));
Collection<TypeInsertPoint> additionalIdentityElimination = new HashSet<>();
typeReplaceMarkers.removeIf(trm -> trm.getPoint().getPositionInCode() == typeReplaceMarker.getPoint().getPositionInCode());
typeReplaceMarkers.removeIf(trm -> !trm.isConsistent(typeReplaceMarker));
int lengthOfInsert = typeReplaceMarker.getInsertPoint().getInsertString().length();
int postitionOfInsert = typeReplaceMarker.getPositionInCode();
for (TypeReplaceMarker toCheck : typeReplaceMarkers) {
if (toCheck.getPoint().getPositionInCode() > postitionOfInsert) {
toCheck.getInsertPoint().point.addExtraOffset(lengthOfInsert);
}
// Add extra offset for the additional insert points of "typeReplaceMarker"
// to "toCheck"
// ...
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPointsUnsorted()) {
int lengthAdditionalInsert = additionalPoint.getInsertString().length();
int positionAdditionalInsert = additionalPoint.getPositionInCode();
if (additionalIdentityElimination.add(additionalPoint) && postitionOfInsert > positionAdditionalInsert) {
toCheck.getInsertPoint().point.addExtraOffset(lengthAdditionalInsert);
}
}
for (TypeInsertPoint tip : typeReplaceMarker.getInsertPoint().getAdditionalPointsUnsorted()) {
// Add to all other type replace markers the extra offsets of the additional
// points of this type replace marker.
// ...
if (toCheck.getPoint().getPositionInCode() > tip.getPositionInCode()) {
toCheck.getInsertPoint().point.addExtraOffset(tip.getInsertString().length());
}
}
for (TypeInsertPoint toCheckAddi : toCheck.getInsertPoint().getAdditionalPointsUnsorted()) {
if (toCheckAddi.getPositionInCode() > postitionOfInsert) {
toCheckAddi.addExtraOffset(lengthOfInsert);
}
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPointsUnsorted()) {
int lengthAdditionalInsert = additionalPoint.getInsertString().length();
int positionAdditionalInsert = additionalPoint.getPositionInCode();
if (toCheckAddi.getPositionInCode() > positionAdditionalInsert) {
toCheckAddi.addExtraOffset(lengthAdditionalInsert);
}
}
}
}
typeReplaceMarkers.remove(typeReplaceMarker);
// Remove resultsets if not consistent.
for (TypeReplaceMarker trm : typeReplaceMarkers) {
trm.adjustResultSet(typeReplaceMarker);
}
updateGuiWithNewMarkers(typeReplaceMarkers);
MultiKeyMap<Integer, TypeInsertPoint> alreadyInserted = new MultiKeyMap<>();
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPoints()) {
for (TypeReplaceMarker other : this.typeReplaceMarkers) {
other.getInsertPoint().getAdditionalPointsUnsorted().removeIf(otAddi -> otAddi.getInsertString().trim().equals(additionalPoint.getInsertString().trim()));
}
}
Map<String, TypeInsertPoint> alreadyInserted = new HashMap<>();
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPoints() ) {
if (!additionalPoint.isGenericClassInsertPoint()) {
org.antlr.v4.runtime.Token additionalPt = additionalPoint.point;
alreadyInserted.put(additionalPt.getLine(), additionalPt.getCharPositionInLine(), additionalPoint);
alreadyInserted.put(additionalPoint.getInsertString(), additionalPoint);
}
}
boolean actualHasGenericClassInserts = typeReplaceMarker.getInsertPoint().getAdditionalPoints().stream().anyMatch(tip -> tip.isGenericClassInsertPoint());
if (actualHasGenericClassInserts) {
for (TypeReplaceMarker marker : typeReplaceMarkers) {
Iterator<TypeInsertPoint> addiPoints = marker.getInsertPoint().getAdditionalPointsUnsorted().iterator();
for (TypeReplaceMarker toCheck : typeReplaceMarkers) {
Iterator<TypeInsertPoint> addiPoints = toCheck.getInsertPoint().getAdditionalPointsUnsorted().iterator();
while (addiPoints.hasNext()) {
TypeInsertPoint addiPoint = addiPoints.next();
if (addiPoint.isGenericClassInsertPoint()) {
if (addiPoint.isGenericClassInsertPoint() && actualHasGenericClassInserts) {
addiPoints.remove();
} else if (alreadyInserted.get(addiPoint.point.getLine(), addiPoint.point.getCharPositionInLine()) != null) {
} else if (alreadyInserted.get(addiPoint.getInsertString()) != null) {
addiPoints.remove();
}
}
}
int lengthOfInsert = typeReplaceMarker.getInsertPoint().getInsertString().length();
int postitionOfInsert = typeReplaceMarker.getPositionInCode();
Set<TypeReplaceMarker> sortedMarkers = new TreeSet<TypeReplaceMarker>(typeReplaceMarkers);
Set<Pair<TypeInsertPoint, TypeInsertPoint>> additionalAddiIdentityElimination = new HashSet<>();
Map<TypeInsertPoint, Integer> allShifts = new SummingMap<TypeInsertPoint>();
for (TypeReplaceMarker toCheck : sortedMarkers) {
Collection<TypeInsertPoint> additionalIdentityElimination = new HashSet<>();
if (toCheck.getPositionInCode() >= postitionOfInsert) {
allShifts.put(toCheck.getInsertPoint().point, lengthOfInsert);
}
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPoints()) {
int lengthAdditionalInsert = additionalPoint.getInsertString().length();
int positionAdditionalInsert = additionalPoint.getPositionInCode();
if (additionalIdentityElimination.add(additionalPoint) && toCheck.getPositionInCode() >= positionAdditionalInsert) {
allShifts.put(toCheck.getInsertPoint().point, lengthAdditionalInsert);
}
}
for (TypeInsertPoint toCheckAddi : toCheck.getInsertPoint().getAdditionalPoints()) {
if (toCheckAddi.getPositionInCode() >= postitionOfInsert) {
allShifts.put(toCheckAddi, lengthOfInsert);
}
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPoints()) {
int lengthAdditionalInsert = additionalPoint.getInsertString().length();
int positionAdditionalInsert = additionalPoint.getPositionInCode();
if (additionalAddiIdentityElimination.add(new Pair<>(toCheckAddi,additionalPoint)) && toCheckAddi.getPositionInCode() >= positionAdditionalInsert) {
allShifts.put(toCheckAddi, lengthAdditionalInsert);
}
}
}
}
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPoints()) {
for (TypeReplaceMarker other : this.typeReplaceMarkers) {
other.getInsertPoint().getAdditionalPointsUnsorted().remove(additionalPoint);
}
for (Entry<TypeInsertPoint, Integer> shift : allShifts.entrySet()) {
shift.getKey().addExtraOffset(shift.getValue());
}
updateGuiWithNewMarkers(typeReplaceMarkers);
}
private void removeMarkers() {

View File

@ -0,0 +1,37 @@
package typinferenzplugin.editor;
public class Pair<L, R> {
private final L left;
private final R right;
public Pair(L left, R right) {
assert left != null;
assert right != null;
this.left = left;
this.right = right;
}
public L getLeft() {
return left;
}
public R getRight() {
return right;
}
@Override
public int hashCode() {
return left.hashCode() ^ right.hashCode();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Pair))
return false;
Pair pairo = (Pair) o;
return this.left.equals(pairo.getLeft()) && this.right.equals(pairo.getRight());
}
}

View File

@ -0,0 +1,33 @@
package typinferenzplugin.editor;
import static com.google.common.base.MoreObjects.firstNonNull;
import java.util.HashMap;
import java.util.Map;
public class SummingMap<T> extends HashMap<T, Integer >implements Map<T, Integer> {
private static final long serialVersionUID = 5823300094585927813L;
@Override
public Integer put(T key, Integer value) {
Integer sum = firstNonNull(get(key), 0) + value;
return super.put(key, sum);
}
@Override
public void putAll(Map<? extends T, ? extends Integer> m) {
for (Entry<? extends T, ? extends Integer> me : m.entrySet()) {
put(me.getKey(), me.getValue());
}
}
@Override
public Integer putIfAbsent(T key, Integer value) {
return put(key, value);
}
}