Package org.aspectj.weaver.bcel

Source Code of org.aspectj.weaver.bcel.Utility

/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Common Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/cpl-v10.html
* Contributors:
*     PARC     initial implementation
* ******************************************************************/


package org.aspectj.weaver.bcel;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.ClassParser;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue;
import org.aspectj.apache.bcel.generic.ArrayType;
import org.aspectj.apache.bcel.generic.BIPUSH;
import org.aspectj.apache.bcel.generic.BasicType;
import org.aspectj.apache.bcel.generic.BranchInstruction;
import org.aspectj.apache.bcel.generic.ConstantPushInstruction;
import org.aspectj.apache.bcel.generic.INSTANCEOF;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.LDC;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.ReferenceType;
import org.aspectj.apache.bcel.generic.SIPUSH;
import org.aspectj.apache.bcel.generic.SWITCH;
import org.aspectj.apache.bcel.generic.Select;
import org.aspectj.apache.bcel.generic.TargetLostException;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.Lint;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;

public class Utility {

    private Utility() {
        super();
    }
 
  /*
   * Ensure we report a nice source location - particular in the case
   * where the source info is missing (binary weave).
   */
  public static String beautifyLocation(ISourceLocation isl) {
    StringBuffer nice = new StringBuffer();
    if (isl==null || isl.getSourceFile()==null || isl.getSourceFile().getName().indexOf("no debug info available")!=-1) {
      nice.append("no debug info available");
      } else {
        // can't use File.getName() as this fails when a Linux box encounters a path created on Windows and vice-versa
        int takeFrom = isl.getSourceFile().getPath().lastIndexOf('/');
        if (takeFrom == -1) {
          takeFrom = isl.getSourceFile().getPath().lastIndexOf('\\');
        }         
        nice.append(isl.getSourceFile().getPath().substring(takeFrom +1));
        if (isl.getLine()!=0) nice.append(":").append(isl.getLine());
    }
    return nice.toString();
  }
   
   
    public static Instruction createSuperInvoke(
        InstructionFactory fact,
        BcelWorld world,
        Member signature) {
        short kind;
        if (signature.isInterface()) {
            throw new RuntimeException("bad");
        } else if (signature.isPrivate() || signature.getName().equals("<init>")) {
             throw new RuntimeException("unimplemented, possibly bad");
        } else if (signature.isStatic()) {
            throw new RuntimeException("bad");
        } else {
            kind = Constants.INVOKESPECIAL;
        }
       
        return fact.createInvoke(
            signature.getDeclaringType().getName(),
            signature.getName(),
            BcelWorld.makeBcelType(signature.getReturnType()),
            BcelWorld.makeBcelTypes(signature.getParameterTypes()),
            kind);
  }
   
    // XXX don't need the world now
    public static Instruction createInvoke(
        InstructionFactory fact,
        BcelWorld world,
        Member signature) {
        short kind;
        if (signature.isInterface()) {
            kind = Constants.INVOKEINTERFACE;
        } else if (signature.isStatic()) {
            kind = Constants.INVOKESTATIC;
        } else if (signature.isPrivate() || signature.getName().equals("<init>")) {
            kind = Constants.INVOKESPECIAL;
        } else {
            kind = Constants.INVOKEVIRTUAL;
        }

        UnresolvedType targetType = signature.getDeclaringType();
        if (targetType.isParameterizedType()) {
          targetType = targetType.resolve(world).getGenericType();
        }
        return fact.createInvoke(
            targetType.getName(),
            signature.getName(),
            BcelWorld.makeBcelType(signature.getReturnType()),
            BcelWorld.makeBcelTypes(signature.getParameterTypes()),
            kind);
  }

  public static Instruction createGet(InstructionFactory fact, Member signature) {
        short kind;
        if (signature.isStatic()) {
            kind = Constants.GETSTATIC;
        } else {
            kind = Constants.GETFIELD;
        }

        return fact.createFieldAccess(
            signature.getDeclaringType().getName(),
            signature.getName(),
            BcelWorld.makeBcelType(signature.getReturnType()),
            kind);
  }

