Logo Search packages:      
Sourcecode: aspectj version File versions  Download package

TypeVariableReferenceType.java

/* *******************************************************************
 * 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;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Map;

/**
 * Represents a type variable in a type or generic method declaration
 */
00021 public class TypeVariableReferenceType extends BoundedReferenceType implements TypeVariableReference {

      private TypeVariable typeVariable;
      private boolean resolvedIfBounds = false;

      // If 'fixedUp' then the type variable in here is a reference to the real one that may
      // exist either on a member or a type. Not fixedUp means that we unpacked a generic
      // signature and weren't able to fix it up during resolution (didn't quite know enough
      // at the right time). Wonder if we can fix it up late?
      boolean fixedUp = false;

      public TypeVariableReferenceType(TypeVariable aTypeVariable, World aWorld) {
            super(aTypeVariable.getGenericSignature(), aTypeVariable.getErasureSignature(), aWorld);
            this.typeVariable = aTypeVariable;
            this.isExtends = false;
            this.isSuper = false;
      }

      public ReferenceTypeDelegate getDelegate() {
            if (delegate == null)
                  setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType) typeVariable.getFirstBound()));
            return delegate;
      }

      public UnresolvedType getUpperBound() {
            if (typeVariable == null)
                  return super.getUpperBound();
            return typeVariable.getUpperBound();
      }

      public UnresolvedType getFirstBound() {
            if (typeVariable == null)
                  return super.getUpperBound();
            return typeVariable.getFirstBound();
      }

      public UnresolvedType getLowerBound() {
            return typeVariable.getLowerBound();
      }

      private void setAdditionalInterfaceBoundsFromTypeVar() {
            if (typeVariable.getAdditionalInterfaceBounds() == null) {
                  return;
            } else {
                  UnresolvedType[] ifBounds = typeVariable.getAdditionalInterfaceBounds();
                  additionalInterfaceBounds = new ReferenceType[ifBounds.length];
                  for (int i = 0; i < ifBounds.length; i++) {
                        additionalInterfaceBounds[i] = (ReferenceType) ifBounds[i].resolve(getWorld());
                  }
            }
      }

00073       public UnresolvedType parameterize(Map typeBindings) {
            UnresolvedType ut = (UnresolvedType) typeBindings.get(getName());
            if (ut != null)
                  return world.resolve(ut);
            return this;
      }

      public ReferenceType[] getAdditionalBounds() {
            if (!resolvedIfBounds) {
                  setAdditionalInterfaceBoundsFromTypeVar();
                  resolvedIfBounds = true;
            }
            return super.getAdditionalBounds();
      }

      public TypeVariable getTypeVariable() {
            // if (!fixedUp) throw new BCException("ARGH"); // fix it up now?
            return typeVariable;
      }

      public boolean isTypeVariableReference() {
            return true;
      }

00097       public String toString() {
            return typeVariable.getName();
      }

      public boolean isGenericWildcard() {
            return false;
      }

      // public ResolvedType resolve(World world) {
      // return super.resolve(world);
      // }

      public boolean isAnnotation() {
            World world = ((ReferenceType) getUpperBound()).getWorld();
            ResolvedType annotationType = ResolvedType.ANNOTATION.resolve(world);
            if (getUpperBound() != null && ((ReferenceType) getUpperBound()).isAnnotation())
                  return true;
            ReferenceType[] ifBounds = getAdditionalBounds();
            for (int i = 0; i < ifBounds.length; i++) {
                  if (ifBounds[i].isAnnotation())
                        return true;
                  if (ifBounds[i] == annotationType)
                        return true; // annotation itself does not have the annotation flag set in Java!
            }
            return false;
      }

      /**
       * return the signature for a *REFERENCE* to a type variable, which is simply: Tname; there is no bounds info included, that is
       * in the signature of the type variable itself
       */
00128       public String getSignature() {
            StringBuffer sb = new StringBuffer();
            sb.append("T");
            sb.append(typeVariable.getName());
            sb.append(";");
            return sb.toString();
      }

      public void write(DataOutputStream s) throws IOException {
            super.write(s);
            // TypeVariableDeclaringElement tvde = typeVariable.getDeclaringElement();
            // if (tvde == null) {
            // s.writeInt(TypeVariable.UNKNOWN);
            // } else {
            // s.writeInt(typeVariable.getDeclaringElementKind());
            // if (typeVariable.getDeclaringElementKind() == TypeVariable.TYPE) {
            // ((UnresolvedType)tvde).write(s);
            // } else if (typeVariable.getDeclaringElementKind() == TypeVariable.METHOD){
            // // it's a method
            // ((ResolvedMember)tvde).write(s);
            // }
            // }
      }
}

Generated by  Doxygen 1.6.0   Back to index