[jboss-cvs] JBossAS SVN: r63858 - projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Jul 6 01:39:30 EDT 2007


Author: flavia.rainone at jboss.com
Date: 2007-07-06 01:39:30 -0400 (Fri, 06 Jul 2007)
New Revision: 63858

Modified:
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/Algorithm.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ParamTypeAssignabilityAlgorithm.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableHierarchy.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableNode.java
Log:
[JBAOP-420] Implemented reverse algorithm

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/Algorithm.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/Algorithm.java	2007-07-06 05:00:42 UTC (rev 63857)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/Algorithm.java	2007-07-06 05:39:30 UTC (rev 63858)
@@ -47,10 +47,10 @@
       }
       
       protected boolean assignValue(Type type, Type fromType,
-            VariableHierarchy variableHierarchy, boolean boundLevel)
+            VariableHierarchy variableHierarchy)
       {
          VariableNode node = variableHierarchy.getVariableNode((TypeVariable) type);
-         return node.assignValue(fromType, boundLevel);
+         return node.assignValue(fromType);
       }
       
       protected boolean addBound(Type type, Type fromType,
@@ -73,10 +73,10 @@
       }
       
       protected boolean assignValue(Type type, Type fromType,
-            VariableHierarchy variableHierarchy, boolean boundLevel)
+            VariableHierarchy variableHierarchy)
       {
          VariableNode fromNode = variableHierarchy.getVariableNode((TypeVariable) fromType);
-         return fromNode.assignValue(type, boundLevel);
+         return fromNode.assignValue(type);
       }
       
       protected boolean addBound(Type type, Type fromType,
@@ -91,7 +91,7 @@
    protected abstract boolean isVariableOperationApplicable(Type type, Type fromType);
    
    protected abstract boolean assignValue(Type type, Type fromType,
-         VariableHierarchy variableHierarchy, boolean boundLevel);
+         VariableHierarchy variableHierarchy);
    
    protected abstract boolean addBound(Type type, Type fromType,
          VariableHierarchy variableHierarchy);