    /**
     * Creae a field GET instruction
     *
     * @param fact
     * @param signature
     * @param declaringType
     * @return
     */
    public static Instruction createGetOn(InstructionFactory fact, Member signature, UnresolvedType declaringType) {
        short kind;
        if (signature.isStatic()) {
            kind = Constants.GETSTATIC;
        } else {
            kind = Constants.GETFIELD;
        }

        return fact.createFieldAccess(
            declaringType.getName(),
            signature.getName(),
            BcelWorld.makeBcelType(signature.getReturnType()),
            kind);
    }

  public static Instruction createSet(InstructionFactory fact, Member signature) {
        short kind;
        if (signature.isStatic()) {
            kind = Constants.PUTSTATIC;
        } else {
            kind = Constants.PUTFIELD;
        }

        return fact.createFieldAccess(
            signature.getDeclaringType().getName(),
            signature.getName(),
            BcelWorld.makeBcelType(signature.getReturnType()),
            kind);
  }

  public static Instruction createInvoke(
        InstructionFactory fact,
        JavaClass declaringClass,
        Method newMethod) {
        short kind;
        if (newMethod.isInterface()) {
            kind = Constants.INVOKEINTERFACE;
        } else if (newMethod.isStatic()) {
            kind = Constants.INVOKESTATIC;
        } else if (newMethod.isPrivate() || newMethod.getName().equals("<init>")) {
            kind = Constants.INVOKESPECIAL;
        } else {
            kind = Constants.INVOKEVIRTUAL;
        }

        return fact.createInvoke(
            declaringClass.getClassName(),
            newMethod.getName(),
            Type.getReturnType(newMethod.getSignature()),
            Type.getArgumentTypes(newMethod.getSignature()),
            kind);
  }
 
  public static byte[] stringToUTF(String s) {
    try {
      ByteArrayOutputStream out0 = new ByteArrayOutputStream();
      DataOutputStream out1 = new DataOutputStream(out0);
      out1.writeUTF(s);
      return out0.toByteArray();
    } catch (IOException e) {
      throw new RuntimeException("sanity check");
    }
  }

    public static Instruction createInstanceof(InstructionFactory fact, ReferenceType t) {
    int cpoolEntry =
      (t instanceof ArrayType)
      ? fact.getConstantPool().addArrayClass((ArrayType)t)
      : fact.getConstantPool().addClass((ObjectType)t);
    return new INSTANCEOF(cpoolEntry);
    }

    public static Instruction createInvoke(
            InstructionFactory fact,
            LazyMethodGen m) {
        short kind;
        if (m.getEnclosingClass().isInterface()) {
            kind = Constants.INVOKEINTERFACE;
        } else if (m.isStatic()) {
            kind = Constants.INVOKESTATIC;
        } else if (m.isPrivate() || m.getName().equals("<init>")) {
            kind = Constants.INVOKESPECIAL;
        } else {
            kind = Constants.INVOKEVIRTUAL;
        }

        return fact.createInvoke(
            m.getClassName(),
            m.getName(),
            m.getReturnType(),
            m.getArgumentTypes(),
            kind);
    }

    /**
     * Create an invoke instruction
     *
     * @param fact
     * @param kind INVOKEINTERFACE, INVOKEVIRTUAL..
     * @param member
     * @return
     */
    public static Instruction createInvoke(
            InstructionFactory fact,
            short kind,
            Member member) {
        return fact.createInvoke(
            member.getDeclaringType().getName(),
            member.getName(),
            BcelWorld.makeBcelType(member.getReturnType()),
            BcelWorld.makeBcelTypes(member.getParameterTypes()),
            kind);
    }

    // ??? these should perhaps be cached.  Remember to profile this to see if it's a problem.
    public static String[] makeArgNames(int n) {
        String[] ret = new String[n];
        for (int i=0; i<n; i++) {
            ret[i] = "arg" + i;
        }
        return ret;
    }
   
    // Lookup table, for converting between pairs of types, it gives
    // us the method name in the Conversions class
    private static Hashtable validBoxing = new Hashtable();
   
