Skip to content

Commit

Permalink
Merge pull request #243 from alexfedorenchik/synthetics
Browse files Browse the repository at this point in the history
Handling of SYNTHETIC and BRIDGE modifiers added
  • Loading branch information
codecholeric authored Oct 20, 2019
2 parents e1d5cc2 + e862fae commit 12e3984
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ public enum JavaModifier {
@PublicAPI(usage = ACCESS)
SYNCHRONIZED(EnumSet.of(ApplicableType.METHOD), Opcodes.ACC_SYNCHRONIZED),
@PublicAPI(usage = ACCESS)
NATIVE(EnumSet.of(ApplicableType.METHOD), Opcodes.ACC_NATIVE);
NATIVE(EnumSet.of(ApplicableType.METHOD), Opcodes.ACC_NATIVE),
@PublicAPI(usage = ACCESS)
BRIDGE(EnumSet.of(ApplicableType.METHOD), Opcodes.ACC_BRIDGE),
@PublicAPI(usage = ACCESS)
SYNTHETIC(EnumSet.allOf(ApplicableType.class), Opcodes.ACC_SYNTHETIC);

private final Set<ApplicableType> applicableTo;
private final int asmAccessFlag;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
import com.tngtech.archunit.core.importer.testexamples.simpleimport.InterfaceToImport;
import com.tngtech.archunit.core.importer.testexamples.simplenames.SimpleNameExamples;
import com.tngtech.archunit.core.importer.testexamples.specialtargets.ClassCallingSpecialTarget;
import com.tngtech.archunit.core.importer.testexamples.syntheticimport.ClassWithSynthetics;
import com.tngtech.archunit.testutil.LogTestRule;
import com.tngtech.archunit.testutil.OutsideOfClassPathRule;
import com.tngtech.java.junit.dataprovider.DataProvider;
Expand All @@ -194,11 +195,13 @@
import static com.tngtech.archunit.core.domain.JavaConstructor.CONSTRUCTOR_NAME;
import static com.tngtech.archunit.core.domain.JavaFieldAccess.AccessType.GET;
import static com.tngtech.archunit.core.domain.JavaFieldAccess.AccessType.SET;
import static com.tngtech.archunit.core.domain.JavaModifier.BRIDGE;
import static com.tngtech.archunit.core.domain.JavaModifier.FINAL;
import static com.tngtech.archunit.core.domain.JavaModifier.PRIVATE;
import static com.tngtech.archunit.core.domain.JavaModifier.PROTECTED;
import static com.tngtech.archunit.core.domain.JavaModifier.PUBLIC;
import static com.tngtech.archunit.core.domain.JavaModifier.STATIC;
import static com.tngtech.archunit.core.domain.JavaModifier.SYNTHETIC;
import static com.tngtech.archunit.core.domain.JavaModifier.TRANSIENT;
import static com.tngtech.archunit.core.domain.JavaModifier.VOLATILE;
import static com.tngtech.archunit.core.domain.JavaStaticInitializer.STATIC_INITIALIZER_NAME;
Expand Down Expand Up @@ -384,6 +387,20 @@ public void handles_static_modifier_of_nested_classes() throws Exception {
assertThat(classes.get(ClassWithNestedClass.StaticNestedInterface.class).getModifiers()).as("modifiers of ClassWithNestedClass.StaticNestedInterface").contains(STATIC);
}

@Test
public void handles_synthetic_modifiers() throws Exception {
JavaClasses classes = classesIn("testexamples/syntheticimport").classes;

JavaField syntheticField = getOnlyElement(classes.get(ClassWithSynthetics.ClassWithSyntheticField.class).getFields());
assertThat(syntheticField.getModifiers()).as("modifiers of field in ClassWithSynthetics.ClassWithSyntheticField").contains(SYNTHETIC);

JavaMethod syntheticMethod = getOnlyElement(classes.get(ClassWithSynthetics.ClassWithSyntheticMethod.class).getMethods());
assertThat(syntheticMethod.getModifiers()).as("modifiers of method in ClassWithSynthetics.ClassWithSyntheticMethod").contains(SYNTHETIC);

JavaMethod compareMethod = classes.get(ClassWithSynthetics.class).getMethod("compare", Object.class, Object.class);
assertThat(compareMethod.getModifiers()).as("modifiers of bridge method in ClassWithSynthetics").contains(BRIDGE, SYNTHETIC);
}

@Test
public void imports_jdk_classes() {
JavaClasses classes = new ClassFileImporter().importClasses(File.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.tngtech.archunit.core.importer.testexamples.syntheticimport;

import java.util.Comparator;

@SuppressWarnings({"unused", "InnerClassMayBeStatic"})
public class ClassWithSynthetics implements Comparator<String> {
// for (non-static) inner classes the compiler must create a synthetic field, holding a reference to the outer class
public class ClassWithSyntheticField {
}

// for accesses to private fields of inner classes, the compiler must create a synthetic method to allow access to this field
// thus together with the method 'getNestedField', this causes the existence of a synthetic method
public class ClassWithSyntheticMethod {
private String nestedField;
}

public String getNestedField() {
return new ClassWithSyntheticMethod().nestedField;
}

// to cover type erasure, the compiler must add a bridge method with signature compare(Object, Object) here
@Override
public int compare(String o1, String o2) {
return 0;
}
}

0 comments on commit 12e3984

Please sign in to comment.