Package org.aspectj.weaver.patterns

Source Code of org.aspectj.weaver.patterns.AnnotationPatternList

/* *******************************************************************
* Copyright (c) 2004 IBM Corporation.
* 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
* ******************************************************************/
package org.aspectj.weaver.patterns;

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

import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;

/**
* @author colyer
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class AnnotationPatternList extends PatternNode {

  private AnnotationTypePattern[] typePatterns;
  int ellipsisCount = 0;
 
  public static final AnnotationPatternList EMPTY =
    new AnnotationPatternList(new AnnotationTypePattern[] {});
 
  public static final AnnotationPatternList ANY =
      new AnnotationPatternList(new AnnotationTypePattern[] {AnnotationTypePattern.ELLIPSIS});
 
  public AnnotationPatternList() {
    typePatterns = new AnnotationTypePattern[0];
    ellipsisCount = 0;
  }

  public AnnotationPatternList(AnnotationTypePattern[] arguments) {
    this.typePatterns = arguments;
    for (int i=0; i<arguments.length; i++) {
      if (arguments[i] == AnnotationTypePattern.ELLIPSIS) ellipsisCount++;
    }
  }
 
  public AnnotationPatternList(List l) {
    this((AnnotationTypePattern[]) l.toArray(new AnnotationTypePattern[l.size()]));
  }

  protected AnnotationTypePattern[] getAnnotationPatterns() {
    return typePatterns;
  }
 
  public AnnotationPatternList parameterizeWith(Map typeVariableMap) {
    AnnotationTypePattern[] parameterizedPatterns = new AnnotationTypePattern[this.typePatterns.length];
    for (int i = 0; i < parameterizedPatterns.length; i++) {
      parameterizedPatterns[i] = this.typePatterns[i].parameterizeWith(typeVariableMap);
    }
    AnnotationPatternList ret = new AnnotationPatternList(parameterizedPatterns);
    ret.copyLocationFrom(this);
    return ret;
  }
 
  public void resolve(World inWorld) {
    for (int i = 0; i < typePatterns.length; i++) {
      typePatterns[i].resolve(inWorld);
    }
  }
 
  public FuzzyBoolean matches(ResolvedType[] someArgs) {
    // do some quick length tests first
      int numArgsMatchedByEllipsis = (someArgs.length + ellipsisCount) - typePatterns.length;
    if (numArgsMatchedByEllipsis < 0) return FuzzyBoolean.NO;
    if ((numArgsMatchedByEllipsis > 0) && (ellipsisCount == 0)) {
      return FuzzyBoolean.NO;
    }
    // now work through the args and the patterns, skipping at ellipsis
      FuzzyBoolean ret = FuzzyBoolean.YES;
      int argsIndex = 0;
      for (int i = 0; i < typePatterns.length; i++) {
      if (typePatterns[i] == AnnotationTypePattern.ELLIPSIS) {
        // match ellipsisMatchCount args
        argsIndex += numArgsMatchedByEllipsis;
      } else if (typePatterns[i] == AnnotationTypePattern.ANY) {
        argsIndex++;
      } else {
        // match the argument type at argsIndex with the ExactAnnotationTypePattern
        // we know it is exact because nothing else is allowed in args
        if (someArgs[argsIndex].isPrimitiveType()) return FuzzyBoolean.NO; // can never match
        ExactAnnotationTypePattern ap = (ExactAnnotationTypePattern)typePatterns[i];
        FuzzyBoolean matches = ap.matchesRuntimeType(someArgs[argsIndex]);
        if (matches == FuzzyBoolean.NO) {
          return FuzzyBoolean.MAYBE;  // could still match at runtime
        } else {
          argsIndex++;
          ret = ret.and(matches);
        }
      }
    }    
      return ret;
  }
 
  public int size() { return typePatterns.length; }
 
  public AnnotationTypePattern get(int index) {
    return typePatterns[index];
  }

  public AnnotationPatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) {
    for (int i=0; i<typePatterns.length; i++) {
      AnnotationTypePattern p = typePatterns[i];
      if (p != null) {
        typePatterns[i] = typePatterns[i].resolveBindings(scope, bindings, allowBinding);
      }
    }
    return this;
  }
 
  public AnnotationPatternList resolveReferences(IntMap bindings) {
    int len = typePatterns.length;
    AnnotationTypePattern[] ret = new AnnotationTypePattern[len];
    for (int i=0; i < len; i++) {
      ret[i] = typePatterns[i].remapAdviceFormals(bindings);
    }
    return new AnnotationPatternList(ret);
  }

    public String toString() {
      StringBuffer buf = new StringBuffer();
      buf.append("(");
      for (int i=0, len=typePatterns.length; i < len; i++) {
        AnnotationTypePattern type = typePatterns[i];
        if (i > 0) buf.append(", ");
        if (type == AnnotationTypePattern.ELLIPSIS) {
          buf.append("..");
        } else {
          String annPatt = type.toString();
          buf.append(annPatt.startsWith("@") ? annPatt.substring(1) : annPatt);
        }
      }
      buf.append(")");
      return buf.toString();
    }
   
  public boolean equals(Object other) {
    if (!(other instanceof AnnotationPatternList)) return false;
    AnnotationPatternList o = (AnnotationPatternList)other;
    int len = o.typePatterns.length;
    if (len != this.typePatterns.length) return false;
    for (int i=0; i<len; i++) {
      if (!this.typePatterns[i].equals(o.typePatterns[i])) return false;
    }
    return true;
  }
 
    public int hashCode() {
        int result = 41;
        for (int i = 0, len = typePatterns.length; i < len; i++) {
            result = 37*result + typePatterns[i].hashCode();
        }
        return result;
    }
   
  public static AnnotationPatternList read(VersionedDataInputStream s, ISourceContext context) throws IOException  {
    short len = s.readShort();
    AnnotationTypePattern[] arguments = new AnnotationTypePattern[len];
    for (int i=0; i<len; i++) {
      arguments[i] = AnnotationTypePattern.read(s, context);
    }
    AnnotationPatternList ret = new AnnotationPatternList(arguments);
    ret.readLocation(context, s);
    return ret;
  }


  public void write(DataOutputStream s) throws IOException {
    s.writeShort(typePatterns.length);
    for (int i=0; i<typePatterns.length; i++) {
      typePatterns[i].write(s);
    }
    writeLocation(s);
  }

    public Object accept(PatternNodeVisitor visitor, Object data) {
        return visitor.visit(this, data);
    }
 
  public Object traverse(PatternNodeVisitor visitor, Object data) {
    Object ret = accept(visitor, data);
    for (int i = 0; i < typePatterns.length; i++) {
      typePatterns[i].traverse(visitor,ret);
    }
    return ret;
  }

}
TOP

Related Classes of org.aspectj.weaver.patterns.AnnotationPatternList

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.