blob: b47978f6283ec35daa2773fa59ee56b5d355b8c4 [file] [log] [blame]
/* *******************************************************************
* 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(), false);
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;
if (invocationType == null) // static import call
return !isPrivate() && scope.getCurrentPackage() == receiverType.getPackage();
// 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;
}
}