@@ -114,8 +114,7 @@
       }
       if (type instanceof ParameterizedType)
       {
-         return isAssignable((ParameterizedType) type, fromType,
-               variableHierarchy, false);
+         return isAssignable((ParameterizedType) type, fromType, variableHierarchy);
       }
       if (type instanceof WildcardType)
       {
@@ -211,7 +210,7 @@
     * @param type
     * @return
     */
-   private Type[] getConcreteBounds(Type type)
+   public static Type[] getConcreteBounds(Type type)
    {
       TypeVariable current = (TypeVariable) type;
       Type[] bounds = current.getBounds();
@@ -224,22 +223,30 @@
    }
 
    private boolean isAssignable(ParameterizedType paramType, Type fromType, 
-         VariableHierarchy variableHierarchy, boolean boundLevel)
+         VariableHierarchy variableHierarchy)
    {
       if (fromType instanceof TypeVariable)
       {
          Type[] concreteBounds = getConcreteBounds((TypeVariable) fromType);
-         for (int i = 0; i < concreteBounds.length; i++)
+         try
          {
-            if (isAssignable(paramType, concreteBounds[i], variableHierarchy, true))
+            variableHierarchy.startRealBoundComparation();
+            for (int i = 0; i < concreteBounds.length; i++)
             {
-               return true;
+               if (isAssignable(paramType, concreteBounds[i], variableHierarchy))
+               {
+                  return true;
+               }
             }
          }
+         finally
+         {
+            variableHierarchy.finishRealBoundComparation();
+         }
          return false;
       }
       return ParamTypeAssignabilityAlgorithm.isAssignable(
-            paramType, fromType, CHECKER, this, variableHierarchy, boundLevel);
+            paramType, fromType, CHECKER, this, variableHierarchy);
    }
 
    private boolean isAssignable(GenericArrayType arrayType, Type fromType,
@@ -268,11 +275,11 @@
    private static final ParamTypeAssignabilityAlgorithm.EqualityChecker<Algorithm, VariableHierarchy> CHECKER
       = new ParamTypeAssignabilityAlgorithm.EqualityChecker<Algorithm, VariableHierarchy>()
    {
-      public boolean isSame(Type type, Type fromType, Algorithm client, VariableHierarchy variableHierarchy, boolean boundLevel)
+      public boolean isSame(Type type, Type fromType, Algorithm client, VariableHierarchy variableHierarchy)
       {
          if(Algorithm.VARIABLE_TARGET.isVariableOperationApplicable(type, fromType))
          {
-            return Algorithm.VARIABLE_TARGET.assignValue(type, fromType, variableHierarchy, boundLevel);
+            return Algorithm.VARIABLE_TARGET.assignValue(type, fromType, variableHierarchy);
          }
          if (type instanceof Class)
          {
@@ -287,12 +294,12 @@
             ParameterizedType fromParamType = (ParameterizedType) fromType;
             ParameterizedType paramType = (ParameterizedType) type;
             if (!isSame(paramType.getRawType(), fromParamType.getRawType(), client,
-                  variableHierarchy, boundLevel))
+                  variableHierarchy))
             {
                return false;
             }
             return isSame(paramType.getActualTypeArguments(),
-                  fromParamType.getActualTypeArguments(), client, variableHierarchy, boundLevel);
+                  fromParamType.getActualTypeArguments(), client, variableHierarchy);
          }
          if (type instanceof WildcardType)
          {

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ParamTypeAssignabilityAlgorithm.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ParamTypeAssignabilityAlgorithm.java	2007-07-06 05:00:42 UTC (rev 63857)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ParamTypeAssignabilityAlgorithm.java	2007-07-06 05:39:30 UTC (rev 63858)
@@ -58,11 +58,11 @@
        *                      fromArguments</code> list can be assigned to a list of
        *                      <code>arguments</code> type.
        */
-      protected boolean isSame(Type[] arguments, Type[] fromArguments, C caller, T token, boolean assignAllowed)
+      protected boolean isSame(Type[] arguments, Type[] fromArguments, C caller, T token)
       {
          for (int i = 0; i < arguments.length; i++)
          {
-            if (!isSame(arguments[i], fromArguments[i], caller, token, assignAllowed))
+            if (!isSame(arguments[i], fromArguments[i], caller, token))
             {
                return false;
             }
@@ -87,7 +87,7 @@
        *                      <code>fromArgument</code> as the equivalent parameter
        *                      value
        */
-      abstract boolean isSame(Type argument, Type fromArgument, C caller, T token, boolean assignAllowed);
+      abstract boolean isSame(Type argument, Type fromArgument, C caller, T token);
    }
 
    /**
@@ -100,7 +100,7 @@
     * @return
     */
    public static<C, T> boolean isAssignable(ParameterizedType paramType, Type fromType,
-         EqualityChecker<C, T> checker, C caller, T checkerToken, boolean assignAllowed)
+         EqualityChecker<C, T> checker, C caller, T checkerToken)
    {
       Class<?> fromRaw = null;
       ParameterizedType fromParamType = null;
@@ -129,7 +129,7 @@
          {
             // compare arguments with arguments
             return checker.isSame(paramType.getActualTypeArguments(),
-                  fromParamType.getActualTypeArguments(), caller, checkerToken, assignAllowed);
+                  fromParamType.getActualTypeArguments(), caller, checkerToken);
          }
          else if (!desiredType.isAssignableFrom(fromRaw))
          {
@@ -147,6 +147,6 @@
       {
          return true; // TODO with Warning
       }
-      return checker.isSame(paramType.getActualTypeArguments(), arguments, caller, checkerToken, assignAllowed);
+      return checker.isSame(paramType.getActualTypeArguments(), arguments, caller, checkerToken);
    }
 }
