Skip to content
New issue

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

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

Already on GitHub? # to your account

fix(test): CtGenerationTest#testGenerateRoleHandler egg/chicken problem #2087

Merged
merged 1 commit into from
Jun 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/main/java/spoon/metamodel/Metamodel.java
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,16 @@ public static Set<CtType<?>> getAllMetamodelInterfaces() {
*/
public static Metamodel getInstance() {
if (instance == null) {
try {
//this is needed just for CtGenerationTest#testGenerateRoleHandler
//which must not use RoleHandler at time when RoleHandler is generated and Spoon model doesn't fit to old RoleHandlers
//to avoid egg/chicken problem
if ("true".equals(System.getProperty(MetamodelProperty.class.getName() + "-noRoleHandler"))) {
MetamodelProperty.useRuntimeMethodInvocation = true;
}
} catch (SecurityException e) {
//ignore that
}
instance = new Metamodel();
}
return instance;
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/spoon/metamodel/MetamodelProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import static spoon.metamodel.Metamodel.addUniqueObject;
import static spoon.metamodel.Metamodel.getOrCreate;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -39,6 +41,7 @@
import spoon.reflect.reference.CtTypeReference;
import spoon.support.DerivedProperty;
import spoon.support.UnsettableProperty;
import spoon.support.util.RtHelper;

/**
* Represents a property of the Spoon metamodel.
Expand Down Expand Up @@ -587,11 +590,27 @@ public RoleHandler getRoleHandler() {
return roleHandler;
}

static boolean useRuntimeMethodInvocation = false;

/**
* @param element an instance whose attribute value is read
* @return a value of attribute defined by this {@link MetamodelProperty} from the provided `element`
*/
public <T, U> U getValue(T element) {
if (useRuntimeMethodInvocation) {
MMMethod method = getMethod(MMMethodKind.GET);
if (method != null) {
Method rtMethod = RtHelper.getMethod(getOwner().getImplementationClass().getActualClass(), method.getName(), 0);
if (rtMethod != null) {
try {
return (U) rtMethod.invoke(element);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new SpoonException("Invokation of getter on " + toString() + " failed", e);
}
}
throw new SpoonException("Cannot invoke getter on " + toString());
}
}
return getRoleHandler().getValue(element);
}

Expand All @@ -600,6 +619,21 @@ public <T, U> U getValue(T element) {
* @param value to be set value of attribute defined by this {@link MetamodelProperty} on the provided `element`
*/
public <T, U> void setValue(T element, U value) {
if (useRuntimeMethodInvocation) {
MMMethod method = getMethod(MMMethodKind.SET);
if (method != null) {
Method rtMethod = RtHelper.getMethod(getOwner().getImplementationClass().getActualClass(), method.getName(), 1);
if (rtMethod != null) {
try {
rtMethod.invoke(element, value);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new SpoonException("Invokation of setter on " + toString() + " failed", e);
}
return;
}
throw new SpoonException("Cannot invoke setter on " + toString());
}
}
getRoleHandler().setValue(element, value);
}
}
8 changes: 7 additions & 1 deletion src/test/java/spoon/processing/CtGenerationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import spoon.generating.CtBiScannerGenerator;
import spoon.generating.ReplacementVisitorGenerator;
import spoon.generating.RoleHandlersGenerator;
import spoon.metamodel.MetamodelProperty;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtType;
import spoon.reflect.visitor.CtBiScannerDefault;
Expand Down Expand Up @@ -173,7 +174,12 @@ public void testGenerateRoleHandler() throws Exception {
launcher.addInputResource("./src/main/java/spoon/reflect/meta/impl/AbstractRoleHandler.java");
launcher.addProcessor(new RoleHandlersGenerator());
launcher.setOutputFilter(new RegexFilter("\\Q" + RoleHandlersGenerator.TARGET_PACKAGE + ".ModelRoleHandlers\\E.*"));
launcher.run();
try {
System.setProperty(MetamodelProperty.class.getName()+"-noRoleHandler", "true");
launcher.run();
} finally {
System.setProperty(MetamodelProperty.class.getName()+"-noRoleHandler", "false");
}

// cp ./target/generated/spoon/reflect/meta/impl/ModelRoleHandlers.java ./src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java
CtClass<Object> actual = build(new File(launcher.getModelBuilder().getSourceOutputDirectory()+"/spoon/reflect/meta/impl/ModelRoleHandlers.java")).Class().get("spoon.reflect.meta.impl.ModelRoleHandlers");
Expand Down