123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- /* *******************************************************************
- * 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.lang.reflect.Modifier;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.NoSuchElementException;
- import java.util.Set;
-
- /**
- * Iterates over the signatures of a join point, calculating new signatures lazily to minimize processing and to avoid unneccessary
- * "can't find type" errors. Iterator can be cached and reused by calling the "reset" method between iterations.
- */
- public class JoinPointSignatureIterator implements Iterator<JoinPointSignature> {
-
- ResolvedType firstDefiningType;
-
- private Member signaturesOfMember;
- private ResolvedMember firstDefiningMember;
- private World world;
- private List<JoinPointSignature> discoveredSignatures = new ArrayList<JoinPointSignature>();
- private List<JoinPointSignature> additionalSignatures = Collections.emptyList();
- private Iterator<JoinPointSignature> discoveredSignaturesIterator = null;
- private Iterator<ResolvedType> superTypeIterator = null;
- private boolean isProxy = false;
- private Set<ResolvedType> visitedSuperTypes = new HashSet<ResolvedType>();
- private List<SearchPair> yetToBeProcessedSuperMembers = null;
-
- private boolean iteratingOverDiscoveredSignatures = true;
- private boolean couldBeFurtherAsYetUndiscoveredSignatures = true;
- private final static UnresolvedType jlrProxy = UnresolvedType.forSignature("Ljava/lang/reflect/Proxy;");
-
- public JoinPointSignatureIterator(Member joinPointSignature, World world) {
- this.signaturesOfMember = joinPointSignature;
- this.world = world;
- addSignaturesUpToFirstDefiningMember();
- if (!shouldWalkUpHierarchy()) {
- couldBeFurtherAsYetUndiscoveredSignatures = false;
- }
- }
-
- public void reset() {
- discoveredSignaturesIterator = discoveredSignatures.iterator();
- additionalSignatures.clear();
- iteratingOverDiscoveredSignatures = true;
- }
-
- public boolean hasNext() {
- if (iteratingOverDiscoveredSignatures && discoveredSignaturesIterator.hasNext()) {
- return true;
- } else if (couldBeFurtherAsYetUndiscoveredSignatures) {
- if (additionalSignatures.size() > 0) {
- return true;
- } else {
- return findSignaturesFromSupertypes();
- }
- } else {
- return false;
- }
- }
-
- public JoinPointSignature next() {
- if (iteratingOverDiscoveredSignatures && discoveredSignaturesIterator.hasNext()) {
- return discoveredSignaturesIterator.next();
- } else {
- if (additionalSignatures.size() > 0) {
- return additionalSignatures.remove(0);
- }
- }
- throw new NoSuchElementException();
- }
-
- public void remove() {
- throw new UnsupportedOperationException("can't remove from JoinPointSignatureIterator");
- }
-
- /**
- * Walk up the hierarchy creating one member for each type up to and including the first defining type.
- */
- private void addSignaturesUpToFirstDefiningMember() {
- ResolvedType originalDeclaringType = signaturesOfMember.getDeclaringType().resolve(world);
- ResolvedType superType = originalDeclaringType.getSuperclass();
- if (superType != null && superType.equals(jlrProxy)) {
- // Proxy types are generated without any regard to generics (pr268419) and so the member walking
- // should also ignore them
- isProxy = true;
- }
-
- // is it the array constructor join point?
- if (world.isJoinpointArrayConstructionEnabled() && originalDeclaringType.isArray()) {
- Member m = signaturesOfMember;
- ResolvedMember rm = new ResolvedMemberImpl(m.getKind(), m.getDeclaringType(), m.getModifiers(), m.getReturnType(), m
- .getName(), m.getParameterTypes());
- discoveredSignatures.add(new JoinPointSignature(rm, originalDeclaringType));
- couldBeFurtherAsYetUndiscoveredSignatures = false;
- return;
- }
-
- firstDefiningMember = (signaturesOfMember instanceof ResolvedMember ?
- (ResolvedMember) signaturesOfMember: signaturesOfMember.resolve(world));
-
- if (firstDefiningMember == null) {
- couldBeFurtherAsYetUndiscoveredSignatures = false;
- return;
- }
-
- // declaringType can be unresolved if we matched a synthetic member generated by Aj...
- // should be fixed elsewhere but add this resolve call on the end for now so that we can
- // focus on one problem at a time...
- firstDefiningType = firstDefiningMember.getDeclaringType().resolve(world);
- if (firstDefiningType != originalDeclaringType) {
- if (signaturesOfMember.getKind() == Member.CONSTRUCTOR) {
- return;
- }
- }
-
- if (originalDeclaringType == firstDefiningType) {
- // a common case
- discoveredSignatures.add(new JoinPointSignature(firstDefiningMember, originalDeclaringType));
- } else {
- List<ResolvedType> declaringTypes = new ArrayList<ResolvedType>();
- accumulateTypesInBetween(originalDeclaringType, firstDefiningType, declaringTypes);
- for (ResolvedType declaringType : declaringTypes) {
- discoveredSignatures.add(new JoinPointSignature(firstDefiningMember, declaringType));
- }
- }
- }
-
- /**
- * Build a list containing every type between subtype and supertype, inclusively.
- */
- private void accumulateTypesInBetween(ResolvedType subType, ResolvedType superType, List<ResolvedType> types) {
- types.add(subType);
- if (subType == superType) {
- return;
- } else {
- for (Iterator<ResolvedType> iter = subType.getDirectSupertypes(); iter.hasNext();) {
- ResolvedType parent = iter.next();
- if (superType.isAssignableFrom(parent, true)) {
- accumulateTypesInBetween(parent, superType, types);
- }
- }
- }
- }
-
- private boolean shouldWalkUpHierarchy() {
- if (signaturesOfMember.getKind() == Member.CONSTRUCTOR) {
- return false;
- }
- if (signaturesOfMember.getKind() == Member.FIELD) {
- return false;
- }
- if (Modifier.isStatic(signaturesOfMember.getModifiers())) {
- return false;
- }
- return true;
- }
-
- private boolean findSignaturesFromSupertypes() {
- iteratingOverDiscoveredSignatures = false;
- if (superTypeIterator == null) {
- superTypeIterator = firstDefiningType.getDirectSupertypes();
- }
- if (superTypeIterator.hasNext()) {
- ResolvedType superType = superTypeIterator.next();
- if (isProxy && (superType.isGenericType() || superType.isParameterizedType())) {
- superType = superType.getRawType();
- }
- if (visitedSuperTypes.contains(superType)) {
- return findSignaturesFromSupertypes();
- } else {
- // we haven't looked in this type yet
- visitedSuperTypes.add(superType);
- if (superType.isMissing()) {
- // issue a warning, stop looking for join point signatures in this line
- warnOnMissingType(superType);
- return findSignaturesFromSupertypes();
- }
- ResolvedMemberImpl foundMember = (ResolvedMemberImpl) superType.lookupResolvedMember(firstDefiningMember, true,
- isProxy);
- if (foundMember != null && isVisibleTo(firstDefiningMember, foundMember)) {
- List<ResolvedType> declaringTypes = new ArrayList<ResolvedType>();
- // declaring type can be unresolved if the member can from an ITD...
- ResolvedType resolvedDeclaringType = foundMember.getDeclaringType().resolve(world);
- accumulateTypesInBetween(superType, resolvedDeclaringType, declaringTypes);
- for (ResolvedType declaringType : declaringTypes) {
- JoinPointSignature member = null;
- if (isProxy) {
- if (declaringType.isGenericType() || declaringType.isParameterizedType()) {
- declaringType = declaringType.getRawType();
- }
- }
- member = new JoinPointSignature(foundMember, declaringType);
- discoveredSignatures.add(member); // for next time we are reset
- if (additionalSignatures == Collections.EMPTY_LIST) {
- additionalSignatures = new ArrayList<JoinPointSignature>();
- }
- additionalSignatures.add(member); // for this time
- }
- // if this was a parameterized type, look in the generic type that backs it too
- if (!isProxy && superType.isParameterizedType() && (foundMember.backingGenericMember != null)) {
- JoinPointSignature member = new JoinPointSignature(foundMember.backingGenericMember,
- foundMember.declaringType.resolve(world));
- discoveredSignatures.add(member); // for next time we are reset
- if (additionalSignatures == Collections.EMPTY_LIST) {
- additionalSignatures = new ArrayList<JoinPointSignature>();
- }
- additionalSignatures.add(member); // for this time
- }
- if (yetToBeProcessedSuperMembers == null) {
- yetToBeProcessedSuperMembers = new ArrayList<SearchPair>();
- }
- yetToBeProcessedSuperMembers.add(new SearchPair(foundMember, superType));
- return true;
- } else {
- return findSignaturesFromSupertypes();
- }
- }
- }
- if (yetToBeProcessedSuperMembers != null && !yetToBeProcessedSuperMembers.isEmpty()) {
- SearchPair nextUp = yetToBeProcessedSuperMembers.remove(0);
- firstDefiningType = nextUp.type;
- firstDefiningMember = nextUp.member;
- superTypeIterator = null;
- return findSignaturesFromSupertypes();
- }
- couldBeFurtherAsYetUndiscoveredSignatures = false;
- return false;
- }
-
- /**
- * Returns true if the parent member is visible to the child member In the same declaring type this is always true, otherwise if
- * parent is private it is false.
- *
- * @param childMember
- * @param parentMember
- * @return
- */
- private boolean isVisibleTo(ResolvedMember childMember, ResolvedMember parentMember) {
- if (childMember.getDeclaringType().equals(parentMember.getDeclaringType())) {
- return true;
- }
- if (Modifier.isPrivate(parentMember.getModifiers())) {
- return false;
- } else {
- return true;
- }
- }
-
- private void warnOnMissingType(ResolvedType missing) {
- if (missing instanceof MissingResolvedTypeWithKnownSignature) {
- // which it should be...
- MissingResolvedTypeWithKnownSignature mrt = (MissingResolvedTypeWithKnownSignature) missing;
- mrt.raiseWarningOnJoinPointSignature(signaturesOfMember.toString());
- }
- }
-
- private static class SearchPair {
- public ResolvedMember member;
- public ResolvedType type;
-
- public SearchPair(ResolvedMember member, ResolvedType type) {
- this.member = member;
- this.type = type;
- }
- }
-
- }
|