\ No newline at end of file

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableHierarchy.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableHierarchy.java	2007-07-06 05:00:42 UTC (rev 63857)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableHierarchy.java	2007-07-06 05:39:30 UTC (rev 63858)
@@ -35,6 +35,7 @@
 {
    private Map<String, VariableNode> map;
    private int boundComparation;
+   private int realBoundComparation;
    
    public VariableHierarchy()
    {
@@ -67,4 +68,19 @@
    {
       return this.boundComparation > 0;
    }
+   
+   void startRealBoundComparation()
+   {
+      this.realBoundComparation ++;
+   }
+   
+   void finishRealBoundComparation()
+   {
+      this.realBoundComparation --;
+   }
+   
+   boolean isRealBoundComparation()
+   {
+      return this.realBoundComparation > 0;
+   }
 }
\ No newline at end of file

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableNode.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableNode.java	2007-07-06 05:00:42 UTC (rev 63857)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableNode.java	2007-07-06 05:39:30 UTC (rev 63858)
@@ -42,6 +42,7 @@
    private VariableNode previous;
    private VariableNode next;
    private Collection<Type> lowerBounds;
+   private Collection<Type> upperBounds;
    private TypeVariable variable;
    private Type assignedValue;
    
@@ -49,7 +50,8 @@
    {
       this.hierarchy = hierarchy;
       this.variable = content;
-      lowerBounds = new HashSet<Type>();
+      this.lowerBounds = new HashSet<Type>();
+      this.upperBounds = new HashSet<Type>();
       Type[] bounds = content.getBounds();
       if (bounds.length == 1 && bounds[0] instanceof TypeVariable)
       {
@@ -59,35 +61,28 @@
       }
    }
    
-   public final boolean assignValue(Type value, boolean boundLevel)
+   public final boolean assignValue(Type value)
    {
+      // assigned bounds can only be assigned to concrete types
       if (this.hierarchy.isBoundComparation() && !(value instanceof Class)
             && !(value instanceof ParameterizedType))
       {
          return false;
       }
-      
-      if (boundLevel && value instanceof WildcardType)
+      // real bounds can have values assigned to variables
+      if (this.hierarchy.isRealBoundComparation() && (value instanceof WildcardType))
       {
          return false;
       }
       
       if (this.assignedValue != null)
       {
-         // TODO HERE1 HERE HERE HERE HERE
          return isSame(value, this.assignedValue, true);
       }
       
-      // TODO fix this
-      /*if (value instanceof WildcardType)
+      if (!isInsideUpperBounds(value, false) || !areLowerBoundsInside(value, false))
       {
          return false;
-      }*/
-      
-      if (!isInsideBounds(value, true) ||
-            (this.previous != null && !this.previous.areBoundsInside(value)))
-      {
-         return false;
       }
       this.assignedValue = value;
       return true;
@@ -95,12 +90,11 @@
    
    public final boolean addLowerBound(Type lowerBound)
    {
-      if (!isInsideBounds(lowerBound, false) ||
-            (this.previous != null && !this.previous.areBoundsInside(lowerBound)))
+      if (!isInsideUpperBounds(lowerBound, false) ||
+            (this.previous != null && !this.previous.areLowerBoundsInside(lowerBound, true)))
       {
          return false;
       }
-      // TODO check this
       if (lowerBound instanceof TypeVariable)
       {
          Type[] bounds = ((TypeVariable) lowerBound).getBounds();
@@ -115,16 +109,39 @@
    
    public final boolean addUpperBound(Type upperBound)
    {
-      // TODO
+      if ((this.next != null && !this.next.isInsideUpperBounds(upperBound, true)) ||
+          !areLowerBoundsInside(upperBound, false))
+      {
+         return false;
+      }
+      if (upperBound instanceof TypeVariable)
+      {
+         Type[] bounds = ((TypeVariable) upperBound).getBounds();
+         this.upperBounds.add(new ChoiceBound((TypeVariable) upperBound, bounds));
+      }
+      else
+      {
+         this.upperBounds.add(upperBound);
+      }
       return true;
    }
    
-   private boolean areBoundsInside(Type bound)
+   private boolean areLowerBoundsInside(Type bound, boolean checkUpperBounds)
    {
       if (this.assignedValue != null && !isAssignable(bound, assignedValue))
       {
          return false;
       }
+      if (checkUpperBounds)
+      {
+         for (Type upperBound: this.upperBounds)
+         {
+            if (!isAssignable(bound, upperBound))
+            {
+               return false;
+            }
+         }
+      }
       for (Type lowerBound: this.lowerBounds)
       {
          if (!isAssignable(bound, lowerBound))
@@ -134,12 +151,12 @@
       }
       if (previous != null)
       {
-         return previous.areBoundsInside(bound);
+         return previous.areLowerBoundsInside(bound, true);
       }
       return true;
    }
    
-   private boolean isInsideBounds(Type lowerBound, boolean checkLowerBounds)
+   private boolean isInsideUpperBounds(Type lowerBound, boolean checkLowerBounds)
    {
       if (this.assignedValue != null && !isAssignable(lowerBound, assignedValue))
       {
@@ -155,6 +172,13 @@
             }
          }
       }
+      for (Type upperBound: upperBounds)
+      {
+         if (!isAssignable(upperBound, lowerBound))
+         {
+            return false;
+         }
+      }
       if (next == null)
       {
          Type[] bounds = variable.getBounds();
@@ -175,69 +199,119 @@
          }
          return true;
       }
-      return next.isInsideBounds(lowerBound, true);
+      return next.isInsideUpperBounds(lowerBound, true);
    }
    
-   private boolean isAssignable(TypeVariable type, TypeVariable fromType)
+   private static boolean isSame(Type argument, Type fromArgument, boolean argumentAssigned)
    {
-      Type[] fromBounds = fromType.getBounds();
-      if (type == fromType)
+      if (argument instanceof WildcardType)
       {
-         return true;
-      }
-      while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
-      {
-         if (fromBounds[0] == type)
+         WildcardType wildcard = (WildcardType) argument;
+         Type[] upperBounds = wildcard.getUpperBounds();
+         Type[] lowerBounds = wildcard.getLowerBounds();
+         if (fromArgument instanceof WildcardType)
          {
+            WildcardType fromWildcard = (WildcardType) fromArgument;
+            Type[] fromUpperBounds = fromWildcard.getUpperBounds();
+            if (!isAssignable(upperBounds, fromUpperBounds))
+            {
+               return false;
+            }
+            
+            Type[] fromLowerBounds = fromWildcard.getLowerBounds();
+            outer: for (int i = 0; i < fromLowerBounds.length; i++)
+            {
+               for (int j = 0; j < lowerBounds.length; j++)
+               {
+                  if (isAssignable(fromLowerBounds[i], lowerBounds[j]))
+                  {
+                     continue outer;
+                  }
+               }
+               return false;
+            }
             return true;
          }
-         fromType = (TypeVariable) fromBounds[0];
-         fromBounds = fromType.getBounds();
+         if (argumentAssigned)
+         {
+            return false;
+         }
+         if(fromArgument instanceof TypeVariable)
+         {
+            if (!isAssignable(upperBounds, ((TypeVariable) fromArgument).getBounds()))
+            {
+               return false;
+            }
+         }
+         else
+         {
+            for (int i = 0; i < upperBounds.length; i++)
+            {
+               if (!isAssignable(upperBounds[i], fromArgument))
+               {
+                  return false;
+               }
+            }
+            return true;
+         }
       }
-      TypeVariable variable = (TypeVariable) type;
-      Type[] bounds = variable.getBounds();
-      while (bounds.length == 1 && bounds[0] instanceof TypeVariable)
+      else if (argument instanceof GenericArrayType)
       {
-         if (bounds[0] == fromType)
+         if (fromArgument instanceof GenericArrayType)
          {
+            return isSame(((GenericArrayType) argument).getGenericComponentType(),
+                  ((GenericArrayType) fromArgument).getGenericComponentType(),
+                  argumentAssigned);
+         }
+         else
+         {
             return false;
          }
-         variable = (TypeVariable) bounds[0];
-         bounds = variable.getBounds();
       }
-      // TODO check if this should really be removed
-      /*outer: for (int i = 0; i < bounds.length; i++)
+      return argument.equals(fromArgument); // TODO check this works correctly
+   }
+
+   private static boolean isAssignable(Type[] upperBounds, Type[] fromUpperBounds)
+   {
+      outer: for (int i = 0; i < upperBounds.length; i++)
       {
-         for (int j = 0; j < fromBounds.length; j++)
+         for (int j = 0; j < fromUpperBounds.length; j++)
          {
-            if (isAssignable(bounds[i], fromBounds[j]))
+            if (isAssignable(upperBounds[i], fromUpperBounds[j]))
             {
                continue outer;
             }
          }
          return false;
       }
-      return true;*/
-      return false;
+      return true;
    }
    
    // both type and bound belong to the same context
-   private boolean isAssignable(Type type, Type fromType)
+   private static boolean isAssignable(Type type, Type fromType)
    {
       if (fromType instanceof TypeVariable)
       {
          TypeVariable fromVariable = (TypeVariable) fromType;
          if (type instanceof TypeVariable)
          {
-            return isAssignable((TypeVariable) type, fromVariable);
+            if (type == fromType)
+            {
+               return true;
+            }
+            Type[] fromBounds = fromVariable.getBounds();
+            while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
+            {
+               if (fromBounds[0] == type)
+               {
+                  return true;
+               }
+               fromVariable = (TypeVariable) fromBounds[0];
+               fromBounds = fromVariable.getBounds();
+            }
+            return false;
          }
-         Type[] fromBounds = fromVariable.getBounds();
-         TypeVariable temp = fromVariable;
-         while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
-         {
-            temp = (TypeVariable) fromBounds[0];
-            fromBounds = temp.getBounds();            
-         }
+         Type[] fromBounds = Algorithm.getConcreteBounds(fromVariable);
          for (Type fromBound: fromBounds)
          {
             if (isAssignable(type, fromBound))
@@ -322,7 +396,7 @@
       if (type instanceof ParameterizedType)
       {
          return ParamTypeAssignabilityAlgorithm.isAssignable(
-               (ParameterizedType) type, fromType, CHECKER, this, null, false);
+               (ParameterizedType) type, fromType, CHECKER, null, null);
       }
       if (type instanceof TypeVariable)
       {
@@ -352,103 +426,13 @@
       return !choiceBound.bounds.isEmpty();
    }
    
-   protected boolean isSame(Type argument, Type fromArgument, boolean argumentAssigned)
-   {
-      if (argument instanceof WildcardType)
-      {
-         WildcardType wildcard = (WildcardType) argument;
-         Type[] upperBounds = wildcard.getUpperBounds();
-         Type[] lowerBounds = wildcard.getLowerBounds();
-         if (fromArgument instanceof WildcardType)
-         {
-            WildcardType fromWildcard = (WildcardType) fromArgument;
-            Type[] fromUpperBounds = fromWildcard.getUpperBounds();
-            if (!isAssignable(upperBounds, fromUpperBounds))
-            {
-               return false;
-            }
-            
-            Type[] fromLowerBounds = fromWildcard.getLowerBounds();
-            outer: for (int i = 0; i < fromLowerBounds.length; i++)
-            {
-               for (int j = 0; j < lowerBounds.length; j++)
-               {
-                  if (isAssignable(fromLowerBounds[i], lowerBounds[j]))
-                  {
-                     continue outer;
-                  }
-               }
-               return false;
-            }
-            return true;
-         }
-         if (argumentAssigned)
-         {
-            return false;
-         }
-         if(fromArgument instanceof TypeVariable)
-         {
-            if (!isAssignable(upperBounds, ((TypeVariable) fromArgument).getBounds()))
-            {
-               return false;
-            }
-         }
-         else
-         {
-            for (int i = 0; i < upperBounds.length; i++)
-            {
-               if (!isAssignable(upperBounds[i], fromArgument))
-               {
-                  return false;
-               }
-            }
-            return true;
-         }
-      }
-      else if (argument instanceof GenericArrayType)
-      {
-         if (fromArgument instanceof GenericArrayType)
-         {
-            return isSame(((GenericArrayType) argument).getGenericComponentType(),
-                  ((GenericArrayType) fromArgument).getGenericComponentType(),
-                  argumentAssigned);
-         }
-         else
-         {
-            return false;
-         }
-      }
-      return argument.equals(fromArgument); // TODO check this works correctly
-   }
-
-   /**
-    * @param node
-    * @param upperBounds
-    * @param upperBounds
-    */
-   private boolean isAssignable(Type[] upperBounds, Type[] fromUpperBounds)
-   {
-      outer: for (int i = 0; i < upperBounds.length; i++)
-      {
-         for (int j = 0; j < fromUpperBounds.length; j++)
-         {
-            if (isAssignable(upperBounds[i], fromUpperBounds[j]))
-            {
-               continue outer;
-            }
-         }
-         return false;
-      }
-      return true;
-   }
-   
    private static ParamTypeAssignabilityAlgorithm.EqualityChecker<VariableNode, ?> CHECKER =
       new ParamTypeAssignabilityAlgorithm.EqualityChecker<VariableNode, Object>()
+   {
+      public boolean isSame(Type argument, Type fromArgument, VariableNode node,
+            Object token)
       {
-         public boolean isSame(Type argument, Type fromArgument, VariableNode node,
-               Object token, boolean boundLevel)
-         {
-            return node.isSame(argument, fromArgument, false);
-         }
-      };
+         return VariableNode.isSame(argument, fromArgument, false);
+      }
+   };
 }
\ No newline at end of file




More information about the jboss-cvs-commits mailing list