/* *******************************************************************
 * 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 Eclipse Public License v1.0 
 * which accompanies this distribution and is available at 
 * http://www.eclipse.org/legal/epl-v10.html 
 *  
 * Contributors: 
 *     PARC     initial implementation 
 * ******************************************************************/

package org.aspectj.weaver.patterns;

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

import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;

!TypePattern

any binding to formals is explicitly forbidden for any composite, ! is just the most obviously wrong case.

Author:Erik Hilsdale, Jim Hugunin
/** * !TypePattern * * <p> * any binding to formals is explicitly forbidden for any composite, ! is just the most obviously wrong case. * * @author Erik Hilsdale * @author Jim Hugunin */
public class NotTypePattern extends TypePattern { private TypePattern negatedPattern; private boolean isBangVoid = false; // is this '!void' private boolean checked = false; public NotTypePattern(TypePattern pattern) { super(false, false); // ??? we override all methods that care about includeSubtypes this.negatedPattern = pattern; setLocation(pattern.getSourceContext(), pattern.getStart(), pattern.getEnd()); } public TypePattern getNegatedPattern() { return negatedPattern; } @Override protected boolean couldEverMatchSameTypesAs(TypePattern other) { return true; } @Override public FuzzyBoolean matchesInstanceof(ResolvedType type) { return negatedPattern.matchesInstanceof(type).not(); } @Override protected boolean matchesExactly(ResolvedType type) { return (!negatedPattern.matchesExactly(type) && annotationPattern.matches(type).alwaysTrue()); } @Override protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { return (!negatedPattern.matchesExactly(type, annotatedType) && annotationPattern.matches(annotatedType).alwaysTrue()); } @Override public boolean matchesStatically(ResolvedType type) { return !negatedPattern.matchesStatically(type); } @Override public void setAnnotationTypePattern(AnnotationTypePattern annPatt) { super.setAnnotationTypePattern(annPatt); } @Override public void setIsVarArgs(boolean isVarArgs) { negatedPattern.setIsVarArgs(isVarArgs); } @Override public void write(CompressingDataOutputStream s) throws IOException { s.writeByte(TypePattern.NOT); negatedPattern.write(s); annotationPattern.write(s); writeLocation(s); } public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException { TypePattern ret = new NotTypePattern(TypePattern.read(s, context)); if (s.getMajorVersion() >= AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) { ret.annotationPattern = AnnotationTypePattern.read(s, context); } ret.readLocation(context, s); return ret; } @Override public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) { if (requireExactType) { return notExactType(scope); } negatedPattern = negatedPattern.resolveBindings(scope, bindings, false, false); return this; } @Override public boolean isBangVoid() { if (!checked) { isBangVoid = negatedPattern.getExactType().isVoid(); checked = true; } return isBangVoid; } @Override public TypePattern parameterizeWith(Map<String,UnresolvedType> typeVariableMap, World w) { TypePattern newNegatedPattern = negatedPattern.parameterizeWith(typeVariableMap, w); NotTypePattern ret = new NotTypePattern(newNegatedPattern); ret.copyLocationFrom(this); return ret; } @Override public String toString() { StringBuffer buff = new StringBuffer(); if (annotationPattern != AnnotationTypePattern.ANY) { buff.append('('); buff.append(annotationPattern.toString()); buff.append(' '); } buff.append('!'); buff.append(negatedPattern); if (annotationPattern != AnnotationTypePattern.ANY) { buff.append(')'); } return buff.toString(); } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (!(obj instanceof NotTypePattern)) { return false; } return (negatedPattern.equals(((NotTypePattern) obj).negatedPattern)); } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return 17 + 37 * negatedPattern.hashCode(); } @Override public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } @Override public Object traverse(PatternNodeVisitor visitor, Object data) { Object ret = accept(visitor, data); negatedPattern.traverse(visitor, ret); return ret; } }