japicmp.model.JApiMethod Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of japicmp Show documentation
Show all versions of japicmp Show documentation
japicmp is a library that computes the differences between two
versions of a jar file/artifact in order to ease the API documentation for clients/customers.
package japicmp.model;
import japicmp.cmp.JarArchiveComparator;
import japicmp.util.Optional;
import japicmp.util.OptionalHelper;
import japicmp.util.SignatureParser;
import javassist.CtMethod;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
public class JApiMethod extends JApiBehavior {
private final Optional oldMethod;
private final Optional newMethod;
private final JApiReturnType returnType;
public JApiMethod(JApiClass jApiClass, String name, JApiChangeStatus changeStatus, Optional oldMethod, Optional newMethod, JarArchiveComparator jarArchiveComparator) {
super(jApiClass, name, oldMethod, newMethod, changeStatus, jarArchiveComparator);
this.oldMethod = oldMethod;
this.newMethod = newMethod;
this.returnType = computeReturnTypeChanges(oldMethod, newMethod);
this.changeStatus = evaluateChangeStatus(this.changeStatus);
}
private JApiChangeStatus evaluateChangeStatus(JApiChangeStatus changeStatus) {
if (changeStatus == JApiChangeStatus.UNCHANGED) {
if (this.returnType.getChangeStatus() != JApiChangeStatus.UNCHANGED) {
changeStatus = JApiChangeStatus.MODIFIED;
}
}
return changeStatus;
}
@Override
public void enhanceGenericTypeToParameters() {
super.enhanceGenericTypeToParameters(this.jApiClass, this.oldMethod, this.newMethod);
}
private JApiReturnType computeReturnTypeChanges(Optional oldMethodOptional, Optional newMethodOptional) {
JApiReturnType jApiReturnType = new JApiReturnType(JApiChangeStatus.UNCHANGED, Optional.absent(), Optional.absent());
if (oldMethodOptional.isPresent() && newMethodOptional.isPresent()) {
SignatureParser.ParsedParameter oldReturnType = computeReturnType(oldMethodOptional.get());
SignatureParser.ParsedParameter newReturnType = computeReturnType(newMethodOptional.get());
JApiChangeStatus changeStatusReturnType = JApiChangeStatus.UNCHANGED;
if (!oldReturnType.getType().equals(newReturnType.getType())) {
changeStatusReturnType = JApiChangeStatus.MODIFIED;
}
jApiReturnType = new JApiReturnType(changeStatusReturnType, Optional.of(oldReturnType.getType()), Optional.of(newReturnType.getType()));
SignatureParser.copyGenericParameters(computeReturnTypeGenericSignature(oldMethodOptional.get(), oldReturnType), jApiReturnType.getOldGenericTypes());
SignatureParser.copyGenericParameters(computeReturnTypeGenericSignature(newMethodOptional.get(), newReturnType), jApiReturnType.getNewGenericTypes());
} else {
if (oldMethodOptional.isPresent()) {
SignatureParser.ParsedParameter oldReturnType = computeReturnType(oldMethodOptional.get());
jApiReturnType = new JApiReturnType(JApiChangeStatus.REMOVED, Optional.of(oldReturnType.getType()), Optional.absent());
SignatureParser.copyGenericParameters(computeReturnTypeGenericSignature(oldMethodOptional.get(), oldReturnType), jApiReturnType.getOldGenericTypes());
}
if (newMethodOptional.isPresent()) {
SignatureParser.ParsedParameter newReturnType = computeReturnType(newMethodOptional.get());
jApiReturnType = new JApiReturnType(JApiChangeStatus.NEW, Optional.absent(), Optional.of(newReturnType.getType()));
SignatureParser.copyGenericParameters(computeReturnTypeGenericSignature(newMethodOptional.get(), newReturnType), jApiReturnType.getNewGenericTypes());
}
}
return jApiReturnType;
}
private SignatureParser.ParsedParameter computeReturnType(CtMethod ctMethod) {
SignatureParser parser = new SignatureParser();
parser.parse(ctMethod.getSignature());
return parser.getReturnType();
}
private SignatureParser.ParsedParameter computeReturnTypeGenericSignature(CtMethod ctMethod, SignatureParser.ParsedParameter rawSignatureParam) {
SignatureParser parser = new SignatureParser();
String genericSignature = ctMethod.getGenericSignature();
if (genericSignature != null) {
parser.parse(genericSignature);
return parser.getReturnType();
}
return rawSignatureParam;
}
public boolean hasSameReturnType(JApiMethod otherMethod) {
boolean haveSameReturnType = false;
JApiReturnType otherReturnType = otherMethod.getReturnType();
if (otherReturnType.getChangeStatus() == JApiChangeStatus.UNCHANGED || otherReturnType.getChangeStatus() == JApiChangeStatus.MODIFIED) {
if (this.returnType.getChangeStatus() == JApiChangeStatus.UNCHANGED || this.returnType.getChangeStatus() == JApiChangeStatus.MODIFIED) {
if (otherReturnType.getOldReturnType().equals(this.returnType.getOldReturnType()) && otherReturnType.getNewReturnType().equals(this.returnType.getNewReturnType())) {
haveSameReturnType = true;
}
} else if (this.returnType.getChangeStatus() == JApiChangeStatus.NEW) {
if (otherReturnType.getNewReturnType().equals(this.returnType.getNewReturnType())) {
haveSameReturnType = true;
}
} else if (this.returnType.getChangeStatus() == JApiChangeStatus.REMOVED) {
if (otherReturnType.getOldReturnType().equals(this.returnType.getOldReturnType())) {
haveSameReturnType = true;
}
}
} else if (otherReturnType.getChangeStatus() == JApiChangeStatus.NEW) {
if (this.returnType.getChangeStatus() == JApiChangeStatus.UNCHANGED || this.returnType.getChangeStatus() == JApiChangeStatus.MODIFIED) {
if (otherReturnType.getNewReturnType().equals(this.returnType.getNewReturnType())) {
haveSameReturnType = true;
}
} else if (this.returnType.getChangeStatus() == JApiChangeStatus.NEW) {
if (otherReturnType.getNewReturnType().equals(this.returnType.getNewReturnType())) {
haveSameReturnType = true;
}
} else if (this.returnType.getChangeStatus() == JApiChangeStatus.REMOVED) {
if (otherReturnType.getNewReturnType().equals(this.returnType.getOldReturnType())) {
haveSameReturnType = true;
}
}
} else {
if (this.returnType.getChangeStatus() == JApiChangeStatus.UNCHANGED || this.returnType.getChangeStatus() == JApiChangeStatus.MODIFIED) {
if (otherReturnType.getOldReturnType().equals(this.returnType.getNewReturnType())) {
haveSameReturnType = true;
}
} else if (this.returnType.getChangeStatus() == JApiChangeStatus.NEW) {
if (otherReturnType.getOldReturnType().equals(this.returnType.getNewReturnType())) {
haveSameReturnType = true;
}
} else if (this.returnType.getChangeStatus() == JApiChangeStatus.REMOVED) {
if (otherReturnType.getOldReturnType().equals(this.returnType.getOldReturnType())) {
haveSameReturnType = true;
}
}
}
return haveSameReturnType;
}
public boolean hasSameSignature(JApiMethod jApiMethod) {
return hasSameReturnType(jApiMethod) && hasSameParameter(jApiMethod);
}
@XmlTransient
public Optional getNewMethod() {
return newMethod;
}
@XmlTransient
public Optional getOldMethod() {
return oldMethod;
}
@XmlElement(name = "returnType")
public JApiReturnType getReturnType() {
return returnType;
}
public String toString()
{
return "JApiMethod [oldMethod="
+ toString(oldMethod)
+ ", newMethod="
+ toString(newMethod)
+ ", returnType="
+ returnType
+ ", getCompatibilityChanges()="
+ getCompatibilityChanges()
+ "]";
}
public static String toString(Optional method) {
if(method == null ) {
return OptionalHelper.N_A;
}
if(method.isPresent()) {
return method.get().getLongName();
}
return OptionalHelper.N_A;
}
@Override
public boolean isSourceCompatible() {
boolean sourceCompatible = super.isSourceCompatible();
if (sourceCompatible) {
sourceCompatible = returnType.isSourceCompatible();
}
for (JApiParameter jApiParameter : getParameters()) {
for (JApiCompatibilityChange compatibilityChange : jApiParameter.getCompatibilityChanges()) {
if (!compatibilityChange.isSourceCompatible()) {
sourceCompatible = false;
break;
}
}
}
return sourceCompatible;
}
}