Skip to content

Commit

Permalink
issue124: now changing the type of variable causes also the maxCommon…
Browse files Browse the repository at this point in the history
…Type of the enclosing declaration to change
  • Loading branch information
ftomassetti committed Feb 23, 2017
1 parent 888ad04 commit 26bf9b3
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 8 deletions.
Expand Up @@ -455,7 +455,7 @@ protected void setAsParentNodeOf(NodeList<? extends Node> list) {
}
}

protected <P> void notifyPropertyChange(ObservableProperty property, P oldValue, P newValue) {
public <P> void notifyPropertyChange(ObservableProperty property, P oldValue, P newValue) {
this.observers.forEach( o -> o.propertyChange(this, property, oldValue, newValue));
}

Expand Down
Expand Up @@ -28,11 +28,17 @@
import com.github.javaparser.ast.expr.SimpleName;
import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
import com.github.javaparser.ast.nodeTypes.NodeWithType;
import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
import com.github.javaparser.ast.observer.ObservableProperty;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.visitor.GenericVisitor;
import com.github.javaparser.ast.visitor.VoidVisitor;

import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.github.javaparser.utils.Utils.assertNonEmpty;
import static com.github.javaparser.utils.Utils.assertNotNull;
import com.github.javaparser.ast.visitor.CloneVisitor;
Expand Down Expand Up @@ -151,8 +157,24 @@ public Type getType() {
public VariableDeclarator setType(final Type type) {
assertNotNull(type);
notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
if (this.type != null)
if (this.getParentNode().isPresent() && this.getParentNode().get() instanceof NodeWithVariables) {
NodeWithVariables nodeWithVariables = (NodeWithVariables)this.getParentNode().get();
Type currentMaxCommonType = nodeWithVariables.getMaximumCommonType();
List<Type> types = new LinkedList<>();
int index = nodeWithVariables.getVariables().indexOf(this);
for (int i=0;i<nodeWithVariables.getVariables().size();i++) {
if (i == index) {
types.add(type);
} else {
types.add(nodeWithVariables.getVariable(i).getType());
}
}
Type newMaxCommonType = NodeWithVariables.maximumCommonType(types);
((Node)nodeWithVariables).notifyPropertyChange(ObservableProperty.MAXIMUM_COMMON_TYPE, currentMaxCommonType, newMaxCommonType);
}
if (this.type != null) {
this.type.setParentNode(null);
}
this.type = type;
setAsParentNodeOf(type);
return this;
Expand Down
Expand Up @@ -28,6 +28,9 @@
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.metamodel.DerivedProperty;

import java.util.List;
import java.util.stream.Collectors;

/**
* A node which has a list of variables.
*/
Expand Down Expand Up @@ -107,6 +110,10 @@ default Type getElementType() {
*/
@DerivedProperty
default Type getMaximumCommonType() {
return maximumCommonType(this.getVariables().stream().map(v -> v.getType()).collect(Collectors.toList()));
}

static Type maximumCommonType(List<Type> types) {
// we use a local class because we cannot use an helper static method in an interface
class Helper {
// Conceptually: given a type we start from the Element Type and get as many array levels as indicated
Expand Down Expand Up @@ -134,8 +141,8 @@ private Type toArrayLevel(Type type, int level) {
// Now, given that equality on nodes consider the position the simplest way is to compare
// the pretty-printed string got for a node. We just check all them are the same and if they
// are we just just is not null
Object[] values = this.getVariables().stream().map(v -> {
Type t = helper.toArrayLevel(v.getType(), currentLevel);
Object[] values = types.stream().map(v -> {
Type t = helper.toArrayLevel(v, currentLevel);
return t == null ? null : t.toString();
}).distinct().toArray();
if (values.length == 1 && values[0] != null) {
Expand All @@ -144,7 +151,7 @@ private Type toArrayLevel(Type type, int level) {
keepGoing = false;
}
}
return helper.toArrayLevel(this.getVariables().get(0).getType(), --level);
return helper.toArrayLevel(types.get(0), --level);
}

}
@@ -1,5 +1,6 @@
package com.github.javaparser.printer.lexicalpreservation;

import com.github.javaparser.ASTParserConstants;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.type.PrimitiveType;
import com.github.javaparser.printer.concretesyntaxmodel.CsmElement;
Expand Down Expand Up @@ -398,6 +399,13 @@ public void apply(NodeText nodeText) {
nodeTextIndex++;
} else if (removed.element instanceof CsmToken && ((CsmToken)removed.element).isWhiteSpace()) {
diffIndex++;
} else if (removed.element instanceof LexicalDifferenceCalculator.CsmChild && ((LexicalDifferenceCalculator.CsmChild)removed.element).getChild() instanceof PrimitiveType) {
if (isPrimitiveType(nodeTextEl)) {
nodeText.removeElement(nodeTextIndex);
diffIndex++;
} else {
throw new UnsupportedOperationException("removed " + removed.element + " vs " + nodeTextEl);
}
} else {
throw new UnsupportedOperationException("removed " + removed.element + " vs " + nodeTextEl);
}
Expand All @@ -410,6 +418,36 @@ public void apply(NodeText nodeText) {
} while (diffIndex < this.elements.size() || nodeTextIndex < nodeText.getElements().size());
}

private boolean isPrimitiveType(TextElement textElement) {
if (textElement instanceof TokenTextElement) {
TokenTextElement tokenTextElement = (TokenTextElement)textElement;
if (tokenTextElement.getTokenKind() == ASTParserConstants.BYTE) {
return true;
}
if (tokenTextElement.getTokenKind() == ASTParserConstants.CHAR) {
return true;
}
if (tokenTextElement.getTokenKind() == ASTParserConstants.SHORT) {
return true;
}
if (tokenTextElement.getTokenKind() == ASTParserConstants.INT) {
return true;
}
if (tokenTextElement.getTokenKind() == ASTParserConstants.LONG) {
return true;
}
if (tokenTextElement.getTokenKind() == ASTParserConstants.FLOAT) {
return true;
}
if (tokenTextElement.getTokenKind() == ASTParserConstants.DOUBLE) {
return true;
}
return false;
} else {
return false;
}
}

public long cost() {
return elements.stream().filter(e -> !(e instanceof Kept)).count();
}
Expand Down
Expand Up @@ -28,6 +28,7 @@
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.expr.SimpleName;
Expand Down Expand Up @@ -145,6 +146,9 @@ public void concretePropertyChange(Node observedNode, ObservableProperty propert
}

new LexicalDifferenceCalculator().calculatePropertyChange(nodeText, observedNode, property, oldValue, newValue);
/*if (property == ObservableProperty.TYPE && observedNode instanceof VariableDeclarator) {
// TODO recalculate the maximum common type of the parent
}*/

//Una volta calcolata la differenza la applico al nodeText

Expand Down
Expand Up @@ -66,11 +66,13 @@ public void propertyChange(Node observedNode, ObservableProperty property, Objec

cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN));
assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
"VariableDeclarator.type changed from int to boolean"), changes);
"VariableDeclarator.type changed from int to boolean",
"FieldDeclaration.maximum_common_type changed from int to boolean"), changes);

cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam");
assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
"VariableDeclarator.type changed from int to boolean",
"FieldDeclaration.maximum_common_type changed from int to boolean",
"Parameter.name changed from p to myParam"), changes);
}