    static {
      validBoxing.put("Ljava/lang/Byte;B","byteObject");
      validBoxing.put("Ljava/lang/Character;C","charObject");
      validBoxing.put("Ljava/lang/Double;D","doubleObject");
      validBoxing.put("Ljava/lang/Float;F","floatObject");
      validBoxing.put("Ljava/lang/Integer;I","intObject");
      validBoxing.put("Ljava/lang/Long;J","longObject");
      validBoxing.put("Ljava/lang/Short;S","shortObject");
      validBoxing.put("Ljava/lang/Boolean;Z","booleanObject");
      validBoxing.put("BLjava/lang/Byte;","byteValue");
      validBoxing.put("CLjava/lang/Character;","charValue");
      validBoxing.put("DLjava/lang/Double;","doubleValue");
      validBoxing.put("FLjava/lang/Float;","floatValue");
      validBoxing.put("ILjava/lang/Integer;","intValue");
      validBoxing.put("JLjava/lang/Long;","longValue");
      validBoxing.put("SLjava/lang/Short;","shortValue");
      validBoxing.put("ZLjava/lang/Boolean;","booleanValue");
    }
   
    public static void appendConversion(
        InstructionList il,
        InstructionFactory fact,
        ResolvedType fromType,
        ResolvedType toType)
    {
        if (! toType.isConvertableFrom(fromType) &&
           ! fromType.isConvertableFrom(toType)) {
            throw new BCException("can't convert from " + fromType + " to " + toType);
        }
      // XXX I'm sure this test can be simpler but my brain hurts and this works
        if (!toType.getWorld().isInJava5Mode()) {
          if (toType.needsNoConversionFrom(fromType)) return;
        } else {
          if (toType.needsNoConversionFrom(fromType) && !(toType.isPrimitiveType()^fromType.isPrimitiveType())) return;
        }
        if (toType.equals(ResolvedType.VOID)) {
            // assert fromType.equals(UnresolvedType.OBJECT)
            il.append(InstructionFactory.createPop(fromType.getSize()));
        } else if (fromType.equals(ResolvedType.VOID)) {
            // assert toType.equals(UnresolvedType.OBJECT)
            il.append(InstructionFactory.createNull(Type.OBJECT));
            return;
        } else if (fromType.equals(UnresolvedType.OBJECT)) {
            Type to = BcelWorld.makeBcelType(toType);
            if (toType.isPrimitiveType()) {
                String name = toType.toString() + "Value";
                il.append(
                    fact.createInvoke(
                        "org.aspectj.runtime.internal.Conversions",
                        name,
                        to,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKESTATIC));
            } else {
                il.append(fact.createCheckCast((ReferenceType)to));
            }
        } else if (toType.equals(UnresolvedType.OBJECT)) {
            // assert fromType.isPrimitive()
            Type from = BcelWorld.makeBcelType(fromType);
            String name = fromType.toString() + "Object";
            il.append(
                fact.createInvoke(
                    "org.aspectj.runtime.internal.Conversions",
                    name,
                    Type.OBJECT,
                    new Type[] { from },
                    Constants.INVOKESTATIC));
        } else if (toType.getWorld().isInJava5Mode() && validBoxing.get(toType.getSignature()+fromType.getSignature())!=null) {
          // XXX could optimize by using any java boxing code that may be just before the call...
          Type from   = BcelWorld.makeBcelType(fromType);
          Type to     = BcelWorld.makeBcelType(toType);
            String name = (String)validBoxing.get(toType.getSignature()+fromType.getSignature());
            if (toType.isPrimitiveType()) {
              il.append(
                        fact.createInvoke(
                          "org.aspectj.runtime.internal.Conversions",
                          name,
              to,
                          new Type[]{Type.OBJECT},
                          Constants.INVOKESTATIC));
            } else {
                il.append(
                  fact.createInvoke(
                    "org.aspectj.runtime.internal.Conversions",
                    name,
                    Type.OBJECT,
                    new Type[] { from },
                    Constants.INVOKESTATIC));
                il.append(fact.createCheckCast((ReferenceType) to));
            }
        } else if (fromType.isPrimitiveType()) {
            // assert toType.isPrimitive()
            Type from = BcelWorld.makeBcelType(fromType);
            Type to = BcelWorld.makeBcelType(toType);
            try {
                il.append(fact.createCast(from, to));
            } catch (RuntimeException e) {
                il.append(fact.createCast(from, Type.INT));
                il.append(fact.createCast(Type.INT, to));
            }
        } else {
            Type to = BcelWorld.makeBcelType(toType);
            // assert ! fromType.isPrimitive() && ! toType.isPrimitive()
            il.append(fact.createCheckCast((ReferenceType) to));
        }
    }

    public static InstructionList createConversion(InstructionFactory factory,Type fromType,Type toType) {
      return createConversion(factory,fromType,toType,false);
    }
   
