changeset 7354:867ec7c2a9ca

added support for writing substitutions for methods in package private classes
author Doug Simon <doug.simon@oracle.com>
date Fri, 11 Jan 2013 17:50:13 +0100
parents 8f7be0c45a82
children 8c163cfda1e5
files graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java
diffstat 2 files changed, 37 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java	Fri Jan 11 15:05:31 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java	Fri Jan 11 17:50:13 2013 +0100
@@ -31,7 +31,24 @@
 @Target(ElementType.TYPE)
 public @interface ClassSubstitution {
 
-    Class<?> value();
+    /**
+     * Specifies the substituted class.
+     * <p>
+     * If the default value is specified for this element, then a non-default
+     * value must be given for the {@link #className()} element.
+      */
+    Class<?> value() default ClassSubstitution.class;
+
+    /**
+     * Specifies the substituted class.
+     * <p>
+     * This method is provided for cases where the substituted class
+     * is not accessible (according to Java language access control rules).
+     * <p>
+     * If the default value is specified for this element, then a non-default
+     * value must be given for the {@link #value()} element.
+     */
+    String className() default "";
 
     /**
      * Used to map a substitute method to an original method where the default mapping
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Fri Jan 11 15:05:31 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Fri Jan 11 17:50:13 2013 +0100
@@ -79,13 +79,30 @@
      * annotated with {@link Snippet}.
      */
     public void install(Class<? extends SnippetsInterface> snippetsHolder) {
-        if (snippetsHolder.isAnnotationPresent(ClassSubstitution.class)) {
-            installSubstitutions(snippetsHolder, snippetsHolder.getAnnotation(ClassSubstitution.class).value());
+        ClassSubstitution classSubs = snippetsHolder.getAnnotation(ClassSubstitution.class);
+        if (classSubs != null) {
+            Class< ? > originalClass = getOriginalClass(classSubs);
+            installSubstitutions(snippetsHolder, originalClass);
         } else {
             installSnippets(snippetsHolder);
         }
     }
 
+    private static Class< ? > getOriginalClass(ClassSubstitution classSubs) throws GraalInternalError {
+        Class<?> originalClass = classSubs.value();
+        if (originalClass == ClassSubstitution.class) {
+            assert !classSubs.className().isEmpty();
+            try {
+                originalClass = Class.forName(classSubs.className());
+            } catch (ClassNotFoundException e) {
+                throw new GraalInternalError("Could not resolve substituted class " + classSubs.className(), e);
+            }
+        } else {
+            assert classSubs.className().isEmpty();
+        }
+        return originalClass;
+    }
+
     private void installSnippets(Class< ? extends SnippetsInterface> clazz) {
         for (Method method : clazz.getDeclaredMethods()) {
             if (method.getAnnotation(Snippet.class) != null) {