* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.patterns;
import java.io.DataOutputStream;
import org.aspectj.weaver.World;
public class DeclareParents extends Declare {
- private TypePattern child;
- private TypePatternList parents;
+ protected TypePattern child;
+ protected TypePatternList parents;
private boolean isWildChild = false;
- private boolean isExtends = true;
-// private String[] typeVariablesInScope = new String[0]; // AspectJ 5 extension for generic types
-
+ protected boolean isExtends = true;
+
+ // private String[] typeVariablesInScope = new String[0]; // AspectJ 5 extension for generic types
public DeclareParents(TypePattern child, List parents, boolean isExtends) {
- this(child, new TypePatternList(parents),isExtends);
+ this(child, new TypePatternList(parents), isExtends);
}
-
- private DeclareParents(TypePattern child, TypePatternList parents, boolean isExtends) {
+
+ protected DeclareParents(TypePattern child, TypePatternList parents, boolean isExtends) {
this.child = child;
this.parents = parents;
this.isExtends = isExtends;
- if (child instanceof WildTypePattern) isWildChild = true;
+ if (child instanceof WildTypePattern)
+ isWildChild = true;
}
-
-// public String[] getTypeParameterNames() {
-// return this.typeVariablesInScope;
-// }
-//
-// public void setTypeParametersInScope(String[] typeParameters) {
-// this.typeVariablesInScope = typeParameters;
-// }
-
+
+ // public String[] getTypeParameterNames() {
+ // return this.typeVariablesInScope;
+ // }
+ //
+ // public void setTypeParametersInScope(String[] typeParameters) {
+ // this.typeVariablesInScope = typeParameters;
+ // }
+
public boolean match(ResolvedType typeX) {
- if (!child.matchesStatically(typeX)) return false;
- if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() &&
- !typeX.isExposedToWeaver())
- {
+ if (!child.matchesStatically(typeX))
+ return false;
+ if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() && !typeX.isExposedToWeaver()) {
typeX.getWorld().getLint().typeNotExposedToWeaver.signal(typeX.getName(), getSourceLocation());
}
-
+
return true;
}
-
+
public Object accept(PatternNodeVisitor visitor, Object data) {
- return visitor.visit(this,data);
+ return visitor.visit(this, data);
}
-
- public Declare parameterizeWith(Map typeVariableBindingMap,World w) {
- DeclareParents ret =
- new DeclareParents(
- child.parameterizeWith(typeVariableBindingMap,w),
- parents.parameterizeWith(typeVariableBindingMap,w),
- isExtends);
+
+ public Declare parameterizeWith(Map typeVariableBindingMap, World w) {
+ DeclareParents ret = new DeclareParents(child.parameterizeWith(typeVariableBindingMap, w), parents.parameterizeWith(
+ typeVariableBindingMap, w), isExtends);
ret.copyLocationFrom(this);
return ret;
}
-
+
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("declare parents: ");
buf.append(child);
- buf.append(isExtends ? " extends " : " implements "); //extends and implements are treated equivalently
+ buf.append(isExtends ? " extends " : " implements "); // extends and implements are treated equivalently
buf.append(parents);
buf.append(";");
return buf.toString();
}
-
- public boolean equals(Object other) {
- if (!(other instanceof DeclareParents)) return false;
- DeclareParents o = (DeclareParents)other;
+
+ public boolean equals(Object other) {
+ if (!(other instanceof DeclareParents))
+ return false;
+ DeclareParents o = (DeclareParents) other;
return o.child.equals(child) && o.parents.equals(parents);
}
-
- //??? cache this
- public int hashCode() {
- int result = 23;
- result = 37*result + child.hashCode();
- result = 37*result + parents.hashCode();
- return result;
- }
+ // ??? cache this
+ public int hashCode() {
+ int result = 23;
+ result = 37 * result + child.hashCode();
+ result = 37 * result + parents.hashCode();
+ return result;
+ }
public void write(DataOutputStream s) throws IOException {
s.writeByte(Declare.PARENTS);
child.write(s);
parents.write(s);
-// s.writeInt(typeVariablesInScope.length);
-// for (int i = 0; i < typeVariablesInScope.length; i++) {
-// s.writeUTF(typeVariablesInScope[i]);
-// }
+ // s.writeInt(typeVariablesInScope.length);
+ // for (int i = 0; i < typeVariablesInScope.length; i++) {
+ // s.writeUTF(typeVariablesInScope[i]);
+ // }
writeLocation(s);
}
public static Declare read(VersionedDataInputStream s, ISourceContext context) throws IOException {
- DeclareParents ret = new DeclareParents(TypePattern.read(s, context), TypePatternList.read(s, context),true);
-// if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
-// int numTypeVariablesInScope = s.readInt();
-// ret.typeVariablesInScope = new String[numTypeVariablesInScope];
-// for (int i = 0; i < numTypeVariablesInScope; i++) {
-// ret.typeVariablesInScope[i] = s.readUTF();
-// }
-// }
+ DeclareParents ret = new DeclareParents(TypePattern.read(s, context), TypePatternList.read(s, context), true);
+ // if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
+ // int numTypeVariablesInScope = s.readInt();
+ // ret.typeVariablesInScope = new String[numTypeVariablesInScope];
+ // for (int i = 0; i < numTypeVariablesInScope; i++) {
+ // ret.typeVariablesInScope[i] = s.readUTF();
+ // }
+ // }
ret.readLocation(context, s);
return ret;
}
-
+
public boolean parentsIncludeInterface(World w) {
for (int i = 0; i < parents.size(); i++) {
- if (parents.get(i).getExactType().resolve(w).isInterface()) return true;
+ if (parents.get(i).getExactType().resolve(w).isInterface())
+ return true;
}
- return false;
+ return false;
}
+
public boolean parentsIncludeClass(World w) {
for (int i = 0; i < parents.size(); i++) {
- if (parents.get(i).getExactType().resolve(w).isClass()) return true;
+ if (parents.get(i).getExactType().resolve(w).isClass())
+ return true;
}
- return false;
+ return false;
}
-
- public void resolve(IScope scope) {
-// ScopeWithTypeVariables resolutionScope = new ScopeWithTypeVariables(typeVariablesInScope,scope);
- child = child.resolveBindings(scope, Bindings.NONE, false, false);
+
+ public void resolve(IScope scope) {
+ // ScopeWithTypeVariables resolutionScope = new ScopeWithTypeVariables(typeVariablesInScope,scope);
+ child = child.resolveBindings(scope, Bindings.NONE, false, false);
isWildChild = (child instanceof WildTypePattern);
- parents = parents.resolveBindings(scope, Bindings.NONE, false, true);
+ parents = parents.resolveBindings(scope, Bindings.NONE, false, true);
-// Could assert this ...
-// for (int i=0; i < parents.size(); i++) {
-// parents.get(i).assertExactType(scope.getMessageHandler());
-// }
- }
+ // Could assert this ...
+ // for (int i=0; i < parents.size(); i++) {
+ // parents.get(i).assertExactType(scope.getMessageHandler());
+ // }
+ }
public TypePatternList getParents() {
return parents;
public TypePattern getChild() {
return child;
}
-
+
// note - will always return true after deserialization, this doesn't affect weaver
public boolean isExtends() {
return this.isExtends;
}
-
+
public boolean isAdviceLike() {
return false;
}
-
- private ResolvedType maybeGetNewParent(ResolvedType targetType, TypePattern typePattern, World world,boolean reportErrors) {
- if (typePattern == TypePattern.NO) return null; // already had an error here
-// isWildChild = (child instanceof WildTypePattern);
+ private ResolvedType maybeGetNewParent(ResolvedType targetType, TypePattern typePattern, World world, boolean reportErrors) {
+ if (typePattern == TypePattern.NO)
+ return null; // already had an error here
+
+ // isWildChild = (child instanceof WildTypePattern);
UnresolvedType iType = typePattern.getExactType();
ResolvedType parentType = iType.resolve(world);
-
+
if (targetType.equals(world.getCoreType(UnresolvedType.OBJECT))) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.DECP_OBJECT),
- this.getSourceLocation(), null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.DECP_OBJECT), this.getSourceLocation(), null);
return null;
}
-
- // Ensure the target doesn't already have an
+
+ // Ensure the target doesn't already have an
// alternate parameterization of the generic type on it
if (parentType.isParameterizedType() || parentType.isRawType()) {
// Let's take a look at the parents we already have
- boolean isOK = verifyNoInheritedAlternateParameterization(targetType,parentType,world);
- if (!isOK) return null;
+ boolean isOK = verifyNoInheritedAlternateParameterization(targetType, parentType, world);
+ if (!isOK)
+ return null;
}
- if (parentType.isAssignableFrom(targetType)) return null; // already a parent
-
- // Enum types that are targetted for decp through a wild type pattern get linted
+ if (parentType.isAssignableFrom(targetType))
+ return null; // already a parent
+
+ // Enum types that are targetted for decp through a wild type pattern get linted
if (reportErrors && isWildChild && targetType.isEnum()) {
- world.getLint().enumAsTargetForDecpIgnored.signal(targetType.toString(),getSourceLocation());
+ world.getLint().enumAsTargetForDecpIgnored.signal(targetType.toString(), getSourceLocation());
}
-
- // Annotation types that are targetted for decp through a wild type pattern get linted
+
+ // Annotation types that are targetted for decp through a wild type pattern get linted
if (reportErrors && isWildChild && targetType.isAnnotation()) {
- world.getLint().annotationAsTargetForDecpIgnored.signal(targetType.toString(),getSourceLocation());
+ world.getLint().annotationAsTargetForDecpIgnored.signal(targetType.toString(), getSourceLocation());
}
// 1. Can't use decp to make an enum/annotation type implement an interface
if (targetType.isEnum() && parentType.isInterface()) {
- if (reportErrors && !isWildChild) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ENUM_TO_IMPL_INTERFACE,targetType),getSourceLocation(),null);
- }
+ if (reportErrors && !isWildChild) {
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ENUM_TO_IMPL_INTERFACE,
+ targetType), getSourceLocation(), null);
+ }
return null;
}
if (targetType.isAnnotation() && parentType.isInterface()) {
- if (reportErrors && !isWildChild) {
- world.showMessage(IMessage.ERROR,WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ANNOTATION_TO_IMPL_INTERFACE,targetType),getSourceLocation(),null);
- }
+ if (reportErrors && !isWildChild) {
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ANNOTATION_TO_IMPL_INTERFACE,
+ targetType), getSourceLocation(), null);
+ }
return null;
}
-
+
// 2. Can't use decp to change supertype of an enum/annotation
if (targetType.isEnum() && parentType.isClass()) {
if (reportErrors && !isWildChild) {
- world.showMessage(IMessage.ERROR,WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ENUM_TO_EXTEND_CLASS,targetType),getSourceLocation(),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ENUM_TO_EXTEND_CLASS,
+ targetType), getSourceLocation(), null);
}
return null;
}
if (targetType.isAnnotation() && parentType.isClass()) {
if (reportErrors && !isWildChild) {
- world.showMessage(IMessage.ERROR,WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ANNOTATION_TO_EXTEND_CLASS,targetType),getSourceLocation(),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ANNOTATION_TO_EXTEND_CLASS,
+ targetType), getSourceLocation(), null);
}
return null;
}
-
+
// 3. Can't use decp to declare java.lang.Enum/java.lang.annotation.Annotation as the parent of a type
if (parentType.getSignature().equals(UnresolvedType.ENUM.getSignature())) {
if (reportErrors && !isWildChild) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.CANT_DECP_TO_MAKE_ENUM_SUPERTYPE,targetType),getSourceLocation(),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages
+ .format(WeaverMessages.CANT_DECP_TO_MAKE_ENUM_SUPERTYPE, targetType), getSourceLocation(), null);
}
return null;
- }
+ }
if (parentType.getSignature().equals(UnresolvedType.ANNOTATION.getSignature())) {
if (reportErrors && !isWildChild) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.CANT_DECP_TO_MAKE_ANNOTATION_SUPERTYPE,targetType),getSourceLocation(),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_TO_MAKE_ANNOTATION_SUPERTYPE,
+ targetType), getSourceLocation(), null);
}
return null;
- }
-
- if (parentType.isAssignableFrom(targetType)) return null; // already a parent
+ }
+
+ if (parentType.isAssignableFrom(targetType))
+ return null; // already a parent
if (targetType.isAssignableFrom(parentType)) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.CANT_EXTEND_SELF,targetType.getName()),
- this.getSourceLocation(), null
- );
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_EXTEND_SELF, targetType.getName()), this
+ .getSourceLocation(), null);
return null;
}
-
+
if (parentType.isClass()) {
if (targetType.isInterface()) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.INTERFACE_CANT_EXTEND_CLASS),
- this.getSourceLocation(), null
- );
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.INTERFACE_CANT_EXTEND_CLASS), this
+ .getSourceLocation(), null);
return null;
// how to handle xcutting errors???
}
-
+
if (!targetType.getSuperclass().isAssignableFrom(parentType)) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.DECP_HIERARCHY_ERROR,
- iType.getName(),
- targetType.getSuperclass().getName()),
- this.getSourceLocation(), null
- );
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.DECP_HIERARCHY_ERROR, iType.getName(),
+ targetType.getSuperclass().getName()), this.getSourceLocation(), null);
return null;
} else {
return parentType;
- }
+ }
} else {
return parentType;
}
}
-
+
/**
- * This method looks through the type hierarchy for some target type - it is attempting to
- * find an existing parameterization that clashes with the new parent that the user
- * wants to apply to the type. If it finds an existing parameterization that matches the
- * new one, it silently completes, if it finds one that clashes (e.g. a type already has
- * A<String> when the user wants to add A<Number>) then it will produce an error.
+ * This method looks through the type hierarchy for some target type - it is attempting to find an existing parameterization
+ * that clashes with the new parent that the user wants to apply to the type. If it finds an existing parameterization that
+ * matches the new one, it silently completes, if it finds one that clashes (e.g. a type already has A<String> when the user
+ * wants to add A<Number>) then it will produce an error.
*
* It uses recursion and exits recursion on hitting 'jlObject'
- *
+ *
* Related bugzilla entries: pr110788
*/
- private boolean verifyNoInheritedAlternateParameterization(ResolvedType typeToVerify,ResolvedType newParent,World world) {
-
+ private boolean verifyNoInheritedAlternateParameterization(ResolvedType typeToVerify, ResolvedType newParent, World world) {
- if (typeToVerify.equals(ResolvedType.OBJECT)) return true;
+ if (typeToVerify.equals(ResolvedType.OBJECT))
+ return true;
ResolvedType newParentGenericType = newParent.getGenericType();
Iterator iter = typeToVerify.getDirectSupertypes();
while (iter.hasNext()) {
- ResolvedType supertype = (ResolvedType)iter.next();
- if ( ((supertype.isRawType() && newParent.isParameterizedType()) ||
- (supertype.isParameterizedType() && newParent.isRawType())) && newParentGenericType.equals(supertype.getGenericType())) {
+ ResolvedType supertype = (ResolvedType) iter.next();
+ if (((supertype.isRawType() && newParent.isParameterizedType()) || (supertype.isParameterizedType() && newParent
+ .isRawType()))
+ && newParentGenericType.equals(supertype.getGenericType())) {
// new parent is a parameterized type, but this is a raw type
- world.getMessageHandler().handleMessage(new Message(
- WeaverMessages.format(WeaverMessages.CANT_DECP_MULTIPLE_PARAMETERIZATIONS,newParent.getName(),typeToVerify.getName(),supertype.getName()),
- getSourceLocation(), true, new ISourceLocation[]{typeToVerify.getSourceLocation()}));
+ world.getMessageHandler().handleMessage(
+ new Message(WeaverMessages.format(WeaverMessages.CANT_DECP_MULTIPLE_PARAMETERIZATIONS, newParent.getName(),
+ typeToVerify.getName(), supertype.getName()), getSourceLocation(), true,
+ new ISourceLocation[] { typeToVerify.getSourceLocation() }));
return false;
}
if (supertype.isParameterizedType()) {
ResolvedType generictype = supertype.getGenericType();
-
+
// If the generic types are compatible but the parameterizations aren't then we have a problem
- if (generictype.isAssignableFrom(newParentGenericType) &&
- !supertype.isAssignableFrom(newParent)) {
- world.getMessageHandler().handleMessage(new Message(
- WeaverMessages.format(WeaverMessages.CANT_DECP_MULTIPLE_PARAMETERIZATIONS,newParent.getName(),typeToVerify.getName(),supertype.getName()),
- getSourceLocation(), true, new ISourceLocation[]{typeToVerify.getSourceLocation()}));
+ if (generictype.isAssignableFrom(newParentGenericType) && !supertype.isAssignableFrom(newParent)) {
+ world.getMessageHandler().handleMessage(
+ new Message(WeaverMessages.format(WeaverMessages.CANT_DECP_MULTIPLE_PARAMETERIZATIONS, newParent
+ .getName(), typeToVerify.getName(), supertype.getName()), getSourceLocation(), true,
+ new ISourceLocation[] { typeToVerify.getSourceLocation() }));
return false;
}
}
- if (!verifyNoInheritedAlternateParameterization(supertype,newParent,world)) {
+ if (!verifyNoInheritedAlternateParameterization(supertype, newParent, world)) {
return false;
}
}
return true;
}
- public List/*<ResolvedType>*/ findMatchingNewParents(ResolvedType onType,boolean reportErrors) {
- if (onType.isRawType()) onType = onType.getGenericType();
- if (!match(onType)) return Collections.EMPTY_LIST;
-
+ public List/* <ResolvedType> */findMatchingNewParents(ResolvedType onType, boolean reportErrors) {
+ if (onType.isRawType())
+ onType = onType.getGenericType();
+ if (!match(onType))
+ return Collections.EMPTY_LIST;
+
List ret = new ArrayList();
- for (int i=0; i < parents.size(); i++) {
- ResolvedType t = maybeGetNewParent(onType, parents.get(i), onType.getWorld(),reportErrors);
- if (t != null) ret.add(t);
+ for (int i = 0; i < parents.size(); i++) {
+ ResolvedType t = maybeGetNewParent(onType, parents.get(i), onType.getWorld(), reportErrors);
+ if (t != null)
+ ret.add(t);
}
-
+
return ret;
}
public String getNameSuffix() {
return "parents";
}
+
+ public boolean isMixin() {
+ return false;
+ }
}