    public static InstructionList createConversion(
            InstructionFactory fact,
            Type fromType,
            Type toType,
            boolean allowAutoboxing) {
        //System.out.println("cast to: " + toType);

        InstructionList il = new InstructionList();
       
        //PR71273
        if ((fromType.equals(Type.BYTE) || fromType.equals(Type.CHAR) || fromType.equals(Type.SHORT)) &&
            (toType.equals(Type.INT))) {
          return il;
        }
       
        if (fromType.equals(toType))
            return il;
        if (toType.equals(Type.VOID)) {
            il.append(InstructionFactory.createPop(fromType.getSize()));
            return il;
        }

        if (fromType.equals(Type.VOID)) {
            if (toType instanceof BasicType)
                throw new BCException("attempting to cast from void to basic type");
            il.append(InstructionFactory.createNull(Type.OBJECT));
            return il;
        }

        if (fromType.equals(Type.OBJECT)) {
            if (toType instanceof BasicType) {
                String name = toType.toString() + "Value";
                il.append(
                    fact.createInvoke(
                        "org.aspectj.runtime.internal.Conversions",
                        name,
                        toType,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKESTATIC));
                return il;
            }
        }

        if (toType.equals(Type.OBJECT)) {
            if (fromType instanceof BasicType) {
                String name = fromType.toString() + "Object";
                il.append(
                    fact.createInvoke(
                        "org.aspectj.runtime.internal.Conversions",
                        name,
                        Type.OBJECT,
                        new Type[] { fromType },
                        Constants.INVOKESTATIC));
                return il;
            } else if (fromType instanceof ReferenceType) {
                return il;
            } else {
                throw new RuntimeException();
            }
        }
       
        if (fromType instanceof ReferenceType
                && ((ReferenceType)fromType).isAssignmentCompatibleWith(toType)) {
            return il;
        }
       
        if (allowAutoboxing) {
          if (toType instanceof BasicType && fromType instanceof ReferenceType) {
            // unboxing
            String name = toType.toString() + "Value";
              il.append(
                  fact.createInvoke(
                      "org.aspectj.runtime.internal.Conversions",
                      name,
                      toType,
                      new Type[] { Type.OBJECT },
                      Constants.INVOKESTATIC));
              return il;
          }
         
          if (fromType instanceof BasicType && toType instanceof ReferenceType) {
            // boxing
            String name = fromType.toString() + "Object";
              il.append(
                  fact.createInvoke(
                      "org.aspectj.runtime.internal.Conversions",
                      name,
                      Type.OBJECT,
                      new Type[] { fromType },
                      Constants.INVOKESTATIC));
              il.append(fact.createCast(Type.OBJECT, toType));
              return il;
          }
        }

        il.append(fact.createCast(fromType, toType));
        return il;
    }

  public static Instruction createConstant(
        InstructionFactory fact,
        int i) {
    Instruction inst;
    switch(i) {
      case -1: inst =  InstructionConstants.ICONST_M1; break;
      case 0: inst =  InstructionConstants.ICONST_0;  break;     
      case 1: inst =  InstructionConstants.ICONST_1; break;
      case 2: inst =  InstructionConstants.ICONST_2; break;       
      case 3: inst =  InstructionConstants.ICONST_3; break;
      case 4: inst =  InstructionConstants.ICONST_4;  break;     
      case 5: inst =  InstructionConstants.ICONST_5;  break
    }
    if (i <= Byte.MAX_VALUE && i >= Byte.MIN_VALUE) {
         inst =  new BIPUSH((byte)i);
    } else if (i <= Short.MAX_VALUE && i >= Short.MIN_VALUE) {
      inst =  new SIPUSH((short)i);
    } else {
      inst =  new LDC(fact.getClassGen().getConstantPool().addInteger(i));
    }
    return inst;
  }

