import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseTypeMunger;
+import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedFieldBinding;
+import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler;
+import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+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.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
import org.aspectj.weaver.AjAttribute;
public void resolveOnType(ClassScope classScope) {
super.resolveOnType(classScope);
- if (ignoreFurtherInvestigation)
+ if (ignoreFurtherInvestigation) {
return;
+ }
if (Modifier.isStatic(declaredModifiers) && onTypeBinding.isInterface()) {
scope.problemReporter().signalError(sourceStart, sourceEnd, "static inter-type field on interface not supported");
ignoreFurtherInvestigation = true;
}
public void resolve(ClassScope upperScope) {
- if (munger == null)
+ if (munger == null) {
ignoreFurtherInvestigation = true;
- if (ignoreFurtherInvestigation)
+ }
+ if (ignoreFurtherInvestigation) {
return;
+ }
EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(upperScope);
ResolvedMember sig = munger.getSignature();
EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(classScope);
resolveOnType(classScope);
- if (ignoreFurtherInvestigation)
+ if (ignoreFurtherInvestigation) {
return null;
+ }
binding = classScope.referenceContext.binding.resolveTypesFor(binding);
- if (ignoreFurtherInvestigation)
+ if (ignoreFurtherInvestigation) {
return null;
+ }
- if (isTargetAnnotation(classScope, "field"))
+ if (isTargetAnnotation(classScope, "field")) {
return null; // Error message output in isTargetAnnotation
- if (isTargetEnum(classScope, "field"))
+ }
+ if (isTargetEnum(classScope, "field")) {
return null; // Error message output in isTargetEnum
+ }
if (!Modifier.isStatic(declaredModifiers)) {
super.binding.parameters = new TypeBinding[] { onTypeBinding, };
declaringType = declaringType.getGenericType();
}
- if (interTypeScope == null)
+ if (interTypeScope == null) {
return null; // We encountered a problem building the scope, don't continue - error already reported
+ }
// Build a half correct resolvedmember (makeResolvedMember understands tvars) then build a fully correct sig from it
ResolvedMember sigtemp = world.makeResolvedMemberForITD(binding, onTypeBinding, interTypeScope.getRecoveryAliases());
}
public void generateCode(ClassScope classScope, ClassFile classFile) {
- if (ignoreFurtherInvestigation)
+ if (ignoreFurtherInvestigation) {
return;
+ }
classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute()));
super.generateCode(classScope, classFile);
CodeStream codeStream = classFile.codeStream;
codeStream.reset(this, classFile);
- FieldBinding classField = world.makeFieldBinding(AjcMemberMaker.interFieldClassField(sig, aspectType), munger
- .getTypeVariableAliases());
+ NewFieldTypeMunger fieldMunger = (NewFieldTypeMunger) munger;
+
+ // Force use of version 1 if there is a field with that name on the type already
+ if (world.getItdVersion() == 1) {
+ fieldMunger.version = NewFieldTypeMunger.VersionOne;
+ } else {
+ if (!onTypeBinding.isInterface()) {
+ FieldBinding[] existingFields = onTypeBinding.fields();
+ for (int f = 0; f < existingFields.length; f++) {
+ FieldBinding fieldBinding = existingFields[f];
+ if (CharOperation.equals(fieldBinding.name, sig.getName().toCharArray())) {
+ fieldMunger.version = NewFieldTypeMunger.VersionOne;
+ }
+ }
+ }
+ }
+
+ FieldBinding classField = world.makeFieldBinding(AjcMemberMaker.interFieldClassField(sig, aspectType,
+ fieldMunger.version == NewFieldTypeMunger.VersionTwo), munger.getTypeVariableAliases());
codeStream.initializeMaxLocals(binding);
if (isGetter) {
}
private void generateClassReadBody(MethodBinding binding, FieldBinding field, CodeStream codeStream) {
+ if (field.isPrivate() || !field.canBeSeenBy(binding.declaringClass.fPackage)) {
+
+ PrivilegedHandler handler = (PrivilegedHandler) Scope.findPrivilegedHandler(binding.declaringClass);
+ if (handler == null) {
+ // one is now required!
+ ReferenceBinding typebinding = binding.declaringClass;
+ if (typebinding instanceof ReferenceBinding) {
+ SourceTypeBinding sourceBinding = (SourceTypeBinding) typebinding;
+ handler = new PrivilegedHandler((AspectDeclaration) sourceBinding.scope.referenceContext);
+ sourceBinding.privilegedHandler = handler;
+ }
+ }
+ PrivilegedFieldBinding fBinding = (PrivilegedFieldBinding) handler.getPrivilegedAccessField(field, null);
+
+ if (field.isStatic()) {
+ codeStream.invokestatic(fBinding.reader);
+ } else {
+ codeStream.aload_0();
+ codeStream.invokestatic(fBinding.reader);
+ }
+ return;
+ }
if (field.isStatic()) {
codeStream.getstatic(field);
} else {
}
private void generateClassWriteBody(MethodBinding binding, FieldBinding field, CodeStream codeStream) {
+ if (field.isPrivate() || !field.canBeSeenBy(binding.declaringClass.fPackage)) {
+ PrivilegedFieldBinding fBinding = (PrivilegedFieldBinding) Scope.findPrivilegedHandler(binding.declaringClass)
+ .getPrivilegedAccessField(field, null);
+
+ if (field.isStatic()) {
+ codeStream.load(field.type, 0);
+ codeStream.invokestatic(fBinding.writer);
+ } else {
+ codeStream.aload_0();
+ codeStream.load(field.type, 1);
+ codeStream.invokestatic(fBinding.writer);
+ }
+ return;
+ }
if (field.isStatic()) {
codeStream.load(field.type, 0);
codeStream.putstatic(field);
+ " should be recompiled with ajc-1.1.1 for best results", onType.getSourceLocation(), null);
needOldStyleWarning = false;
}
- onType.addInterTypeMunger(munger);
+ onType.addInterTypeMunger(munger, true);
}
}
* with its target type.
*/
public ResolvedMemberImpl makeResolvedMemberForITD(MethodBinding binding, TypeBinding declaringType, Map /*
- * TypeVariableBinding >
- * original alias name
- */recoveryAliases) {
+ * TypeVariableBinding >
+ * original alias name
+ */recoveryAliases) {
ResolvedMemberImpl result = null;
try {
typeVariablesForAliasRecovery = recoveryAliases;
this.rawTypeXToBinding.clear();
}
+ public int getItdVersion() {
+ return world.getItdVersion();
+ }
+
}
}
targetTypeX = munger.getSignature().getDeclaringType().resolve(world.getWorld());
// AMC, needed until generic and raw have distinct sigs...
- if (targetTypeX.isParameterizedType() || targetTypeX.isRawType())
+ if (targetTypeX.isParameterizedType() || targetTypeX.isRawType()) {
targetTypeX = targetTypeX.getGenericType();
- // targetBinding = (ReferenceBinding)world.makeTypeBinding(targetTypeX);
+ // targetBinding = (ReferenceBinding)world.makeTypeBinding(targetTypeX);
+ }
}
public static boolean supportsKind(ResolvedTypeMunger.Kind kind) {
*/
public boolean munge(SourceTypeBinding sourceType, ResolvedType onType) {
ResolvedType rt = onType;
- if (rt.isRawType() || rt.isParameterizedType())
+ if (rt.isRawType() || rt.isParameterizedType()) {
rt = rt.getGenericType();
+ }
boolean isExactTargetType = rt.equals(targetTypeX);
if (!isExactTargetType) {
// might be the topmost implementor of an interface we care about
- if (munger.getKind() != ResolvedTypeMunger.Method)
+ if (munger.getKind() != ResolvedTypeMunger.Method) {
return false;
- if (onType.isInterface())
+ }
+ if (onType.isInterface()) {
return false;
- if (!munger.needsAccessToTopmostImplementor())
+ }
+ if (!munger.needsAccessToTopmostImplementor()) {
return false;
+ }
// so we do need access, and this type could be it...
- if (!onType.isTopmostImplementor(targetTypeX))
+ if (!onType.isTopmostImplementor(targetTypeX)) {
return false;
+ }
// we are the topmost implementor of an interface type that needs munging
// but we only care about public methods here (we only do this at all to
// drive the JDT MethodVerifier correctly)
- if (!Modifier.isPublic(munger.getSignature().getModifiers()))
+ if (!Modifier.isPublic(munger.getSignature().getModifiers())) {
return false;
+ }
}
// System.out.println("munging: " + sourceType);
// System.out.println("match: " + world.fromEclipse(sourceType) +
if (sourceType.isInterface()) {
boolean isAbstract = (binding.modifiers & ClassFileConstants.AccAbstract) != 0;
binding.modifiers = (binding.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate));
- if (isAbstract)
+ if (isAbstract) {
binding.modifiers |= ClassFileConstants.AccAbstract;
+ }
}
- if (munger.getSignature().isVarargsMethod())
+ if (munger.getSignature().isVarargsMethod()) {
binding.modifiers |= ClassFileConstants.AccVarargs;
+ }
findOrCreateInterTypeMemberFinder(sourceType).addInterTypeMethod(binding);
return true;
}
String name = new String(tv.sourceName);
TypeVariableBinding[] tv2 = sourceMethod.binding.typeVariables;
for (int j = 0; j < tv2.length; j++) {
- if (new String(tv2[j].sourceName).equals(name))
+ if (new String(tv2[j].sourceName).equals(name)) {
typeVariables[i].declaringElement = binding;
+ }
}
}
for (int i = 0; i < typeVariables.length; i++) {
- if (typeVariables[i].declaringElement == null)
+ if (typeVariables[i].declaringElement == null) {
throw new RuntimeException("Declaring element not set");
+ }
}
// classScope.referenceContext.binding.addMethod(binding);
// classScope.referenceContext.binding.addField(binding);
} else {
InterTypeFieldBinding binding = new InterTypeFieldBinding(world, munger, aspectType, sourceMethod);
- findOrCreateInterTypeMemberFinder(sourceType).addInterTypeField(binding);
+ InterTypeMemberFinder finder = findOrCreateInterTypeMemberFinder(sourceType);
+ // Downgrade this field munger if name is already 'claimed'
+ if (finder.definesField(munger.getSignature().getName())) {
+ munger.version = NewFieldTypeMunger.VersionOne;
+ }
+ finder.addInterTypeField(binding);
}
}
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.ajdt.internal.compiler.lookup;
import org.aspectj.weaver.AjcMemberMaker;
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);
+ 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:
+
+ 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)
- ));
+ 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;
-
+ // System.err.println("canBeSeenBy: " + this + ", " + isPublic());
+ if (isPublic())
+ return true;
+
SourceTypeBinding invocationType = scope.invocationType();
- //System.out.println("receiver: " + receiverType + ", " + 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 (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
+
+ // 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
+ // 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;
-
-
+ // 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 (receiverType != declaringType) return false;
+
if (invocationType != declaringType) {
ReferenceBinding outerInvocationType = invocationType;
ReferenceBinding temp = outerInvocationType.enclosingType();
outerInvocationType = temp;
temp = temp.enclosingType();
}
-
+
ReferenceBinding outerDeclaringClass = declaringType;
temp = outerDeclaringClass.enclosingType();
while (temp != null) {
outerDeclaringClass = temp;
temp = temp.enclosingType();
}
- if (outerInvocationType != outerDeclaringClass) return false;
+ if (outerInvocationType != outerDeclaringClass)
+ return false;
}
return true;
}
-
+
// isDefault()
- if (invocationType.fPackage == declaringClass.fPackage) return true;
+ if (invocationType.fPackage == declaringClass.fPackage)
+ return true;
return false;
}
public SyntheticMethodBinding getAccessMethod(boolean isReadAccess) {
- if (isReadAccess) return reader;
- else return writer;
+ if (isReadAccess)
+ return reader;
+ else
+ return writer;
}
-
- public boolean alwaysNeedsAccessMethod(boolean isReadAccess) { return true; }
-
+ public boolean alwaysNeedsAccessMethod(boolean isReadAccess) {
+ return true;
+ }
public ReferenceBinding getTargetType() {
return targetType;
}
-
+
// overrides ITD'd method in FieldBinding...
public ReferenceBinding getOwningClass() {
return targetType;
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.ajdt.internal.compiler.lookup;
import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
public class PrivilegedFieldBinding extends FieldBinding {
public SimpleSyntheticAccessMethodBinding reader;
public SimpleSyntheticAccessMethodBinding writer;
-
-
+
public FieldBinding baseField;
-
+
public PrivilegedFieldBinding(AspectDeclaration inAspect, FieldBinding baseField) {
super(baseField, baseField.declaringClass);
- this.reader = new SimpleSyntheticAccessMethodBinding(
- inAspect.factory.makeMethodBinding(
- AjcMemberMaker.privilegedAccessMethodForFieldGet(
- inAspect.typeX, inAspect.factory.makeResolvedMember(baseField)
- )));
- this.writer = new SimpleSyntheticAccessMethodBinding(inAspect.factory.makeMethodBinding(
- AjcMemberMaker.privilegedAccessMethodForFieldSet(
- inAspect.typeX, inAspect.factory.makeResolvedMember(baseField)
- )));
-
+ this.reader = new SimpleSyntheticAccessMethodBinding(inAspect.factory.makeMethodBinding(AjcMemberMaker
+ .privilegedAccessMethodForFieldGet(inAspect.typeX, inAspect.factory.makeResolvedMember(baseField), true)));
+ this.writer = new SimpleSyntheticAccessMethodBinding(inAspect.factory.makeMethodBinding(AjcMemberMaker
+ .privilegedAccessMethodForFieldSet(inAspect.typeX, inAspect.factory.makeResolvedMember(baseField), true)));
+
this.constant = Constant.NotAConstant;
this.baseField = baseField;
}
-
public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
return true;
-
}
-
public SyntheticMethodBinding getAccessMethod(boolean isReadAccess) {
if (baseField.alwaysNeedsAccessMethod(isReadAccess)) {
return baseField.getAccessMethod(isReadAccess);
}
- if (isReadAccess) return reader;
- else return writer;
+ if (isReadAccess) {
+ return reader;
+ } else {
+ return writer;
+ }
}
-
- public boolean alwaysNeedsAccessMethod(boolean isReadAccess) { return true; }
- public FieldBinding getFieldBindingForLookup() { return baseField; }
+ public boolean alwaysNeedsAccessMethod(boolean isReadAccess) {
+ return true;
+ }
+ public FieldBinding getFieldBindingForLookup() {
+ return baseField;
+ }
- public String toString() { return "PrivilegedWrapper(" + baseField + ")"; }
-// public ReferenceBinding getTargetType() {
-// return introducedField.declaringClass;
-// }
+ public String toString() {
+ return "PrivilegedWrapper(" + baseField + ")";
+ }
+ // public ReferenceBinding getTargetType() {
+ // return introducedField.declaringClass;
+ // }
}