123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /* *******************************************************************
- * 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
- * Nieraj Singh
- * ******************************************************************/
- package org.aspectj.weaver.patterns;
-
- import java.io.IOException;
- import java.lang.reflect.Modifier;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
-
- import org.aspectj.bridge.IMessage;
- import org.aspectj.util.FuzzyBoolean;
- import org.aspectj.weaver.CompressingDataOutputStream;
- import org.aspectj.weaver.ConcreteTypeMunger;
- import org.aspectj.weaver.ISourceContext;
- import org.aspectj.weaver.Member;
- import org.aspectj.weaver.ResolvedMember;
- import org.aspectj.weaver.ResolvedType;
- import org.aspectj.weaver.VersionedDataInputStream;
- import org.aspectj.weaver.WeaverMessages;
- import org.aspectj.weaver.World;
-
- /**
- * @author colyer Matches types that have a certain method / constructor / field Currently only allowed within declare parents and
- * declare @type
- */
- public class HasMemberTypePattern extends TypePattern {
-
- private SignaturePattern signaturePattern;
-
- public HasMemberTypePattern(SignaturePattern aSignaturePattern) {
- super(false, false);
- this.signaturePattern = aSignaturePattern;
- }
-
- @Override
- protected boolean matchesExactly(ResolvedType type) {
- if (signaturePattern.getKind() == Member.FIELD) {
- return hasField(type);
- } else {
- return hasMethod(type);
- }
- }
-
- public ISignaturePattern getSignaturePattern() {
- return signaturePattern;
- }
-
- private final static String declareAtPrefix = "ajc$declare_at";
-
- private boolean hasField(ResolvedType type) {
- // TODO what about ITDs
- World world = type.getWorld();
- for (Iterator iter = type.getFields(); iter.hasNext();) {
- Member field = (Member) iter.next();
- if (field.getName().startsWith(declareAtPrefix)) {
- continue;
- }
- if (signaturePattern.matches(field, type.getWorld(), false)) {
- if (field.getDeclaringType().resolve(world) != type) {
- if (Modifier.isPrivate(field.getModifiers())) {
- continue;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- protected boolean hasMethod(ResolvedType type) {
- // TODO what about ITDs
- World world = type.getWorld();
- for (Iterator<ResolvedMember> iter = type.getMethods(true, true); iter.hasNext();) {
- Member method = (Member) iter.next();
- if (method.getName().startsWith(declareAtPrefix)) {
- continue;
- }
- if (signaturePattern.matches(method, type.getWorld(), false)) {
- ResolvedType declaringType = method.getDeclaringType().resolve(world);
- if (declaringType != type) {
- if (Modifier.isPrivate(method.getModifiers())) {
- continue;
- }
- }
- // J9: Object.finalize() is marked Deprecated it seems... triggers unhelpful messages
- if (method.getName().equals("finalize") && declaringType.equals(ResolvedType.OBJECT)
- && (signaturePattern.getAnnotationPattern() instanceof ExactAnnotationTypePattern)
- && ((ExactAnnotationTypePattern)signaturePattern.getAnnotationPattern()).getAnnotationType().getSignature().equals("Ljava/lang/Deprecated;")) {
- continue;
- }
- return true;
- }
- }
- // try itds before we give up (this doesnt find annotations - the signature returned may not include them)
- List<ConcreteTypeMunger> mungers = type.getInterTypeMungersIncludingSupers();
- for (Iterator<ConcreteTypeMunger> iter = mungers.iterator(); iter.hasNext();) {
- ConcreteTypeMunger munger = iter.next();
- Member member = munger.getSignature();
- if (signaturePattern.matches(member, type.getWorld(), false)) {
- if (!Modifier.isPublic(member.getModifiers())) {
- continue;
- }
- return true;
- }
- }
- return false;
- }
-
- @Override
- protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
- return matchesExactly(type);
- }
-
- @Override
- public FuzzyBoolean matchesInstanceof(ResolvedType type) {
- throw new UnsupportedOperationException("hasmethod/field do not support instanceof matching");
- }
-
- @Override
- public TypePattern parameterizeWith(Map typeVariableMap, World w) {
- HasMemberTypePattern ret = new HasMemberTypePattern(signaturePattern.parameterizeWith(typeVariableMap, w));
- ret.copyLocationFrom(this);
- return ret;
- }
-
- @Override
- public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
- // check that hasmember type patterns are allowed!
- if (!scope.getWorld().isHasMemberSupportEnabled()) {
- String msg = WeaverMessages.format(WeaverMessages.HAS_MEMBER_NOT_ENABLED, this.toString());
- scope.message(IMessage.ERROR, this, msg);
- }
- signaturePattern.resolveBindings(scope, bindings);
- return this;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof HasMemberTypePattern)) {
- return false;
- }
- if (this == obj) {
- return true;
- }
- return signaturePattern.equals(((HasMemberTypePattern) obj).signaturePattern);
- }
-
- @Override
- public int hashCode() {
- return signaturePattern.hashCode();
- }
-
- @Override
- public String toString() {
- StringBuffer buff = new StringBuffer();
- if (signaturePattern.getKind() == Member.FIELD) {
- buff.append("hasfield(");
- } else {
- buff.append("hasmethod(");
- }
- buff.append(signaturePattern.toString());
- buff.append(")");
- return buff.toString();
- }
-
- @Override
- public void write(CompressingDataOutputStream s) throws IOException {
- s.writeByte(TypePattern.HAS_MEMBER);
- signaturePattern.write(s);
- writeLocation(s);
- }
-
- public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
- SignaturePattern sp = SignaturePattern.read(s, context);
- HasMemberTypePattern ret = new HasMemberTypePattern(sp);
- ret.readLocation(context, s);
- return ret;
- }
-
- @Override
- public Object accept(PatternNodeVisitor visitor, Object data) {
- return visitor.visit(this, data);
- }
-
- }
|