Skip to content

Commit

Permalink
#393 In case of method with array (byte[]) and varargs array (byte[].…
Browse files Browse the repository at this point in the history
…..) parameter, methods are matched correctly
  • Loading branch information
siom79 committed Apr 21, 2024
1 parent a3c9508 commit 7a18ee2
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package japicmp.test;

public class VarArgs {

public static void wrappedBuffer(byte[] arrays) {
return;
}

public static void wrappedBuffer(byte[]... arrays) {
return;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package japicmp.test;

public class VarArgs {

public static void wrappedBuffer(byte[] arrays) {
return;
}

public static void wrappedBuffer(byte[]... arrays) {
return;
}
}
58 changes: 28 additions & 30 deletions japicmp/src/main/java/japicmp/util/SignatureParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ public boolean isTemplate() {
return template;
}

public void setTemplate(boolean template) {
this.template = template;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down Expand Up @@ -111,7 +107,7 @@ public void parse(String signature) {
if (parenthesisOpenIndex > 0 && signature.startsWith("<")) {
String templateDefWithBrackets = signature.substring(0, parenthesisOpenIndex);
if (templateDefWithBrackets.startsWith("<") && templateDefWithBrackets.endsWith(">") && templateDefWithBrackets.length() > 2) {
parseTemplateDefinition(templateDefWithBrackets.substring(1, templateDefWithBrackets.length()-1));
parseTemplateDefinition(templateDefWithBrackets.substring(1, templateDefWithBrackets.length() - 1));
}
}
if (parenthesisCloseIndex > -1) {
Expand Down Expand Up @@ -146,8 +142,8 @@ public List<ParsedTemplate> parseTemplatesOfClass(CtClass ctClass) {
String genericSignature = ctClass.getGenericSignature();
if (genericSignature != null && genericSignature.startsWith("<")) {
int lastClosingBracket = genericSignature.lastIndexOf('>');
if (lastClosingBracket > 0 && genericSignature.length()-2 > 0) {
parseTemplateDefinition(genericSignature.substring(1, genericSignature.length()-1));
if (lastClosingBracket > 0 && genericSignature.length() - 2 > 0) {
parseTemplateDefinition(genericSignature.substring(1, genericSignature.length() - 1));
return this.templates;
}
}
Expand All @@ -157,41 +153,41 @@ public List<ParsedTemplate> parseTemplatesOfClass(CtClass ctClass) {
public List<ParsedParameter> parseTypes(String paramPart) {
List<ParsedParameter> types = new ArrayList<>();
ParsedParameter parsedParameter = new ParsedParameter();
boolean arrayNotation = false;
int arrayNotation = 0;
int i = 0;
while (i < paramPart.length()) {
char c = paramPart.charAt(i);
String type;
StringBuilder type;
switch (c) {
case 'Z':
type = "boolean";
type = new StringBuilder("boolean");
break;
case 'B':
type = "byte";
type = new StringBuilder("byte");
break;
case 'C':
type = "char";
type = new StringBuilder("char");
break;
case 'S':
type = "short";
type = new StringBuilder("short");
break;
case 'I':
type = "int";
type = new StringBuilder("int");
break;
case 'J':
type = "long";
type = new StringBuilder("long");
break;
case 'F':
type = "float";
type = new StringBuilder("float");
break;
case 'D':
type = "double";
type = new StringBuilder("double");
break;
case 'V':
type = "void";
type = new StringBuilder("void");
break;
case '[':
arrayNotation = true;
arrayNotation++;
i++;
continue;
case 'L':
Expand All @@ -212,18 +208,20 @@ public List<ParsedParameter> parseTypes(String paramPart) {
}
i++;
}
type = fqn.toString();
type = new StringBuilder(fqn.toString());
parsedParameter.template = template;
break;
default:
LOGGER.log(Level.FINE, "Unknown type signature: '" + c + "' in " + paramPart);
return Collections.emptyList();
}
if (arrayNotation) {
type += "[]";
arrayNotation = false;
if (arrayNotation > 0) {
for (int an = 0; an < arrayNotation; an++) {
type.append("[]");
}
arrayNotation = 0;
}
parsedParameter.type = type;
parsedParameter.type = type.toString();
types.add(parsedParameter);
parsedParameter = new ParsedParameter();
i++;
Expand Down Expand Up @@ -293,18 +291,18 @@ private void parseTemplateDefinition(String str) {
while (i < str.length()) {
char c = str.charAt(i);
if (c == ':') {
if (i+1 < str.length() && str.charAt(i+1) == ':') {
if (i + 1 < str.length() && str.charAt(i + 1) == ':') {
i++;
}
currentTemplate.name = name.toString();

ParsedParameter parsedParameter = new ParsedParameter();
i = parseGenerics(parsedParameter, str, i+1, true);
i = parseGenerics(parsedParameter, str, i + 1, true);
currentTemplate.type = parsedParameter.type;
currentTemplate.genericTypes = parsedParameter.genericTypes;
while (i+1 < str.length() && str.charAt(i+1) == ':') {
while (i + 1 < str.length() && str.charAt(i + 1) == ':') {
ParsedParameter parsedInterface = new ParsedParameter();
i = parseGenerics(parsedInterface, str, i+2, true);
i = parseGenerics(parsedInterface, str, i + 2, true);
currentTemplate.interfaces.add(parsedInterface);
}
this.templates.add(currentTemplate);
Expand Down Expand Up @@ -412,9 +410,9 @@ public static boolean equalGenericTypes(List<JApiGenericType> oldGenericTypes, L
if (oldGenericTypes.size() != newGenericTypes.size()) {
return false;
}
for (int i=0; i< oldGenericTypes.size(); i++) {
for (int i = 0; i < oldGenericTypes.size(); i++) {
if (!oldGenericTypes.get(i).getType().equals(newGenericTypes.get(i).getType()) ||
!oldGenericTypes.get(i).getGenericWildCard().equals(newGenericTypes.get(i).getGenericWildCard())) {
!oldGenericTypes.get(i).getGenericWildCard().equals(newGenericTypes.get(i).getGenericWildCard())) {
return false;
}
}
Expand Down
47 changes: 47 additions & 0 deletions japicmp/src/test/java/japicmp/compat/CompatibilityChangesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2511,4 +2511,51 @@ public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
assertThat(jApiMethod.getCompatibilityChanges().size(), is(1));
assertThat(jApiMethod.getCompatibilityChanges(), hasItem(new JApiCompatibilityChange(JApiCompatibilityChangeType.CLASS_GENERIC_TEMPLATE_CHANGED)));
}

@Test
public void testMethodWithByteArrayAndArrayOfByteArrays() throws Exception {
JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions();
jarArchiveComparatorOptions.setAccessModifier(AccessModifier.PRIVATE);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClassC = CtClassBuilder.create().name("C").addToClassPool(classPool);
CtMethodBuilder.create()
.returnType(CtClass.voidType)
.name("method")
.parameters(new CtClass[]{classPool.get("byte[]")})
.addToClass(ctClassC);
CtMethodBuilder.create()
.returnType(CtClass.voidType)
.name("method")
.parameters(new CtClass[]{classPool.get("byte[][]")})
.addToClass(ctClassC);
return Collections.singletonList(ctClassC);
}

@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClassC = CtClassBuilder.create().name("C").addToClassPool(classPool);
CtMethodBuilder.create()
.returnType(CtClass.voidType)
.name("method")
.parameters(new CtClass[]{classPool.get("byte[]")})
.addToClass(ctClassC);
CtMethodBuilder.create()
.returnType(CtClass.voidType)
.name("method")
.parameters(new CtClass[]{classPool.get("byte[][]")})
.addToClass(ctClassC);
return Collections.singletonList(ctClassC);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "C");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
for (JApiMethod jApiMethod : jApiClass.getMethods()) {
assertThat(jApiMethod.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiMethod.isBinaryCompatible(), is(true));
assertThat(jApiMethod.isSourceCompatible(), is(true));
assertThat(jApiMethod.getCompatibilityChanges().size(), is(0));
}
}
}
11 changes: 10 additions & 1 deletion japicmp/src/test/java/japicmp/util/SignatureParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.hamcrest.MatcherAssert.assertThat;

public class SignatureParserTest {
private SignatureParser subject;
Expand Down Expand Up @@ -190,6 +190,15 @@ public void testMethodWithGenericUnbounded() {
Assert.assertEquals(JApiGenericType.JApiGenericWildCard.UNBOUNDED, parsedParameters.get(0).getGenericTypes().get(0).getGenericWildCard());
}

@Test
public void testMethodWithDoubleArray() {
subject.parse("([[B)V)");
List<SignatureParser.ParsedParameter> parsedParameters = subject.getParameters();
Assert.assertEquals(1, parsedParameters.size());
Assert.assertEquals("byte[][]", parsedParameters.get(0).getType());
Assert.assertEquals(0, parsedParameters.get(0).getGenericTypes().size());
}

@Test
public void testMethodWithMethodParameters() {
subject.parse("<T:Ljava/lang/Integer;>(TT;)V");
Expand Down

0 comments on commit 7a18ee2

Please sign in to comment.