  public static JavaClass makeJavaClass(String filename, byte[] bytes) {
    try {
        ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), filename);
            return parser.parse();
    } catch (IOException e) {
      throw new BCException("malformed class file");
    }   
  }
 
    public static String arrayToString(int[] a) {
        int len = a.length;
        if (len == 0) return "[]";
        StringBuffer buf = new StringBuffer("[");
        buf.append(a[0]);
        for (int i = 1; i < len; i++) {
            buf.append(", ");
            buf.append(a[i]);
        }
        buf.append("]");
        return buf.toString();
    }

  /**
   * replace an instruction handle with another instruction, in this case, a branch instruction.
   *
   * @param ih the instruction handle to replace.
   * @param branchInstruction the branch instruction to replace ih with
   * @param enclosingMethod where to find ih's instruction list.
   */
    public static void replaceInstruction(
        InstructionHandle ih,
        BranchInstruction branchInstruction,
        LazyMethodGen enclosingMethod)
    {
       
        InstructionList il = enclosingMethod.getBody();
        InstructionHandle fresh = il.append(ih, branchInstruction);
    deleteInstruction(ih, fresh, enclosingMethod);
    }
   
  /** delete an instruction handle and retarget all targeters of the deleted instruction
   * to the next instruction.  Obviously, this should not be used to delete
   * a control transfer instruction unless you know what you're doing.
   *
   * @param ih the instruction handle to delete.
   * @param enclosingMethod where to find ih's instruction list.
   */
  public static void deleteInstruction(
      InstructionHandle ih,
      LazyMethodGen enclosingMethod)
    {
      deleteInstruction(ih, ih.getNext(), enclosingMethod);
    }
       
   
  /** delete an instruction handle and retarget all targeters of the deleted instruction
   * to the provided target.
   *
   * @param ih the instruction handle to delete
   * @param retargetTo the instruction handle to retarget targeters of ih to.
   * @param enclosingMethod where to find ih's instruction list.
   */
    public static void deleteInstruction(
      InstructionHandle ih,
      InstructionHandle retargetTo,
      LazyMethodGen enclosingMethod)
    {
        InstructionList il = enclosingMethod.getBody();
        InstructionTargeter[] targeters = ih.getTargeters();
        if (targeters != null) {
            for (int i = targeters.length - 1; i >= 0; i--) {
                InstructionTargeter targeter = targeters[i];
                targeter.updateTarget(ih, retargetTo);
            }
            ih.removeAllTargeters();
        }
        try {
            il.delete(ih);
        } catch (TargetLostException e) {
            throw new BCException("this really can't happen");
        }
     }
    
     /**
      * Fix for Bugzilla #39479, #40109 patch contributed by Andy Clement
      *
      * Need to manually copy Select instructions - if we rely on the the 'fresh' object
      * created by copy(), the InstructionHandle array 'targets' inside the Select
      * object will not have been deep copied, so modifying targets in fresh will modify
      * the original Select - not what we want !  (It is a bug in BCEL to do with cloning
      * Select objects).
      *
      * <pre>
      * declare error:
      *     call(* Instruction.copy()) && within(org.aspectj.weaver)
      *       && !withincode(* Utility.copyInstruction(Instruction)):
      *     "use Utility.copyInstruction to work-around bug in Select.copy()";
      * </pre>
      */
  public static Instruction copyInstruction(Instruction i) {
    if (i instanceof Select) {
      Select freshSelect = (Select)i;
         
      // Create a new targets array that looks just like the existing one
      InstructionHandle[] targets = new InstructionHandle[freshSelect.getTargets().length];
      for (int ii = 0; ii < targets.length; ii++) {
        targets[ii] = freshSelect.getTargets()[ii];
      }
         
      // Create a new select statement with the new targets array
      SWITCH switchStatement =
        new SWITCH(freshSelect.getMatchs(), targets, freshSelect.getTarget());
      return (Select)switchStatement.getInstruction()
    } else {
      return i.copy(); // Use clone for shallow copy...
    }
  }
    

  /** returns -1 if no source line attribute */
  // this naive version overruns the JVM stack size, if only Java understood tail recursion...
