All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.ajdt.internal.compiler.lookup.InterTypeFieldBinding Maven / Gradle / Ivy

There is a newer version: 1.9.22.1
Show newest version
/* *******************************************************************
 * 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;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy