Package org.aspectj.ajdt.internal.compiler.ast

Source Code of org.aspectj.ajdt.internal.compiler.ast.SuperFixerVisitor

/* *******************************************************************
* 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.ast;

import java.util.HashSet;
import java.util.Set;

import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
import org.aspectj.ajdt.internal.compiler.lookup.InterTypeMethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope;
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.MethodScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.ResolvedMember;

/**
* Takes a method that already has the three extra parameters thisJoinPointStaticPart, thisJoinPoint and
* thisEnclosingJoinPointStaticPart
*/

public class SuperFixerVisitor extends ASTVisitor {
  Set superMethodsCalled = new HashSet();
  AbstractMethodDeclaration method;
  ReferenceBinding targetClass;
  private int depthCounter = 0; // Keeps track of whether we are inside any nested local type declarations

  SuperFixerVisitor(AbstractMethodDeclaration method, ReferenceBinding targetClass) {
    this.method = method;
    this.targetClass = targetClass;
  }

  public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
    depthCounter++;
    return super.visit(localTypeDeclaration, scope);
  }

  public void endVisit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
    depthCounter--;
  }

  public void endVisit(MessageSend call, BlockScope scope) {
    // System.out.println("endVisit: " + call);
    // an error has already occurred
    if (call.codegenBinding == null)
      return;

    MethodBinding superBinding = call.codegenBinding;
    if (superBinding instanceof ProblemMethodBinding) {
      return;
    }
    // InterTypeMethodBindings are always statically bound, so there's no
    // need to treat super calls specially here
    if (superBinding instanceof InterTypeMethodBinding) {
      return;
      // InterTypeMethodBinding m = (InterTypeMethodBinding)superBinding;
      // if (m.postDispatchMethod != null) {
      // call.binding = m.postDispatchMethod;
      // }
      // return;
    }
    if (superBinding instanceof ParameterizedMethodBinding) {
      superBinding = ((ParameterizedMethodBinding) superBinding).original();
    }
    EclipseFactory factory = ((AjLookupEnvironment) method.scope.environment()).factory;
    if (depthCounter != 0 && targetClass.isInterface()) {// pr198196 - when calling MarkerInterface.super.XXX()
      if (call.isSuperAccess() && !call.binding.isStatic()) {
        MethodScope currentMethodScope = scope.methodScope();
        SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType();
        FieldBinding field = sourceType.addSyntheticFieldForInnerclass(targetClass);
        call.receiver = new KnownFieldReference(field, call.receiver.sourceStart, call.receiver.sourceEnd);
      } else {
        return;
      }
    } else if (depthCounter == 0) { // Allow case testSuperItds_pr198196_2/3

      char[] accessName;
      if (call.isSuperAccess() && !call.binding.isStatic()) {
        call.receiver = new ThisReference(call.receiver.sourceStart, call.receiver.sourceEnd);
        accessName = NameMangler.superDispatchMethod(factory.fromBinding(targetClass), new String(superBinding.selector))
            .toCharArray();
      } else if (call.receiver.isThis() && call.binding.isProtected() && !call.binding.isStatic()) {
        // XXX this is a hack that violates some binary compatibility rules
        ReferenceBinding superBindingDeclaringClass = superBinding.declaringClass;
        if (superBindingDeclaringClass.isParameterizedType()) {
          superBindingDeclaringClass = ((ParameterizedTypeBinding) superBindingDeclaringClass).type;
        }
        if (superBindingDeclaringClass.equals(targetClass)) {
          accessName = NameMangler.protectedDispatchMethod(factory.fromBinding(targetClass),
              new String(superBinding.selector)).toCharArray();
        } else {
          accessName = NameMangler.superDispatchMethod(factory.fromBinding(targetClass),
              new String(superBinding.selector)).toCharArray();
        }
      } else {
        return;
      }

      // ??? do we want these to be unique
      MethodBinding superAccessBinding = new MethodBinding(ClassFileConstants.AccPublic, accessName, superBinding.returnType,
          superBinding.parameters, superBinding.thrownExceptions, targetClass);

      AstUtil.replaceMethodBinding(call, superAccessBinding);
    } else {
      return;
    }
    ResolvedMember targetMember = null;
    if (superBinding.declaringClass.isParameterizedType()) { // pr206911
      targetMember = factory.makeResolvedMember(superBinding, ((ParameterizedTypeBinding) superBinding.declaringClass)
          .genericType());
    } else {
      targetMember = factory.makeResolvedMember(superBinding);
    }
    superMethodsCalled.add(targetMember);
  }
}
TOP

Related Classes of org.aspectj.ajdt.internal.compiler.ast.SuperFixerVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.