Bug 171: Marker werden beim Insert verschoben, ohne Compileraufruf.
This commit is contained in:
parent
96ffe4fa79
commit
b29d86e091
@ -10,7 +10,7 @@ import de.dhbwstuttgart.typeinference.result.ResultPair;
|
|||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
import typinferenzplugin.editor.JavEditor;
|
import typinferenzplugin.editor.JavEditor;
|
||||||
|
|
||||||
public class TypeReplaceMarker extends JavMarker {
|
public class TypeReplaceMarker extends JavMarker implements Comparable {
|
||||||
|
|
||||||
private JavEditor editor;
|
private JavEditor editor;
|
||||||
private CodePoint point;
|
private CodePoint point;
|
||||||
@ -109,9 +109,20 @@ public class TypeReplaceMarker extends JavMarker {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
public void adjustResultSet(TypeReplaceMarker typeReplaceMarker) {
|
||||||
resultSets.removeIf(rs -> {
|
resultSets.removeIf(rs -> {
|
||||||
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@ import org.apache.commons.io.output.NullOutputStream;
|
|||||||
import org.eclipse.core.runtime.ILog;
|
import org.eclipse.core.runtime.ILog;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.BytecodeGen;
|
import de.dhbwstuttgart.bytecode.BytecodeGen;
|
||||||
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
|
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
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.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.typedeployment.TypeInsert;
|
import de.dhbwstuttgart.typedeployment.TypeInsert;
|
||||||
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
|
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
|
||||||
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
||||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||||
import typinferenzplugin.editor.JavEditor;
|
import typinferenzplugin.editor.JavEditor;
|
||||||
import typinferenzplugin.error.ErrorOutput;
|
import typinferenzplugin.error.ErrorOutput;
|
||||||
|
|
||||||
@ -63,6 +67,11 @@ public class Typinferenz {
|
|||||||
this.parsedSource = parsedSourceOrNull;
|
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()));
|
return compiler.typeInferenceAsync(resultListener, new OutputStreamWriter(new NullOutputStream()));
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
LOG.log(new Status(ERROR, PLUGIN_ID, e.getMessage(), e));
|
LOG.log(new Status(ERROR, PLUGIN_ID, e.getMessage(), e));
|
||||||
|
@ -7,8 +7,15 @@ import static typinferenzplugin.Activator.PLUGIN_ID;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
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.TreeSet;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
@ -288,90 +295,88 @@ public class JavEditor extends TextEditor implements UnifyResultListener {
|
|||||||
IDocument document = this.getDocumentProvider().getDocument(this.getEditorInput());
|
IDocument document = this.getDocumentProvider().getDocument(this.getEditorInput());
|
||||||
document.set(typeReplaceMarker.insertType(document.get()));
|
document.set(typeReplaceMarker.insertType(document.get()));
|
||||||
|
|
||||||
Collection<TypeInsertPoint> additionalIdentityElimination = new HashSet<>();
|
|
||||||
|
|
||||||
typeReplaceMarkers.removeIf(trm -> trm.getPoint().getPositionInCode() == typeReplaceMarker.getPoint().getPositionInCode());
|
typeReplaceMarkers.removeIf(trm -> trm.getPoint().getPositionInCode() == typeReplaceMarker.getPoint().getPositionInCode());
|
||||||
typeReplaceMarkers.removeIf(trm -> !trm.isConsistent(typeReplaceMarker));
|
typeReplaceMarkers.removeIf(trm -> !trm.isConsistent(typeReplaceMarker));
|
||||||
|
typeReplaceMarkers.remove(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove resultsets if not consistent.
|
// Remove resultsets if not consistent.
|
||||||
for (TypeReplaceMarker trm : typeReplaceMarkers) {
|
for (TypeReplaceMarker trm : typeReplaceMarkers) {
|
||||||
trm.adjustResultSet(typeReplaceMarker);
|
trm.adjustResultSet(typeReplaceMarker);
|
||||||
}
|
}
|
||||||
updateGuiWithNewMarkers(typeReplaceMarkers);
|
|
||||||
|
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPoints()) {
|
||||||
MultiKeyMap<Integer, TypeInsertPoint> alreadyInserted = new MultiKeyMap<>();
|
for (TypeReplaceMarker other : this.typeReplaceMarkers) {
|
||||||
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPoints() ) {
|
other.getInsertPoint().getAdditionalPointsUnsorted().removeIf(otAddi -> otAddi.getInsertString().trim().equals(additionalPoint.getInsertString().trim()));
|
||||||
if (!additionalPoint.isGenericClassInsertPoint()) {
|
|
||||||
org.antlr.v4.runtime.Token additionalPt = additionalPoint.point;
|
|
||||||
alreadyInserted.put(additionalPt.getLine(), additionalPt.getCharPositionInLine(), additionalPoint);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, TypeInsertPoint> alreadyInserted = new HashMap<>();
|
||||||
|
|
||||||
|
for (TypeInsertPoint additionalPoint : typeReplaceMarker.getInsertPoint().getAdditionalPoints() ) {
|
||||||
|
if (!additionalPoint.isGenericClassInsertPoint()) {
|
||||||
|
alreadyInserted.put(additionalPoint.getInsertString(), additionalPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean actualHasGenericClassInserts = typeReplaceMarker.getInsertPoint().getAdditionalPoints().stream().anyMatch(tip -> tip.isGenericClassInsertPoint());
|
boolean actualHasGenericClassInserts = typeReplaceMarker.getInsertPoint().getAdditionalPoints().stream().anyMatch(tip -> tip.isGenericClassInsertPoint());
|
||||||
if (actualHasGenericClassInserts) {
|
|
||||||
for (TypeReplaceMarker marker : typeReplaceMarkers) {
|
for (TypeReplaceMarker toCheck : typeReplaceMarkers) {
|
||||||
Iterator<TypeInsertPoint> addiPoints = marker.getInsertPoint().getAdditionalPointsUnsorted().iterator();
|
Iterator<TypeInsertPoint> addiPoints = toCheck.getInsertPoint().getAdditionalPointsUnsorted().iterator();
|
||||||
while (addiPoints.hasNext()) {
|
while (addiPoints.hasNext()) {
|
||||||
TypeInsertPoint addiPoint = addiPoints.next();
|
TypeInsertPoint addiPoint = addiPoints.next();
|
||||||
if (addiPoint.isGenericClassInsertPoint()) {
|
if (addiPoint.isGenericClassInsertPoint() && actualHasGenericClassInserts) {
|
||||||
addiPoints.remove();
|
addiPoints.remove();
|
||||||
} else if (alreadyInserted.get(addiPoint.point.getLine(), addiPoint.point.getCharPositionInLine()) != null) {
|
} else if (alreadyInserted.get(addiPoint.getInsertString()) != null) {
|
||||||
addiPoints.remove();
|
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 (Entry<TypeInsertPoint, Integer> shift : allShifts.entrySet()) {
|
||||||
for (TypeReplaceMarker other : this.typeReplaceMarkers) {
|
shift.getKey().addExtraOffset(shift.getValue());
|
||||||
other.getInsertPoint().getAdditionalPointsUnsorted().remove(additionalPoint);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateGuiWithNewMarkers(typeReplaceMarkers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeMarkers() {
|
private void removeMarkers() {
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user