Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take transient modifier into account #372

Merged
merged 7 commits into from
Feb 15, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,12 @@ public Integer callback(JApiClass superclass, Map<String, JApiClass> classMap, J
addCompatibilityChange(field, JApiCompatibilityChange.FIELD_NO_LONGER_STATIC);
}
}
if (isNotPrivate(field) && field.getType().hasChanged()) {
addCompatibilityChange(field, JApiCompatibilityChange.FIELD_TYPE_CHANGED);
guillermocalvo marked this conversation as resolved.
Show resolved Hide resolved
// section 13.4.11 of "Java Language Specification" SE7
if (field.getTransientModifier().hasChangedFromTo(TransientModifier.NON_TRANSIENT, TransientModifier.TRANSIENT)) {
addCompatibilityChange(field, JApiCompatibilityChange.FIELD_NOW_TRANSIENT);
}
if (field.getTransientModifier().hasChangedFromTo(TransientModifier.TRANSIENT, TransientModifier.NON_TRANSIENT)) {
addCompatibilityChange(field, JApiCompatibilityChange.FIELD_NO_LONGER_TRANSIENT);
}
checkIfAnnotationDeprecatedAdded(field);
checkIfFieldGenericsChanged(field);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ public enum JApiCompatibilityChange {
FIELD_STATIC_AND_OVERRIDES_STATIC(false, false, JApiSemanticVersionLevel.MAJOR),
FIELD_LESS_ACCESSIBLE_THAN_IN_SUPERCLASS(false, false, JApiSemanticVersionLevel.MAJOR),
FIELD_NOW_FINAL(false, false, JApiSemanticVersionLevel.MAJOR),
FIELD_NOW_TRANSIENT(true, true, JApiSemanticVersionLevel.PATCH),
FIELD_NOW_STATIC(false, false, JApiSemanticVersionLevel.MAJOR),
FIELD_NO_LONGER_TRANSIENT(true, true, JApiSemanticVersionLevel.PATCH),
FIELD_NO_LONGER_STATIC(false, false, JApiSemanticVersionLevel.MAJOR),
FIELD_TYPE_CHANGED(false, false, JApiSemanticVersionLevel.MAJOR),
FIELD_REMOVED(false, false, JApiSemanticVersionLevel.MAJOR),
Expand Down
2 changes: 1 addition & 1 deletion japicmp/src/main/java/japicmp/model/JApiField.java
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ public Optional<CtField> getNewFieldOptional() {
@XmlElementWrapper(name = "modifiers")
@XmlElement(name = "modifier")
public List<? extends JApiModifier<? extends Enum<? extends Enum<?>>>> getModifiers() {
return Arrays.asList(this.accessModifier, this.staticModifier, this.finalModifier, this.syntheticModifier);
return Arrays.asList(this.accessModifier, this.staticModifier, this.finalModifier, this.transientModifier, this.syntheticModifier);
}

@XmlTransient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,8 @@ private void processFieldChanges(StringBuilder sb, JApiClass jApiClass) {
for (JApiField jApiField : jApiFields) {
sb.append(tabs(1)).append(signs(jApiField)).append(" ").append(jApiField.getChangeStatus()).append(" FIELD: ")
.append(accessModifierAsString(jApiField)).append(staticModifierAsString(jApiField))
.append(finalModifierAsString(jApiField)).append(syntheticModifierAsString(jApiField))
.append(finalModifierAsString(jApiField)).append(transientModifierAsString(jApiField))
.append(syntheticModifierAsString(jApiField))
.append(fieldTypeChangeAsString(jApiField));
appendGenericTypes(sb, jApiField);
sb.append(" ").append(jApiField.getName()).append('\n');
Expand All @@ -444,6 +445,11 @@ private String finalModifierAsString(JApiHasFinalModifier hasFinalModifier) {
return modifierAsString(modifier, FinalModifier.NON_FINAL);
}

private String transientModifierAsString(JApiHasTransientModifier hasTransientModifier) {
JApiModifier<TransientModifier> modifier = hasTransientModifier.getTransientModifier();
return modifierAsString(modifier, TransientModifier.NON_TRANSIENT);
}

private String staticModifierAsString(JApiHasStaticModifier hasStaticModifier) {
JApiModifier<StaticModifier> modifier = hasStaticModifier.getStaticModifier();
return modifierAsString(modifier, StaticModifier.NON_STATIC);
Expand Down
3 changes: 3 additions & 0 deletions japicmp/src/main/resources/html.xslt
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,9 @@
<xsl:when test="$modifier = 'NON_FINAL'">
<xsl:if test="$changeStatus = 'MODIFIED'">not_final</xsl:if>
</xsl:when>
<xsl:when test="$modifier = 'NON_TRANSIENT'">
<xsl:if test="$changeStatus = 'MODIFIED'">not_transient</xsl:if>
</xsl:when>
<xsl:when test="$modifier = 'NON_STATIC'">
<xsl:if test="$changeStatus = 'MODIFIED'">not_static</xsl:if>
</xsl:when>
Expand Down
60 changes: 60 additions & 0 deletions japicmp/src/test/java/japicmp/compat/CompatibilityChangesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,36 @@ public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
assertThat(jApiField.isBinaryCompatible(), is(false));
}

@Test
public void testFieldNowTransient() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
options.setAccessModifier(AccessModifier.PRIVATE);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).name("field").addToClass(ctClass);
return Collections.singletonList(ctClass);
}

@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").addToClassPool(classPool);
CtFieldBuilder.create().transientAccess().type(CtClass.intType).name("field").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.MODIFIED));
assertThat(jApiClass.isBinaryCompatible(), is(true));
assertThat(jApiClass.isSourceCompatible(), is(true));
JApiField jApiField = getJApiField(jApiClass.getFields(), "field");
assertThat(jApiField.getCompatibilityChanges(), hasItem(JApiCompatibilityChange.FIELD_NOW_TRANSIENT));
assertThat(jApiField.isBinaryCompatible(), is(true));
assertThat(jApiField.isBinaryCompatible(), is(true));
}

@Test
public void testFieldNowStatic() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
Expand Down Expand Up @@ -825,6 +855,36 @@ public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
assertThat(jApiField.isBinaryCompatible(), is(false));
}

@Test
public void testFieldNoLongerTransient() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
options.setAccessModifier(AccessModifier.PRIVATE);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").addToClassPool(classPool);
CtFieldBuilder.create().transientAccess().type(CtClass.intType).name("field").addToClass(ctClass);
return Collections.singletonList(ctClass);
}

@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).name("field").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.MODIFIED));
assertThat(jApiClass.isBinaryCompatible(), is(true));
assertThat(jApiClass.isSourceCompatible(), is(true));
JApiField jApiField = getJApiField(jApiClass.getFields(), "field");
assertThat(jApiField.getCompatibilityChanges(), hasItem(JApiCompatibilityChange.FIELD_NO_LONGER_TRANSIENT));
assertThat(jApiField.isBinaryCompatible(), is(true));
assertThat(jApiField.isBinaryCompatible(), is(true));
}

@Test
public void testFieldNoLongerStatic() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
Expand Down
5 changes: 5 additions & 0 deletions japicmp/src/test/java/japicmp/util/CtFieldBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ public CtFieldBuilder protectedAccess() {
return this;
}

public CtFieldBuilder transientAccess() {
this.modifier = this.modifier | Modifier.TRANSIENT;
return this;
}

public CtFieldBuilder finalAccess() {
this.modifier = this.modifier | Modifier.FINAL;
return this;
Expand Down
Loading