Expand Down Expand Up @@ -122,16 +124,19 @@ public void propertyChange(Node observedNode, ObservableProperty property, Objec

cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN));
assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
"VariableDeclarator.type changed from int to boolean"), changes);
"VariableDeclarator.type changed from int to boolean",
"FieldDeclaration.maximum_common_type changed from int to boolean"), changes);

cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam");
assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
"VariableDeclarator.type changed from int to boolean",
"FieldDeclaration.maximum_common_type changed from int to boolean",
"Parameter.name changed from p to myParam"), changes);

cu.getClassByName("MyCoolClass").get().addField("int", "bar").getVariables().get(0).setInitializer("0");
assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
"VariableDeclarator.type changed from int to boolean",
"FieldDeclaration.maximum_common_type changed from int to boolean",
"Parameter.name changed from p to myParam"), changes);
}

Expand All @@ -155,18 +160,21 @@ public void propertyChange(Node observedNode, ObservableProperty property, Objec

cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN));
assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
"VariableDeclarator.type changed from int to boolean"), changes);
"VariableDeclarator.type changed from int to boolean",
"FieldDeclaration.maximum_common_type changed from int to boolean"), changes);

cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam");
assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
"VariableDeclarator.type changed from int to boolean",
"FieldDeclaration.maximum_common_type changed from int to boolean",
"Parameter.name changed from p to myParam"), changes);

cu.getClassByName("MyCoolClass").get()
.addField("int", "bar")
.getVariables().get(0).setInitializer("0");
assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
"VariableDeclarator.type changed from int to boolean",
"FieldDeclaration.maximum_common_type changed from int to boolean",
"Parameter.name changed from p to myParam",
"VariableDeclarator.initializer changed from null to 0"), changes);
}
Expand Down

0 comments on commit 26bf9b3

Please sign in to comment.