From d43de06ddbca60615a577533e159a3cba24fcfa9 Mon Sep 17 00:00:00 2001 From: acolyer Date: Wed, 22 Jun 2005 14:38:36 +0000 Subject: [PATCH] early commit of TypeVariable for Andy... --- .../src/org/aspectj/weaver/TypeVariable.java | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 weaver/src/org/aspectj/weaver/TypeVariable.java diff --git a/weaver/src/org/aspectj/weaver/TypeVariable.java b/weaver/src/org/aspectj/weaver/TypeVariable.java new file mode 100644 index 000000000..73c92ac52 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/TypeVariable.java @@ -0,0 +1,131 @@ +/* ******************************************************************* + * Copyright (c) 2005 Contributors. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.weaver; + +/** + * Represents a type variable with bounds + */ +public class TypeVariable { + + /** + * whether or not the bounds of this type variable have been + * resolved + */ + private boolean isResolved = false; + + /** + * the name of the type variable as recorded in the generic signature + */ + private String name; + + /** + * the upper bound of the type variable (default to Object). + * From the extends clause, eg. T extends Number. + */ + private TypeX upperBound = TypeX.OBJECT; + + /** + * any additional upper (interface) bounds. + * from the extends clause, e.g. T extends Number & Comparable + */ + private TypeX[] additionalInterfaceBounds = new TypeX[0]; + + /** + * any lower bound. + * from the super clause, eg T super Foo + */ + private TypeX lowerBound = null; + + public TypeVariable(String aName) { + this.name = aName; + } + + public TypeVariable(String aName, TypeX anUpperBound) { + this(aName); + this.upperBound = anUpperBound; + } + + public TypeVariable(String aName, TypeX anUpperBound, + TypeX[] someAdditionalInterfaceBounds) { + this(aName,anUpperBound); + this.additionalInterfaceBounds = someAdditionalInterfaceBounds; + } + + public TypeVariable(String aName, TypeX anUpperBound, + TypeX[] someAdditionalInterfaceBounds, TypeX aLowerBound) { + this(aName,anUpperBound,someAdditionalInterfaceBounds); + this.lowerBound = aLowerBound; + } + + public TypeX getUpperBound() { + return upperBound; + } + + public TypeX[] getAdditionalInterfaceBounds() { + return additionalInterfaceBounds; + } + + public TypeX getLowerBound() { + return lowerBound; + } + + public String getName() { + return name; + } + + /** + * resolve all the bounds of this type variable + */ + public void resolve(World inSomeWorld) { + if (isResolved) throw new IllegalStateException("already resolved!"); + + upperBound = upperBound.resolve(inSomeWorld); + if (lowerBound != null) lowerBound = lowerBound.resolve(inSomeWorld); + + for (int i = 0; i < additionalInterfaceBounds.length; i++) { + additionalInterfaceBounds[i] = additionalInterfaceBounds[i].resolve(inSomeWorld); + } + + isResolved = true; + } + + /** + * answer true if the given type satisfies all of the bound constraints of this + * type variable. + * If type variable has not been resolved then throws IllegalStateException + */ + public boolean canBeBoundTo(ResolvedTypeX aCandidateType) { + if (!isResolved) throw new IllegalStateException("Can't answer binding questions prior to resolving"); + // can be bound iff... + // aCandidateType is a subtype of upperBound + if (!isASubtypeOf(upperBound,aCandidateType)) { + return false; + } + // aCandidateType is a subtype of all additionalInterfaceBounds + for (int i = 0; i < additionalInterfaceBounds.length; i++) { + if (!isASubtypeOf(additionalInterfaceBounds[i], aCandidateType)) { + return false; + } + } + // lowerBound is a subtype of aCandidateType + if ((lowerBound != null) && (!isASubtypeOf(aCandidateType,lowerBound))) { + return false; + } + return true; + } + + private boolean isASubtypeOf(TypeX candidateSuperType, TypeX candidateSubType) { + ResolvedTypeX superType = (ResolvedTypeX) candidateSuperType; + ResolvedTypeX subType = (ResolvedTypeX) candidateSubType; + return superType.isAssignableFrom(subType); + } +} -- 2.39.5