//  public static int getSourceLine(InstructionHandle ih) {
//    if (ih == null) return -1;
//   
//    InstructionTargeter[] ts = ih.getTargeters();
//    if (ts != null) {
//      for (int j = ts.length - 1; j >= 0; j--) {
//        InstructionTargeter t = ts[j];
//        if (t instanceof LineNumberTag) {
//          return ((LineNumberTag)t).getLineNumber();
//        }
//      }
//    }
//    return getSourceLine(ih.getNext());
//  }
 

  public static int getSourceLine(InstructionHandle ih) {
    int lookahead=0;
    // arbitrary rule that we will never lookahead more than 100 instructions for a line #
    while (lookahead++ < 100) {
      if (ih == null) return -1;
     
          InstructionTargeter[] ts = ih.getTargeters();
          if (ts != null) {
              for (int j = ts.length - 1; j >= 0; j--) {
                  InstructionTargeter t = ts[j];
                  if (t instanceof LineNumberTag) {
                    return ((LineNumberTag)t).getLineNumber();
                  }
              }
          }
          ih = ih.getNext();
    }
    //System.err.println("no line information available for: " + ih);
        return -1;
  }
 
  // assumes that there is no already extant source line tag.  Otherwise we'll have to be better.
  public static void setSourceLine(InstructionHandle ih, int lineNumber) {
    ih.addTargeter(new LineNumberTag(lineNumber));
  }

  public static int makePublic(int i) {
    return i & ~(Modifier.PROTECTED | Modifier.PRIVATE) | Modifier.PUBLIC;
  }
  public static int makePrivate(int i) {
    return i & ~(Modifier.PROTECTED | Modifier.PUBLIC) | Modifier.PRIVATE;
  }
  public static BcelVar[] pushAndReturnArrayOfVars(
    ResolvedType[] proceedParamTypes,
    InstructionList il,
    InstructionFactory fact,
    LazyMethodGen enclosingMethod)
  {
    int len = proceedParamTypes.length;
    BcelVar[] ret = new BcelVar[len];

    for (int i = len - 1; i >= 0; i--) {
      ResolvedType typeX = proceedParamTypes[i];
      Type type = BcelWorld.makeBcelType(typeX);
      int local = enclosingMethod.allocateLocal(type);
     
      il.append(InstructionFactory.createStore(type, local));
      ret[i] = new BcelVar(typeX, local);
    }   
    return ret;
  }

  public static boolean isConstantPushInstruction(Instruction i) {
    return (i instanceof ConstantPushInstruction) || (i instanceof LDC);
  }
 
  /**
     * Check if the annotations contain a SuppressAjWarnings annotation and
     * if that annotation specifies that the given lint message (identified
     * by its key) should be ignored.
     *
     */
    public static boolean isSuppressing(AnnotationX[] anns,String lintkey) {
      if (anns == null) return false;
        boolean suppressed = false;
        // Go through the annotation types on the advice
        for (int i = 0;!suppressed && i<anns.length;i++) {
          // Check for the SuppressAjWarnings annotation
          if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) {
            // Two possibilities:
            // 1. there are no values specified (i.e. @SuppressAjWarnings)
            // 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
            List vals = anns[i].getBcelAnnotation().getValues();
            if (vals == null || vals.size()==0) { // (1)
                suppressed = true;
            } else { // (2)
              // We know the value is an array value
              ArrayElementValue array = (ArrayElementValue)((ElementNameValuePair)vals.get(0)).getValue();
              ElementValue[] values = array.getElementValuesArray();
              for (int j = 0; j < values.length; j++) {
                // We know values in the array are strings
          SimpleElementValue value = (SimpleElementValue)values[j];
          if (value.getValueString().equals(lintkey)) {
            suppressed = true;
          }
        }
            }
          }
        }
        return suppressed;
    }
   
    public static List/*Lint.Kind*/ getSuppressedWarnings(AnnotationX[] anns, Lint lint) {
        if (anns == null) return Collections.EMPTY_LIST;
        // Go through the annotation types
        List suppressedWarnings = new ArrayList();
        boolean found = false;
        for (int i = 0;!found && i<anns.length;i++) {
          // Check for the SuppressAjWarnings annotation
          if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) {
          found = true;
            // Two possibilities:
            // 1. there are no values specified (i.e. @SuppressAjWarnings)
            // 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
            List vals = anns[i].getBcelAnnotation().getValues();
            if (vals == null || vals.size()==0) { // (1)
               suppressedWarnings.addAll(lint.allKinds());
            } else { // (2)
              // We know the value is an array value
              ArrayElementValue array = (ArrayElementValue)((ElementNameValuePair)vals.get(0)).getValue();
              ElementValue[] values = array.getElementValuesArray();
              for (int j = 0; j < values.length; j++) {
                // We know values in the array are strings
          SimpleElementValue value = (SimpleElementValue)values[j];
          Lint.Kind lintKind = lint.getLintKind(value.getValueString());
          if (lintKind != null) suppressedWarnings.add(lintKind);
        }
            }
          }
        }
        return suppressedWarnings;
     }
}
TOP

Related Classes of org.aspectj.weaver.bcel.Utility

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.