Logo Search packages:      
Sourcecode: aspectj version File versions

InterTypeFieldBinding.java

/* *******************************************************************
 * 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.ajdt.internal.compiler.lookup;

import org.aspectj.weaver.AjcMemberMaker;
import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;

public class InterTypeFieldBinding extends FieldBinding {
      public ReferenceBinding targetType;
      public SyntheticMethodBinding reader;
      public SyntheticMethodBinding writer;
      public AbstractMethodDeclaration sourceMethod;
      
      public InterTypeFieldBinding(EclipseFactory world, ResolvedTypeMunger munger, UnresolvedType withinType,
                                                      AbstractMethodDeclaration sourceMethod)
      {
            super(world.makeFieldBinding(munger.getSignature(),munger.getTypeVariableAliases()), null);
            this.sourceMethod = sourceMethod;
            
            targetType = (ReferenceBinding)world.makeTypeBinding(munger.getSignature().getDeclaringType());
            this.declaringClass = (ReferenceBinding)world.makeTypeBinding(withinType);
            // We called the super() with null, we must now do the last step that will have been skipped because of this, see the supers() final line:
            // OPTIMIZE dont makeFieldBinding twice, HORRIBLE
            setAnnotations(world.makeFieldBinding(munger.getSignature(),munger.getTypeVariableAliases()).getAnnotations());
            
            reader = new SimpleSyntheticAccessMethodBinding(
                                                world.makeMethodBinding(
                  AjcMemberMaker.interFieldGetDispatcher(munger.getSignature(), withinType)
            ));
            
            writer = new SimpleSyntheticAccessMethodBinding(world.makeMethodBinding(
                  AjcMemberMaker.interFieldSetDispatcher(munger.getSignature(), withinType)
            ));
      }
      
      public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
            scope.compilationUnitScope().recordTypeReference(declaringClass);
            //System.err.println("canBeSeenBy: " + this + ", " + isPublic());
            if (isPublic()) return true;  
      
            SourceTypeBinding invocationType = scope.invocationType();
            //System.out.println("receiver: " + receiverType + ", " + invocationType);
            ReferenceBinding declaringType = declaringClass;
            
            // FIXME asc what about parameterized types and private ITD generic fields on interfaces?
            
            // Don't work with a raw type, work with the generic type
            if (declaringClass.isRawType()) 
                   declaringType = ((RawTypeBinding)declaringClass).type;
            
            if (invocationType == declaringType) return true;
      
      
      //    if (invocationType.isPrivileged) {
      //          System.out.println("privileged access to: " + this);
      //          return true;
      //    }
            
            if (isProtected()) {
                  throw new RuntimeException("unimplemented");
            }
      
            //XXX make sure this walks correctly
            if (isPrivate()) {
                  // answer true if the receiverType is the declaringClass
                  // AND the invocationType and the declaringClass have a common enclosingType
                  
                  // see pr149071 - it has caused me to comment out this block below - what
                  // is it trying to achieve?  Possibly it should be using the scope.parentScope (the class scope of
                  // where the reference is being made) rather than the receiver type
                  
                  // Is the receiverType an innertype of the declaring type?
//                boolean receiverTypeIsSameOrInsideDeclaringType = receiverType == declaringType;
//                ReferenceBinding typeToCheckNext = receiverType.enclosingType();
//                while (!receiverTypeIsSameOrInsideDeclaringType && typeToCheckNext!=null) {
//                      if (typeToCheckNext==declaringType) receiverTypeIsSameOrInsideDeclaringType=true;
//                }
//                if (!receiverTypeIsSameOrInsideDeclaringType) return false;
                  
                  
                  // the code above replaces this line: (pr118698)
//                if (receiverType != declaringType) return false;
      
                  if (invocationType != declaringType) {
                        ReferenceBinding outerInvocationType = invocationType;
                        ReferenceBinding temp = outerInvocationType.enclosingType();
                        while (temp != null) {
                              outerInvocationType = temp;
                              temp = temp.enclosingType();
                        }
      
                        ReferenceBinding outerDeclaringClass = declaringType;
                        temp = outerDeclaringClass.enclosingType();
                        while (temp != null) {
                              outerDeclaringClass = temp;
                              temp = temp.enclosingType();
                        }
                        if (outerInvocationType != outerDeclaringClass) return false;
                  }
                  return true;
            }
      
            // isDefault()
            if (invocationType.fPackage == declaringClass.fPackage) return true;
            return false;
      }

      public SyntheticMethodBinding getAccessMethod(boolean isReadAccess) {
            if (isReadAccess) return reader;
            else return writer;
      }
      
      public boolean alwaysNeedsAccessMethod(boolean isReadAccess) { return true; }

      

      public ReferenceBinding getTargetType() {
            return targetType;
      }
      
      // overrides ITD'd method in FieldBinding...
      public ReferenceBinding getOwningClass() {
            return targetType;
      }

}

Generated by  Doxygen 1.6.0   Back to index