[jboss-cvs] JBossAS SVN: r63807 - projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Jul 3 20:21:41 EDT 2007
Author: flavia.rainone at jboss.com
Date: 2007-07-03 20:21:41 -0400 (Tue, 03 Jul 2007)
New Revision: 63807
Added:
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java
Removed:
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ContextualizedArguments.java
Modified:
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java
Log:
[JBAOP-420] New version of algorithm
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java 2007-07-03 23:53:31 UTC (rev 63806)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java 2007-07-04 00:21:41 UTC (rev 63807)
@@ -61,13 +61,13 @@
if (type instanceof TypeVariable)
{
VariableNode node = null;
- TypeVariable fromVariable = (TypeVariable) type;
- if (variableHierarchy.containsKey(fromVariable.getName()))
+ TypeVariable variable = (TypeVariable) type;
+ if (variableHierarchy.containsKey(variable.getName()))
{
- node = variableHierarchy.get(fromVariable.getName());
+ node = variableHierarchy.get(variable.getName());
} else
{
- node = new VariableNode(fromVariable, variableHierarchy);
+ node = new VariableNode(variable, variableHierarchy);
}
return node.addLowerBound(fromType);
}
@@ -165,7 +165,8 @@
}
return false;
}
- return ContextualizedArguments.isAssignable(CHECKER, paramType, fromType, variableHierarchy);
+ return ParamTypeAssignabilityAlgorithm.isAssignable(
+ paramType, fromType, CHECKER, variableHierarchy);
}
private boolean isAssignable(GenericArrayType arrayType, Type fromType,
@@ -190,75 +191,77 @@
return false;
}
- // ////////////////////////////////////////////////////////
- private static final ContextualizedArguments.EqualityChecker<Map<String, VariableNode>> CHECKER
- = new ContextualizedArguments.EqualityChecker<Map<String,VariableNode>>()
+ //////////////////////////////////////////////////////////
+ private static final ParamTypeAssignabilityAlgorithm.EqualityChecker<Map<String, VariableNode>> CHECKER
+ = new ParamTypeAssignabilityAlgorithm.EqualityChecker<Map<String,VariableNode>>()
+ {
+ public boolean isSame(Type type, Type fromType, Map<String, VariableNode> variableHierarchy)
{
-
- public boolean isSame(Type type2, Type type1, Map<String, VariableNode> variableHierarchy)
+ if (type instanceof TypeVariable)
{
- if (type2 instanceof TypeVariable)
+ TypeVariable variable = (TypeVariable) type;
+ VariableNode node = variableHierarchy.containsKey(variable.getName())?
+ variableHierarchy.get(variable.getName()):
+ new VariableNode(variable, variableHierarchy);
+ return node.assignValue(fromType);
+ }
+ if (type instanceof Class)
+ {
+ return type.equals(fromType);
+ }
+ if (type instanceof ParameterizedType)
+ {
+ if (!(fromType instanceof ParameterizedType))
{
- TypeVariable variable2 = (TypeVariable) type2;
- VariableNode node = variableHierarchy.containsKey(variable2.getName())?
- variableHierarchy.get(variable2.getName()):
- new VariableNode(variable2, variableHierarchy);
- return node.assignValue(type1);
+ return false;
}
- if (type2 instanceof Class)
+ ParameterizedType fromParamType = (ParameterizedType) fromType;
+ ParameterizedType paramType = (ParameterizedType) type;
+ if (!isSame(paramType.getRawType(), fromParamType.getRawType(),
+ variableHierarchy))
{
- return type1.equals(type2);
+ return false;
}
- if (type2 instanceof ParameterizedType)
+ return isSame(paramType.getActualTypeArguments(),
+ fromParamType.getActualTypeArguments(), variableHierarchy);
+ }
+ if (type instanceof WildcardType)
+ {
+ Type[] upperBounds = ((WildcardType) type).getUpperBounds();
+ Algorithm algorithm = Algorithm.getInstance();
+ if (fromType instanceof WildcardType)
{
- if (!(type1 instanceof ParameterizedType))
+ Type[] fromUpperBounds = ((WildcardType) fromType).getUpperBounds();
+ outer: for (int i = 0; i < upperBounds.length; i++)
{
+ for (int j = 0; j < fromUpperBounds.length; j++)
+ {
+ if (algorithm.isAssignable(upperBounds[i],
+ fromUpperBounds[i], variableHierarchy))
+ {
+ continue outer;
+ }
+ }
return false;
}
- ParameterizedType paramType1 = (ParameterizedType) type1;
- ParameterizedType paramType2 = (ParameterizedType) type2;
- if (!isSame(paramType2.getRawType(), paramType1.getRawType(), variableHierarchy))
- {
- return false;
- }
- return isSame(paramType2.getActualTypeArguments(), paramType1.getActualTypeArguments(), variableHierarchy);
+ // TODO lower bounds: inverted algorithm
+ return true;
}
- if (type2 instanceof WildcardType)
+ else
{
- Type[] upperBounds2 = ((WildcardType) type2).getUpperBounds();
- Algorithm algorithm = Algorithm.getInstance();
- if (type1 instanceof WildcardType)
+ for (int i = 0; i < upperBounds.length; i++)
{
- Type[] upperBounds1 = ((WildcardType) type1).getUpperBounds();
- outer: for (int i = 0; i < upperBounds2.length; i++)
+ if (!algorithm.isAssignable(upperBounds[i], fromType,
+ variableHierarchy))
{
- for (int j = 0; j < upperBounds1.length; j++)
- {
- if (algorithm.isAssignable(upperBounds2[i], upperBounds1[i], variableHierarchy))
- {
- continue outer;
- }
- }
return false;
}
- // TODO lower bounds: inverted algorithm
- return true;
}
- else
- {
- for (int i = 0; i < upperBounds2.length; i++)
- {
- if (!algorithm.isAssignable(upperBounds2[i], type1, variableHierarchy))
- {
- return false;
- }
- }
- // TODO lower bounds: inverted algorithm
- return true;
- }
+ // TODO lower bounds: inverted algorithm
+ return true;
}
- return true;
}
- };
-
+ return true;
+ }
+ };
}
\ No newline at end of file
Added: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java (rev 0)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java 2007-07-04 00:21:41 UTC (rev 63807)
@@ -0,0 +1,490 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.advice.annotation;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+/**
+ * Argument contextualizer. Performs contextualization of arguments through hierarchy
+ *
+ *
+ * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ArgumentContextualizer
+{
+ public static final Type[] getContextualizedArguments(ParameterizedType paramType,
+ Class rawType, Class desiredType)
+ {
+ ArgumentContextualizer contextualizedArguments = getContextualizedArgumentsInternal(
+ desiredType, rawType);
+ if (contextualizedArguments == null)
+ {
+ return null;
+ }
+ if (paramType != null)
+ {
+ contextualizedArguments.contextualizeVariables(null, paramType);
+ }
+ return contextualizedArguments.getArguments();
+ }
+
+
+ private static final ArgumentContextualizer getContextualizedArgumentsInternal(
+ Class<?> desiredType, Class<?> classType)
+ {
+ Type superType = null;
+ if (desiredType.isInterface())
+ {
+ for (Type superInterface : classType.getGenericInterfaces())
+ {
+ if ((superInterface instanceof Class && desiredType
+ .isAssignableFrom((Class<?>) superInterface))
+ || (superInterface instanceof ParameterizedType &&
+ desiredType.isAssignableFrom((Class<?>)
+ ((ParameterizedType) superInterface).getRawType())))
+ {
+ superType = superInterface;
+ break;
+ }
+ }
+ }
+ if (superType == null)
+ {
+ superType = classType.getGenericSuperclass();
+ }
+ ArgumentContextualizer result = null;
+ if (superType instanceof Class)
+ {
+ if (superType == desiredType)
+ {
+ return null;
+ }
+ result = getContextualizedArgumentsInternal(desiredType,
+ (Class<?>) superType);
+ }
+ else
+ {
+ ParameterizedType superParamType = (ParameterizedType) superType;
+ Class<?> superClassType = (Class<?>) superParamType.getRawType();
+ if (superClassType == desiredType)
+ {
+ return new ArgumentContextualizer(superParamType
+ .getActualTypeArguments(), classType);
+ }
+ else
+ {
+ result = getContextualizedArgumentsInternal(desiredType,
+ superClassType);
+ }
+ }
+ if (result == null
+ || !result.contextualizeVariables(classType, superType))
+ {
+ return null;
+ }
+ return result;
+ }
+
+
+ private Type[] arguments;
+ private LinkedList<VariableReplacer> variableReplacements;
+
+ // declaring class extends queried class (DeclaringClass<A, B, C> extends Queried<X, Y, Z, ..., W>,
+ // where X, Y, Z...W, are a list of types for which we need to map (contextualize)
+ // variables
+ // A, B, C... D are variables of DeclaringClass, that may be used in the contextualization proccess
+ /**
+ * Constructor.
+ *
+ * @param arguments the set of arguments in their original context (the
+ * extends or implements declaration)
+ * @param declaringClass the class that declared those arguments. This class
+ * must be the same class that extends/implements a
+ * queried parameterized type.
+ */
+ private ArgumentContextualizer(Type[] arguments, Class<?> declaringClass)
+ {
+ this.arguments = arguments;
+ for (int i = 0; i < arguments.length; i++)
+ {
+ Type newArgument = processArgument(arguments, i, declaringClass,
+ replacementCreator, this);
+ if (newArgument != null)
+ {
+ this.arguments[i] = newArgument;
+ }
+ }
+ }
+
+ // newDeclaringClass extends/implements oldDeclaringType
+ // returns false = warning (work with raw type hence)
+ /**
+ * Performs a contextualization step.
+ *
+ * @param subClass a class that declares to extend/implement <code>superType
+ * </code>
+ * @param superType the super type of <code>subClass</code>
+ *
+ * @return <code>true</code> if the contextualization process was successfully
+ * performed; </code>false</code> otherwise.
+ */
+ private boolean contextualizeVariables(Class subClass, Type superType)
+ {
+ if (!initialized || variableReplacements.isEmpty())
+ {
+ initialized = false;
+ return true;
+ }
+ if (superType instanceof Class)
+ {
+ return false; // warning: variables lost in hierarchy
+ }
+ ParameterizedType superParamType = (ParameterizedType) superType;
+ for (iterator = variableReplacements.listIterator(); iterator.hasNext(); )
+ {
+ if(iterator.next().replace(superParamType, subClass))
+ {
+ iterator.remove();
+ }
+ }
+ iterator = null;
+ return true;
+ }
+
+ /**
+ * Process an argument, definining whether it needs to be replaced during
+ * contextualization process or not.
+ *
+ * @param <O>
+ *
+ * @param argumentContainer the array that contains the argument to be
+ * processed
+ * @param argumentIndex the index of the argument in <code>
+ * argumentContainer</code>
+ * @param declaringClass the class that declares the argument
+ * @param recorder object responsible for recording future
+ * replacements to be performed during
+ * contextualization
+ * @param outer
+ * @return the argument processed. This return value may be null if no
+ * processement of <code>argumentContainer[argumentIndex]</code> is
+ * rerquired, or an equivalent type otherwise.
+ */
+ private static <O> Type processArgument(Type[] argumentContainer,
+ int argumentIndex, Class<?> declaringClass,
+ ReplacementScheduler<O> recorder, O outer)
+ {
+ Type argument = argumentContainer[argumentIndex];
+ if (argument instanceof Class)
+ {
+ return null;
+ }
+ if (argument instanceof ParameterizedType)
+ {
+ ParameterizedType paramType = (ParameterizedType) argument;
+ ParameterizedType_ newParamType = null;
+ Type[] arguments = paramType.getActualTypeArguments();
+ for (int i = 0; i < arguments.length; i++)
+ {
+ Type newType = processArgument(arguments, i, declaringClass, recorder,
+ outer);
+ if (newType != null)
+ {
+ if (newParamType == null)
+ {
+ newParamType = new ParameterizedType_(paramType);
+ }
+ newParamType.getActualTypeArguments()[i] = newType;
+ }
+ }
+ return newParamType;
+ }
+ //else if (bounds[i] instanceof TypeVariable)
+ if (declaringClass == null)
+ {
+ return null;
+ }
+ String paramName = ((TypeVariable) argument).getName();
+ int index = 0;
+ TypeVariable[] typeVariables = declaringClass.getTypeParameters();
+ for (index = 0; index < typeVariables.length; index ++)
+ {
+ if (typeVariables[index].getName().equals(paramName)){
+ break;
+ }
+ }
+ recorder.scheduleReplacement(argumentContainer, argumentIndex, index, outer);
+ return argument;
+ }
+
+ boolean initialized = false;
+
+ private void initialize()
+ {
+ if (!initialized)
+ {
+ Type[] oldResult = this.arguments;
+ this.arguments = new Type[oldResult.length];
+ System.arraycopy(oldResult, 0, this.arguments, 0, this.arguments.length);
+ this.variableReplacements = new LinkedList<VariableReplacer>();
+ initialized = true;
+ }
+ }
+ private ListIterator<VariableReplacer> iterator;
+
+ /**
+ * Returns contextualized arguments.
+ *
+ * @return contextualized arguments
+ */
+ public Type[] getArguments()
+ {
+ return this.arguments;
+ }
+
+ /**
+ * Creates a variable replacement. This replacement should take place during the
+ * contextualization steps, where the variable will be replaced by its value.
+ * Notice this value may or may not be another variable.
+
+ * @param argumentContainer array on which the replacement will be executed
+ * @param argumentIndex the index that indicates a position of the variable
+ * to be replaced in <code>argumentContainer</code>
+ * array
+ * @param variableIndex index of the variable value in the next argument
+ * context array. This index shall be used on the
+ * replacement, during contextualization process.
+ */
+ private void createVariableReplacement(Type[] argumentContainer, int argumentIndex,
+ int variableIndex)
+ {
+ if (iterator != null)
+ {
+ iterator.add(new VariableReplacer(argumentContainer, argumentIndex,
+ variableIndex));
+ }
+ else
+ {
+ this.variableReplacements.add(new VariableReplacer(
+ argumentContainer, argumentIndex, variableIndex));
+ }
+ }
+
+ /**
+ * Replaces a variable by another type according to an argument context.
+ *
+ * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+ class VariableReplacer
+ {
+ private Type[] arguments;
+ private int argumentIndex;
+ private int valueIndex;
+ private boolean pendingExecution;
+
+ /**
+ * Constructor.
+ *
+ * @param arguments array on which the replacement will be executed
+ * @param argumentIndex the index that indicates a position of the variable
+ * to be replaced in <code>argumentContainer</code> array
+ * @param valueIndex index of the variable value in the next argument
+ * context array. This index shall be used on the
+ * replacement, during contextualization process.
+ */
+ public VariableReplacer(Type[] arguments, int argumentIndex, int valueIndex)
+ {
+ this.valueIndex = valueIndex;
+ this.arguments = arguments;
+ this.argumentIndex = argumentIndex;
+ this.pendingExecution = true;
+ }
+
+ // return true if replacement has been done for good
+ /**
+ * Performs replacemen of a variable by a new type.
+ *
+ * @param paramType parameterized type that contains the context to be
+ * used during replacement proccess.
+ * @param declaringClass the class that declares the the variables used in the
+ * arguments of <code>paramType</code>. This class must
+ * extend/implement the generic type
+ * <code>paramType</code>.
+ */
+ public boolean replace(ParameterizedType paramType, Class<?> declaringClass)
+ {
+ arguments[argumentIndex] = paramType.getActualTypeArguments()[valueIndex];
+ this.pendingExecution = false;
+ Type newType = ArgumentContextualizer.processArgument(arguments, argumentIndex,
+ declaringClass, updater, this);
+ if (newType != null)
+ {
+ arguments[argumentIndex] = newType;
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns the contextualizer that scheduled this replacement.
+ *
+ * @return the contextualizer.
+ */
+ ArgumentContextualizer getContextualizer()
+ {
+ return ArgumentContextualizer.this;
+ }
+ }
+
+ /**
+ * Parameterized type implementation. Allows replacement of arguments without
+ * affecting reflection information.
+ *
+ * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+ private static final class ParameterizedType_ implements ParameterizedType
+ {
+ private Type[] arguments;
+ private Type ownerType;
+ private Type rawType;
+
+ ParameterizedType_(ParameterizedType type)
+ {
+ Type[] actualArguments = type.getActualTypeArguments();
+ this.arguments = new Type[actualArguments.length];
+ System.arraycopy(actualArguments, 0, arguments, 0, actualArguments.length);
+ this.ownerType = type.getOwnerType();
+ this.rawType = type.getRawType();
+ }
+
+
+ public Type[] getActualTypeArguments()
+ {
+ return this.arguments;
+ }
+
+ public Type getOwnerType()
+ {
+ return this.ownerType;
+ }
+
+ public Type getRawType()
+ {
+ return this.rawType;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof ParameterizedType))
+ {
+ return false;
+ }
+ ParameterizedType other = (ParameterizedType) obj;
+ if (!this.ownerType.equals(other.getOwnerType()) ||
+ !this.rawType.equals(other.getRawType()))
+ {
+ return false;
+ }
+ Type[] otherArguments = other.getActualTypeArguments();
+ for (int i = 0; i < arguments.length; i++)
+ {
+ if (!arguments[i].equals(otherArguments[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Schedules replacements to be performed during contextualization.
+ *
+ * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ *
+ * @param <C> the scheduler client
+ */
+ interface ReplacementScheduler<C>
+ {
+ /**
+ * Schedules a variable replacement to be performed on next contextualization
+ * step.
+ *
+ * @param argumentContainer array on which the replacement will be executed
+ * @param argumentIndex the index that indicates a position of the variable
+ * to be replaced in <code>argumentContainer</code>
+ * array
+ * @param variableIndex index of the variable value in the next argument
+ * context array. This index shall be used on the
+ * replacement, during contextualization process.
+ * @param client the client of recorder
+ */
+ public void scheduleReplacement(Type[] argumentContainer, int argumentIndex,
+ int variableIndex, C client);
+ }
+
+ /**
+ * Schedules variable replacement when required by contextualizer.
+ * The effect of this scheduling process is the creation of variable replacement.
+ */
+ private static ReplacementScheduler<ArgumentContextualizer> replacementCreator =
+ new ReplacementScheduler<ArgumentContextualizer>()
+ {
+ public void scheduleReplacement(Type[] replacementTarget, int targetIndex,
+ int variableIndex, ArgumentContextualizer outer)
+ {
+ outer.initialize();
+ outer.createVariableReplacement(outer.arguments, targetIndex, variableIndex);
+ }
+ };
+
+ /**
+ * Schedules variable replacement when required by a <code>VariableReplacement
+ * </code> object.
+ * Generally, the effect of this schedule process will be an update in
+ * the client object, unless this one already has a pending replacement scheduled.
+ */
+ private static ReplacementScheduler<VariableReplacer> updater =
+ new ReplacementScheduler<VariableReplacer>()
+ {
+ public void scheduleReplacement(Type[] replacementTarget, int targetIndex,
+ int variableIndex, VariableReplacer replacer)
+ {
+ if (replacer.pendingExecution) // replacer is already busy
+ {
+ replacer.getContextualizer().createVariableReplacement(replacementTarget,
+ targetIndex, variableIndex);
+ }
+ else
+ {
+ replacer.valueIndex = variableIndex;
+ replacer.arguments = replacementTarget;
+ replacer.argumentIndex = targetIndex;
+ replacer.pendingExecution = true;
+ }
+ }
+ };
+}
\ No newline at end of file
Deleted: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ContextualizedArguments.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ContextualizedArguments.java 2007-07-03 23:53:31 UTC (rev 63806)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ContextualizedArguments.java 2007-07-04 00:21:41 UTC (rev 63807)
@@ -1,444 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.aop.advice.annotation;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-
-/**
- * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- *
- */
-class ContextualizedArguments
-{
- static abstract class EqualityChecker<T>
- {
- protected boolean isSame(Type[] arguments, Type[] assignableArguments, T token)
- {
- for (int i = 0; i < arguments.length; i++)
- {
- if (!isSame(arguments[i], assignableArguments[i], token))
- {
- return false;
- }
- }
- return true;
- }
-
- abstract boolean isSame(Type argument, Type assignableArgument, T token);
- }
-
-
- public static<T> boolean isAssignable(EqualityChecker<T> action, ParameterizedType paramType, Type assignable, T token)
- {
- Class<?> typeRaw = null;
- ParameterizedType assignableParamType = null;
- Class<?> desiredType = (Class<?>) paramType.getRawType();
- if (assignable instanceof Class)
- {
- typeRaw = (Class<?>) assignable;
- if (!desiredType.isAssignableFrom(typeRaw))
- {
- return false;
- }
- if (typeRaw.getTypeParameters().length > 0)
- {
- // notice that, if typeClass equals the fromParamType, we also have
- // the
- // result true with a warning (i.e., this if is not only for
- // typeClass
- // subclass of fromParamType, but also for typeCass same as
- // fromParamType raw
- return true;// TODO With warning
- }
- }
- else if (assignable instanceof ParameterizedType)
- {
- assignableParamType = (ParameterizedType) assignable;
- typeRaw = (Class<?>) assignableParamType.getRawType();
- if (typeRaw == desiredType)
- {
- // compare arguments with arguments
- return action.isSame(paramType.getActualTypeArguments(),
- assignableParamType.getActualTypeArguments(), token);
- }
- else if (!desiredType.isAssignableFrom(typeRaw))
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- // try to get, if null, warning, parameters lost in hierarchy
- Type[] arguments = getContextualizedArguments(assignableParamType, typeRaw, desiredType);
- if (arguments == null)
- {
- return true; // TODO with Warning
- }
- return action.isSame(paramType.getActualTypeArguments(), arguments, token);
- }
-
-
-
-
- public static final Type[] getContextualizedArguments(ParameterizedType paramType,
- Class rawType, Class desiredType)
- {
- ContextualizedArguments contextualizedArguments = getContextualizedArgumentsInternal(
- desiredType, rawType);
- if (contextualizedArguments == null)
- {
- return null;
- }
- if (paramType != null)
- {
- contextualizedArguments.contextualizeVariables(null, paramType);
- }
- return contextualizedArguments.getArguments();
- }
-
- private static final ContextualizedArguments getContextualizedArgumentsInternal(
- Class<?> desiredType, Class<?> classType)
- {
- Type superType = null;
- if (desiredType.isInterface())
- {
- for (Type superInterface : classType.getGenericInterfaces())
- {
- if ((superInterface instanceof Class && desiredType
- .isAssignableFrom((Class<?>) superInterface))
- || (superInterface instanceof ParameterizedType &&
- desiredType.isAssignableFrom((Class<?>)
- ((ParameterizedType) superInterface).getRawType())))
- {
- superType = superInterface;
- break;
- }
- }
- }
- else
- {
- superType = classType.getGenericSuperclass();
- }
- ContextualizedArguments result = null;
- if (superType instanceof Class)
- {
- if (superType == desiredType)
- {
- return null;
- }
- result = getContextualizedArgumentsInternal(desiredType,
- (Class<?>) superType);
- }
- else
- {
- ParameterizedType superParamType = (ParameterizedType) superType;
- Class<?> superClassType = (Class<?>) superParamType.getRawType();
- if (superClassType == desiredType)
- {
- return new ContextualizedArguments(superParamType
- .getActualTypeArguments(), classType);
- }
- else
- {
- result = getContextualizedArgumentsInternal(desiredType,
- superClassType);
- }
- }
- if (result == null
- || !result.contextualizeVariables(classType, superType))
- {
- return null;
- }
- return result;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- private static ReplacementRecorder<ContextualizedArguments> replacementCreator = new ReplacementRecorder<ContextualizedArguments>()
- {
- public void recordReplacement(ContextualizedArguments outer, int variableIndex, Type[] replacementTarget, int targetIndex)
- {
- outer.initialize();
- outer.createVariableReplacement(variableIndex, outer.arguments, targetIndex);
- }
- };
-
- private Type[] arguments;
- //private Collection<VariableReplacement> variableReplacements;
- private LinkedList<VariableReplacement> variableReplacements;
-
- // declaring class extends queried class (DeclaringClass<A, B, C> extends Queried<X, Y, Z, ..., W>,
- // where X, Y, Z...W, are a list of types for which we need to map (contextualize)
- // variables
- // A, B, C... D are variables of DeclaringClass, that may be used in the contextualization proccess
- public ContextualizedArguments(Type[] result, Class<?> declaringClass)
- {
- this.arguments = result;
- for (int i = 0; i < result.length; i++)
- {
- Type newArgument = processArgument(result, i, declaringClass,
- replacementCreator, this);
- if (newArgument != null)
- {
- this.arguments[i] = newArgument;
- }
- }
- }
-
- private static <O> Type processArgument(Type[] argumentContainer, int argumentIndex,
- Class<?> declaringClass, ReplacementRecorder<O> recorder, O outer)
- {
- Type argument = argumentContainer[argumentIndex];
- if (argument instanceof Class)
- {
- return null;
- }
- if (argument instanceof ParameterizedType)
- {
- ParameterizedType paramType = (ParameterizedType) argument;
- ParameterizedType_ newParamType = null;
- Type[] arguments = paramType.getActualTypeArguments();
- for (int i = 0; i < arguments.length; i++)
- {
- Type newType = processArgument(arguments, i, declaringClass, recorder,
- outer);
- if (newType != null)
- {
- if (newParamType == null)
- {
- newParamType = new ParameterizedType_(paramType);
- }
- newParamType.getActualTypeArguments()[i] = newType;
- }
- }
- return newParamType;
- }
- //else if (bounds[i] instanceof TypeVariable)
- if (declaringClass == null)
- {
- return null;
- }
- String paramName = ((TypeVariable) argument).getName();
- int index = 0;
- TypeVariable[] typeVariables = declaringClass.getTypeParameters();
- for (index = 0; index < typeVariables.length; index ++)
- {
- if (typeVariables[index].getName().equals(paramName)){
- break;
- }
- }
- recorder.recordReplacement(outer, index, argumentContainer, argumentIndex);
- return argument;
- }
-
- boolean initialized = false;
-
- private void initialize()
- {
- if (!initialized)
- {
- Type[] oldResult = this.arguments;
- this.arguments = new Type[oldResult.length];
- System.arraycopy(oldResult, 0, this.arguments, 0, this.arguments.length);
- this.variableReplacements = new LinkedList<VariableReplacement>();
- initialized = true;
- }
- }
- private ListIterator<VariableReplacement> iterator;
- // newDeclaringClass extends/implements oldDeclaringType
- // returns false = warning (work with raw type hence)
- public boolean contextualizeVariables(Class newDeclaringClass, Type oldDeclaringType)
- {
- if (!initialized || variableReplacements.isEmpty())
- {
- initialized = false;
- return true;
- }
- if (oldDeclaringType instanceof Class)
- {
- return false; // warning
- }
- ParameterizedType oldParamType = (ParameterizedType) oldDeclaringType;
- for (iterator = variableReplacements.listIterator(); iterator.hasNext(); )
- {
- if(iterator.next().replace(oldParamType, newDeclaringClass))
- {
- iterator.remove();
- }
- }
- iterator = null;
- return true;
- }
-
- public Type[] getArguments()
- {
- return this.arguments;
- }
-
- public void createVariableReplacement(int variableIndex, Type[] replacementTarget,
- int targetIndex)
- {
- if (iterator != null)
- {
- iterator.add(new VariableReplacement(variableIndex, replacementTarget,
- targetIndex));
- }
- else
- {
- this.variableReplacements.add(new VariableReplacement(
- variableIndex, replacementTarget, targetIndex));
- }
- }
- private static ReplacementRecorder<VariableReplacement> updater = new ReplacementRecorder<VariableReplacement>()
- {
- public void recordReplacement(VariableReplacement outer, int variableIndex, Type[] replacementTarget, int targetIndex)
- {
- if (outer.pendingReplacement) // outer is already busy
- {
- outer.getOuter().createVariableReplacement(variableIndex,
- replacementTarget, targetIndex);
- }
- else
- {
- outer.variableIndex = variableIndex;
- outer.target = replacementTarget;
- outer.targetIndex = targetIndex;
- outer.pendingReplacement = true;
- }
- }
- };
-
- class VariableReplacement
- {
- private int variableIndex;
- private Type[] target;
- private int targetIndex;
- private boolean pendingReplacement;
-
- public VariableReplacement(int variableIndex, Type[] target, int targetIndex)
- {
- this.variableIndex = variableIndex;
- this.target = target;
- this.targetIndex = targetIndex;
- this.pendingReplacement = true;
- }
-
- // return true if replacement has been done for good
- public boolean replace(ParameterizedType paramType, Class<?> declaringClass)
- {
- target[targetIndex] = paramType.getActualTypeArguments()[variableIndex];
- this.pendingReplacement = false;
- Type newType = ContextualizedArguments.processArgument(target, targetIndex,
- declaringClass, updater, this);
- if (newType != null)
- {
- target[targetIndex] = newType;
- return false;
- }
- return true;
- }
-
- ContextualizedArguments getOuter()
- {
- return ContextualizedArguments.this;
- }
- }
-
- private static class ParameterizedType_ implements ParameterizedType
- {
- private Type[] arguments;
- private Type ownerType;
- private Type rawType;
-
- ParameterizedType_(ParameterizedType type)
- {
- Type[] actualArguments = type.getActualTypeArguments();
- this.arguments = new Type[actualArguments.length];
- System.arraycopy(actualArguments, 0, arguments, 0, actualArguments.length);
- this.ownerType = type.getOwnerType();
- this.rawType = type.getRawType();
- }
-
-
- public Type[] getActualTypeArguments()
- {
- return this.arguments;
- }
-
- public Type getOwnerType()
- {
- return this.ownerType;
- }
-
- public Type getRawType()
- {
- return this.rawType;
- }
-
- public boolean equals(Object obj)
- {
- if (!(obj instanceof ParameterizedType))
- {
- return false;
- }
- ParameterizedType other = (ParameterizedType) obj;
- if (!this.ownerType.equals(other.getOwnerType()) ||
- !this.rawType.equals(other.getRawType()))
- {
- return false;
- }
- Type[] otherArguments = other.getActualTypeArguments();
- for (int i = 0; i < arguments.length; i++)
- {
- if (!arguments[i].equals(otherArguments[i]))
- {
- return false;
- }
- }
- return true;
- }
- }
-
- interface ReplacementRecorder<T>
- {
- public void recordReplacement(T outer, int variableIndex, Type[] replacementTarget, int targetIndex);
-
- }
-}
\ No newline at end of file
Copied: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java (from rev 63629, projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ContextualizedArguments.java)
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java (rev 0)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java 2007-07-04 00:21:41 UTC (rev 63807)
@@ -0,0 +1,151 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.advice.annotation;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/**
+ *
+ *
+ * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ParamTypeAssignabilityAlgorithm
+{
+ /**
+ * Class responsible for telling whether two groups of arguments, used on
+ * two different instances of ParameterizedType, can be considered the same
+ * group of arguments.
+ *
+ * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ *
+ * @param <T> this is a token that can be used to store information useful for
+ * the implementor.
+ */
+ static abstract class EqualityChecker<T>
+ {
+ /**
+ * Indicates whether both argument list can be considered the same.
+ * This method is a facility that will invoke {@link #isSame(Type, Type, Object)}
+ * for each argument of the lists. Both lists have the same length.
+ *
+ * @param arguments list of arguments.
+ * @param fromArguments list of arguments that will be assigned to <code>
+ * arguments</code> only if this method returns <code>true
+ * </code>
+ * @param token a token that may be needed by implementor as auxiliar
+ * @return <code>true</code> only if values of <code>
+ * fromArguments</code> list can be assigned to a list of
+ * <code>arguments</code> type.
+ */
+ protected boolean isSame(Type[] arguments, Type[] fromArguments, T token)
+ {
+ for (int i = 0; i < arguments.length; i++)
+ {
+ if (!isSame(arguments[i], fromArguments[i], token))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Indicates whether both arguments can be considered the same.
+ * This method execution might require some variable inference process,
+ * in which case only a variable type referenced by <code>argument</code> can
+ * have its value infered according to the process.
+ * @param token a token that may be needed by implementor as auxiliar
+ * @param arguments an argument type
+ * @param fromArguments argument type that will have its value assigned to
+ * <code>argument</code> only if this method returns
+ * <code>true</code>
+ *
+ * @return <code>true</code> only if a parameterized type with
+ * <code>argument</code> as one of its parameter values
+ * can be assigned from the same parameterized type with
+ * <code>fromArgument</code> as the equivalent parameter
+ * value
+ */
+ abstract boolean isSame(Type argument, Type fromArgument, T token);
+ }
+
+ /**
+ *
+ * @param <T>
+ * @param paramType
+ * @param fromType
+ * @param checker
+ * @param checkerToken
+ * @return
+ */
+ public static<T> boolean isAssignable(ParameterizedType paramType, Type fromType,
+ EqualityChecker<T> checker, T checkerToken)
+ {
+ Class<?> fromRaw = null;
+ ParameterizedType fromParamType = null;
+ Class<?> desiredType = (Class<?>) paramType.getRawType();
+ if (fromType instanceof Class)
+ {
+ fromRaw = (Class<?>) fromType;
+ if (!desiredType.isAssignableFrom(fromRaw))
+ {
+ return false;
+ }
+ if (fromRaw.getTypeParameters().length > 0)
+ {
+ // notice that, if fromRaw equals desiredType, we also have the
+ // result true with a warning (i.e., this if statemente is not only for
+ // fromRaw subclass of desiredType, but also for fromRaw same as
+ // desiredType
+ return true;// TODO With warning
+ }
+ }
+ else if (fromType instanceof ParameterizedType)
+ {
+ fromParamType = (ParameterizedType) fromType;
+ fromRaw = (Class<?>) fromParamType.getRawType();
+ if (fromRaw == desiredType)
+ {
+ // compare arguments with arguments
+ return checker.isSame(paramType.getActualTypeArguments(),
+ fromParamType.getActualTypeArguments(), checkerToken);
+ }
+ else if (!desiredType.isAssignableFrom(fromRaw))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ // try to get, if null, warning, parameters lost in hierarchy
+ Type[] arguments = ArgumentContextualizer.getContextualizedArguments(
+ fromParamType, fromRaw, desiredType);
+ if (arguments == null)
+ {
+ return true; // TODO with Warning
+ }
+ return checker.isSame(paramType.getActualTypeArguments(), arguments, checkerToken);
+ }
+}
\ No newline at end of file
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java 2007-07-03 23:53:31 UTC (rev 63806)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java 2007-07-04 00:21:41 UTC (rev 63807)
@@ -34,8 +34,9 @@
import java.util.Map;
/**
+ *
+ *
* @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- *
*/
public class VariableNode
{
@@ -70,8 +71,15 @@
{
if (this.assignedValue != null)
{
- return isSame(this.assignedValue, value);
+ return isSame(this.assignedValue, value, true);
}
+
+ // TODO fix this
+ /*if (value instanceof WildcardType)
+ {
+ return false;
+ }*/
+
if (!isInsideBounds(value, true) ||
(this.previous != null && !this.previous.areBoundsInside(value)))
{
@@ -130,7 +138,7 @@
private boolean isInsideBounds(Type lowerBound, boolean checkLowerBounds)
{
- if (this.assignedValue != null && !isAssignable(assignedValue, lowerBound))
+ if (this.assignedValue != null && !isAssignable(lowerBound, assignedValue))
{
return false;
}
@@ -138,7 +146,7 @@
{
for (Type bound: this.lowerBounds)
{
- if (!isAssignable(bound, lowerBound))
+ if (!isAssignable(lowerBound, bound))
{
return false;
}
@@ -160,43 +168,43 @@
}
// both type and bound belong to the same context
- private boolean isAssignable(Type bound, Type type)
+ private boolean isAssignable(Type type, Type fromType)
{
- if (type instanceof TypeVariable)
+ if (fromType instanceof TypeVariable)
{
- if (bound instanceof TypeVariable)
+ TypeVariable fromVariable = (TypeVariable) fromType;
+ Type[] fromBounds = fromVariable.getBounds();
+ if (type instanceof TypeVariable)
{
- if (type == bound)
+ if (type == fromType)
{
return true;
}
- TypeVariable typeVariable = (TypeVariable) type;
- Type[] bounds = typeVariable.getBounds();
- while (bounds.length == 1 && bounds[0] instanceof TypeVariable)
+ while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
{
- if (bounds[0] == bound)
+ if (fromBounds[0] == type)
{
return true;
}
- type = (TypeVariable) bounds[0];
- bounds = typeVariable.getBounds();
+ fromType = (TypeVariable) fromBounds[0];
+ fromBounds = fromVariable.getBounds();
}
- TypeVariable variableBound = (TypeVariable) bound;
- Type[] variableBoundBounds = typeVariable.getBounds();
- while (variableBoundBounds.length == 1 && variableBoundBounds[0] instanceof TypeVariable)
+ TypeVariable variable = (TypeVariable) type;
+ Type[] bounds = variable.getBounds();
+ while (bounds.length == 1 && bounds[0] instanceof TypeVariable)
{
- if (variableBoundBounds[0] == type)
+ if (bounds[0] == fromType)
{
return false;
}
- variableBound = (TypeVariable) variableBoundBounds[0];
- variableBoundBounds = variableBound.getBounds();
+ variable = (TypeVariable) bounds[0];
+ bounds = variable.getBounds();
}
- outer: for (int i = 0; i < variableBoundBounds.length; i++)
+ outer: for (int i = 0; i < bounds.length; i++)
{
- for (int j = 0; j < bounds.length; j++)
+ for (int j = 0; j < fromBounds.length; j++)
{
- if (isAssignable(variableBoundBounds[i], bounds[j]))
+ if (isAssignable(bounds[i], fromBounds[j]))
{
continue outer;
}
@@ -205,53 +213,94 @@
}
return true;
}
- for (Type variableBound: ((TypeVariable) type).getBounds())
+ while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
{
- if (isAssignable(bound, variableBound))
+ fromBounds = fromVariable.getBounds();
+ }
+ for (Type fromBound: fromBounds)
+ {
+ if (isAssignable(type, fromBound))
{
return true;
}
}
return false;
}
- if (bound instanceof Class)
+ if (type instanceof Class)
{
- if (bound == Object.class)
+ if (type == Object.class)
{
return true;
}
- Class<?> boundClass = (Class<?>) bound;
- if (type instanceof Class)
+ Class<?> clazz = (Class<?>) type;
+ if (fromType instanceof Class)
{
- return boundClass.isAssignableFrom((Class<?>) type);
+ return clazz.isAssignableFrom((Class<?>) fromType);
}
- if (type instanceof ParameterizedType)
+ if (fromType instanceof ParameterizedType)
{
- return boundClass.isAssignableFrom((Class<?>) ((ParameterizedType) type).getRawType());
+ return clazz.isAssignableFrom((Class<?>) ((ParameterizedType) fromType).getRawType());
}
- return boundClass.isArray() && isAssignable(boundClass.getComponentType(), ((GenericArrayType) type).
- getGenericComponentType());
+ if (fromType instanceof WildcardType)
+ {
+ WildcardType fromWildcard = (WildcardType) fromType;
+ boolean boundOk = false;
+ for (Type upperBound: fromWildcard.getUpperBounds())
+ {
+ if (isAssignable(type, upperBound))
+ {
+ boundOk = true;
+ break;
+ }
+ }
+ if (!boundOk)
+ {
+ return false;
+ }
+ for (Type lowerBound: fromWildcard.getUpperBounds())
+ {
+ if (isAssignable(type, lowerBound))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ if (fromType instanceof TypeVariable)
+ {
+ for (Type upperBound: ((TypeVariable) fromType).getBounds())
+ {
+ if (isAssignable(type, upperBound))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ return clazz.isArray() && isAssignable(clazz.getComponentType(),
+ ((GenericArrayType) fromType).getGenericComponentType());
}
- if (bound instanceof ParameterizedType)
+ if (type instanceof ParameterizedType)
{
- return ContextualizedArguments.isAssignable(CHECKER, (ParameterizedType) bound, type, this);
+ return ParamTypeAssignabilityAlgorithm.isAssignable(
+ (ParameterizedType) type, fromType, CHECKER, this);
}
- if (bound instanceof TypeVariable)
+ if (type instanceof TypeVariable)
{
- for (Type typeBound: ((TypeVariable) bound).getBounds())
+ for (Type bound: ((TypeVariable) type).getBounds())
{
- if (!isAssignable(typeBound, type))
+ if (!isAssignable(bound, fromType))
{
return false;
}
}
return true;
}
- ChoiceBound choiceBound = (ChoiceBound) bound;
+ ChoiceBound choiceBound = (ChoiceBound) type;
for (Iterator<Type> it = choiceBound.bounds.iterator(); it.hasNext();)
{
- Type option = it.next();
- if (!isAssignable(option, type))
+ Type boundOption = it.next();
+ if (!isAssignable(boundOption, fromType))
{
it.remove();
}
@@ -259,28 +308,28 @@
return !choiceBound.bounds.isEmpty();
}
- protected boolean isSame(Type assignableArgument, Type argument)
+ protected boolean isSame(Type argument, Type fromArgument, boolean argumentAssigned)
{
- if (assignableArgument instanceof WildcardType)
+ if (argument instanceof WildcardType)
{
- WildcardType assignableWildcardArg = (WildcardType) assignableArgument;
- Type[] upperAssignBounds = assignableWildcardArg.getUpperBounds();
- Type[] lowerAssignBounds = assignableWildcardArg.getUpperBounds();
- if (argument instanceof WildcardType)
+ WildcardType wildcard = (WildcardType) argument;
+ Type[] upperBounds = wildcard.getUpperBounds();
+ Type[] lowerBounds = wildcard.getLowerBounds();
+ if (fromArgument instanceof WildcardType)
{
- WildcardType wildcardArg = (WildcardType) argument;
- Type[] upperBounds = wildcardArg.getUpperBounds();
- if (!isAssignable(upperAssignBounds, upperBounds))
+ WildcardType fromWildcard = (WildcardType) fromArgument;
+ Type[] fromUpperBounds = fromWildcard.getUpperBounds();
+ if (!isAssignable(upperBounds, fromUpperBounds))
{
return false;
}
- Type[] lowerBounds = wildcardArg.getLowerBounds();
- outer: for (int i = 0; i < lowerBounds.length; i++)
+ Type[] fromLowerBounds = fromWildcard.getLowerBounds();
+ outer: for (int i = 0; i < fromLowerBounds.length; i++)
{
- for (int j = 0; j < lowerAssignBounds.length; j++)
+ for (int j = 0; j < lowerBounds.length; j++)
{
- if (isAssignable(lowerBounds[i], lowerAssignBounds[j]))
+ if (isAssignable(fromLowerBounds[i], lowerBounds[j]))
{
continue outer;
}
@@ -289,18 +338,22 @@
}
return true;
}
- else if(argument instanceof TypeVariable)
+ if (argumentAssigned)
{
- if (!isAssignable(upperAssignBounds, ((TypeVariable) argument).getBounds()))
+ return false;
+ }
+ if(fromArgument instanceof TypeVariable)
+ {
+ if (!isAssignable(upperBounds, ((TypeVariable) fromArgument).getBounds()))
{
return false;
}
}
else
{
- for (int i = 0; i < upperAssignBounds.length; i++)
+ for (int i = 0; i < upperBounds.length; i++)
{
- if (!isAssignable(upperAssignBounds[i], argument))
+ if (!isAssignable(upperBounds[i], fromArgument))
{
return false;
}
@@ -308,33 +361,34 @@
return true;
}
}
- else if (assignableArgument instanceof GenericArrayType)
+ else if (argument instanceof GenericArrayType)
{
- if (argument instanceof GenericArrayType)
+ if (fromArgument instanceof GenericArrayType)
{
- return isSame(((GenericArrayType) assignableArgument).getGenericComponentType(),
- ((GenericArrayType) argument).getGenericComponentType());
+ return isSame(((GenericArrayType) argument).getGenericComponentType(),
+ ((GenericArrayType) fromArgument).getGenericComponentType(),
+ argumentAssigned);
}
else
{
return false;
}
}
- return assignableArgument.equals(argument);
+ return argument.equals(fromArgument); // TODO check this works correctly
}
/**
* @param node
* @param upperBounds
- * @param upperAssignBounds
+ * @param upperBounds
*/
- private boolean isAssignable(Type[] upperAssignBounds, Type[] upperBounds)
+ private boolean isAssignable(Type[] upperBounds, Type[] fromUpperBounds)
{
- outer: for (int i = 0; i < upperAssignBounds.length; i++)
+ outer: for (int i = 0; i < upperBounds.length; i++)
{
- for (int j = 0; j < upperBounds.length; j++)
+ for (int j = 0; j < fromUpperBounds.length; j++)
{
- if (isAssignable(upperAssignBounds[i], upperBounds[j]))
+ if (isAssignable(upperBounds[i], fromUpperBounds[j]))
{
continue outer;
}
@@ -344,12 +398,12 @@
return true;
}
- private static ContextualizedArguments.EqualityChecker<VariableNode> CHECKER =
- new ContextualizedArguments.EqualityChecker<VariableNode>()
+ private static ParamTypeAssignabilityAlgorithm.EqualityChecker<VariableNode> CHECKER =
+ new ParamTypeAssignabilityAlgorithm.EqualityChecker<VariableNode>()
{
- public boolean isSame(Type assignableArgument, Type argument, VariableNode node)
+ public boolean isSame(Type argument, Type fromArgument, VariableNode node)
{
- return node.isSame(assignableArgument, argument);
+ return node.isSame(fromArgument, argument, false);
}
};
}
More information about the jboss-cvs-commits
mailing list