Java Code Examples for com.sun.tools.javac.tree.JCTree#JCMethodInvocation

The following examples show how to use com.sun.tools.javac.tree.JCTree#JCMethodInvocation . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 6 votes vote down vote up
private JCExpression replaceStringLiteral( Symbol.ClassSymbol fragSym, JCTree tree, String methodName, String type )
{
  TreeMaker make = _tp.getTreeMaker();
  Names names = Names.instance( _tp.getContext() );

  Symbol.MethodSymbol fragmentValueMethod = resolveMethod( tree.pos(), names.fromString( methodName ),
    fragSym.type, List.nil() );

  JCTree.JCMethodInvocation fragmentValueCall = make.Apply( List.nil(),
    memberAccess( make, _tp.getElementUtil(), fragSym.getQualifiedName() + "." + methodName ), List.nil() );
  fragmentValueCall.type = fragmentValueMethod.getReturnType(); // type
  fragmentValueCall.setPos( tree.pos );
  JCTree.JCFieldAccess newMethodSelect = (JCTree.JCFieldAccess)fragmentValueCall.getMethodSelect();
  newMethodSelect.sym = fragmentValueMethod;
  newMethodSelect.type = fragmentValueMethod.type;
  assignTypes( newMethodSelect.selected, fragSym );

  return fragmentValueCall;
}
 
Example 2
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 6 votes vote down vote up
@SuppressWarnings("WeakerAccess")
public static boolean isJailbreakReceiver( JCTree.JCFieldAccess fieldAccess )
{
  Symbol sym = null;
  JCExpression selected = fieldAccess.selected;
  if( selected instanceof JCTree.JCIdent )
  {
    sym = ((JCTree.JCIdent)selected).sym;
  }
  else if( selected instanceof JCTree.JCMethodInvocation )
  {
    if( ((JCTree.JCMethodInvocation)selected).meth instanceof JCTree.JCFieldAccess )
    {
      sym = ((JCTree.JCFieldAccess)((JCTree.JCMethodInvocation)selected).meth).sym;
    }
    else if( ((JCTree.JCMethodInvocation)selected).meth instanceof JCTree.JCIdent )
    {
      sym = ((JCTree.JCIdent)((JCTree.JCMethodInvocation)selected).meth).sym;
    }
  }

  return isJailbreakSymbol( sym );
}
 
Example 3
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 6 votes vote down vote up
private boolean isStructuralMethod( JCTree.JCMethodInvocation tree )
{
  JCExpression methodSelect = tree.getMethodSelect();
  if( methodSelect instanceof JCTree.JCFieldAccess )
  {
    JCTree.JCFieldAccess m = (JCTree.JCFieldAccess)methodSelect;
    if( m.sym != null && !m.sym.getModifiers().contains( javax.lang.model.element.Modifier.STATIC ) )
    {
      if( !isObjectMethod( m.sym ) )
      {
        JCExpression thisArg = m.selected;
        return TypeUtil.isStructuralInterface( _tp, thisArg.type.tsym );
      }
    }
  }
  return false;
}
 
Example 4
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 6 votes vote down vote up
private JCTree.JCMethodInvocation configMethod( JCTree.JCBinary tree, Symbol.MethodSymbol operatorMethod, JCTree.JCMethodInvocation methodCall )
{
  methodCall.setPos( tree.pos );
  methodCall.type = operatorMethod.getReturnType();

  // If methodCall is an extension method, rewrite it
  Symbol.MethodSymbol extMethod = findExtMethod( methodCall );
  if( extMethod != null )
  {
    // Replace with extension method call
    methodCall = replaceExtCall( methodCall, extMethod );
  }

  // Concrete type set in attr
  methodCall.type = tree.type;
  return methodCall;
}
 
Example 5
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 6 votes vote down vote up
private JCExpression classForNameCall( Type type, JCTree tree )
{
  TreeMaker make = _tp.getTreeMaker();
  JavacElements javacElems = _tp.getElementUtil();

  JCTree.JCMethodInvocation typeCall = make.Apply( List.nil(),
    memberAccess( make, javacElems, ReflectUtil.class.getName() + ".type" ),
    List.of( make.Literal( makeLiteralName( type ) ) ) );
  typeCall.setPos( Position.NOPOS );
  typeCall.type = _tp.getSymtab().classType;
  JCTree.JCFieldAccess newMethodSelect = (JCTree.JCFieldAccess)typeCall.getMethodSelect();

  Symbol.ClassSymbol reflectMethodClassSym =
    IDynamicJdk.instance().getTypeElement( _tp.getContext(), _tp.getCompilationUnit(), ReflectUtil.class.getName() );
  Symbol.MethodSymbol typeMethodSymbol = resolveMethod( tree.pos(),
    Names.instance( _tp.getContext() ).fromString( "type" ),
    reflectMethodClassSym.type, List.of( _tp.getSymtab().stringType ) );
  newMethodSelect.sym = typeMethodSymbol;
  newMethodSelect.type = typeMethodSymbol.type;
  newMethodSelect.pos = tree.pos;
  assignTypes( newMethodSelect.selected, reflectMethodClassSym );

  return typeCall;
}
 
Example 6
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 5 votes vote down vote up
private boolean isConstructProxyCall( JCExpression expression )
{
  if( expression instanceof JCTree.JCMethodInvocation )
  {
    // don't erase cast if we generated it here e.g.., for structural call cast on constructProxy

    JCExpression meth = ((JCTree.JCMethodInvocation)expression).meth;
    return meth instanceof JCTree.JCFieldAccess && ((JCTree.JCFieldAccess)meth).getIdentifier().toString().equals( "constructProxy" );
  }
  return expression instanceof JCTypeCast && isConstructProxyCall( ((JCTypeCast)expression).getExpression() );
}
 
Example 7
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 5 votes vote down vote up
/**
 * Replace all extension method call-sites with static calls to extension methods
 */
@Override
public void visitApply( JCTree.JCMethodInvocation tree )
{
  super.visitApply( tree );

  eraseGenericStructuralVarargs( tree );

  if( _tp.isGenerate() &&
      // handle compiler-generated call to iterator(), sometimes a structural interface is involved here (lists in JSON)
      !isStructuralIteratorCall( tree ) )
  {
    // Don't process tree during GENERATE, unless the tree was generated e.g., a bridge method
    return;
  }

  Symbol.MethodSymbol method = findExtMethod( tree );
  if( method != null )
  {
    // Replace with extension method call
    result = replaceExtCall( tree, method );
  }
  else if( isStructuralMethod( tree ) )
  {
    // The structural interface method is implemented directly in the type or supertype hierarchy,
    // replace with proxy call
    result = replaceStructuralCall( tree );
  }
  else if( isJailbreakReceiver( tree ) )
  {
    result = replaceWithReflection( tree );
  }
  else
  {
    result = tree;
  }
}
 
Example 8
Source File: BootstrapInserter.java    From manifold with Apache License 2.0 5 votes vote down vote up
private JCTree.JCStatement buildBootstrapStaticBlock()
{
  TreeMaker make = _javacJacker.getTreeMaker();
  JavacElements javacElems = _javacJacker.getJavacElements();

  JCTree.JCMethodInvocation bootstrapInitCall = make.Apply( List.nil(), memberAccess( make, javacElems, IBootstrap.class.getName() + ".dasBoot" ), List.nil() );
  return make.Block( Modifier.STATIC, List.of( make.Exec( bootstrapInitCall ) ) );
}
 
Example 9
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 5 votes vote down vote up
private void eraseGenericStructuralVarargs( JCTree.JCMethodInvocation tree )
{
  if( tree.varargsElement instanceof Type.ClassType && TypeUtil.isStructuralInterface( _tp, tree.varargsElement.tsym ) )
  {
    tree.varargsElement = _tp.getSymtab().objectType;
  }
}
 
Example 10
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 5 votes vote down vote up
private JCTree replaceWithReflection( JCTree.JCAssign assignTree )
{
  JCTree.JCFieldAccess tree = (JCTree.JCFieldAccess)assignTree.lhs;

  TreeMaker make = _tp.getTreeMaker();
  JavacElements javacElems = _tp.getElementUtil();

  boolean isStatic = tree.sym.getModifiers().contains( javax.lang.model.element.Modifier.STATIC );
  if( tree.sym instanceof Symbol.MethodSymbol )
  {
    return assignTree;
  }

  Type type = tree.sym.type;
  Symbol.MethodSymbol reflectMethodSym = findFieldAccessReflectUtilMethod( tree, type, isStatic, true );

  ArrayList<JCExpression> newArgs = new ArrayList<>();
  newArgs.add( isStatic ? makeClassExpr( tree, tree.selected.type ) : tree.selected ); // receiver or class
  newArgs.add( make.Literal( tree.sym.flatName().toString() ) ); // field name
  newArgs.add( assignTree.rhs ); // field value

  Symbol.ClassSymbol reflectMethodClassSym =
    IDynamicJdk.instance().getTypeElement( _tp.getContext(), _tp.getCompilationUnit(), ReflectionRuntimeMethods.class.getName() );

  JCTree.JCMethodInvocation reflectCall =
    make.Apply( List.nil(),
      memberAccess( make, javacElems, ReflectionRuntimeMethods.class.getName() + "." + reflectMethodSym.flatName().toString() ),
      List.from( newArgs ) );
  reflectCall.setPos( tree.pos );
  reflectCall.type = type;
  JCTree.JCFieldAccess newMethodSelect = (JCTree.JCFieldAccess)reflectCall.getMethodSelect();
  newMethodSelect.sym = reflectMethodSym;
  newMethodSelect.type = reflectMethodSym.type;
  assignTypes( newMethodSelect.selected, reflectMethodClassSym );

  return reflectCall;
}
 
Example 11
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 4 votes vote down vote up
private JCTree.JCMethodInvocation replaceWithReflection( JCTree.JCMethodInvocation tree )
{
  //## todo: maybe try to avoid reflection if the method is accessible -- at least check if the method and its enclosing nest of classes are all public

  Type type = tree.getMethodSelect().type;
  if( type instanceof Type.ErrorType )
  {
    // No such field/method or wrong params
    return tree;
  }

  TreeMaker make = _tp.getTreeMaker();
  JavacElements javacElems = _tp.getElementUtil();

  JCExpression methodSelect = tree.getMethodSelect();
  if( methodSelect instanceof JCTree.JCFieldAccess )
  {
    JCTree.JCFieldAccess m = (JCTree.JCFieldAccess)methodSelect;
    boolean isStatic = m.sym.getModifiers().contains( javax.lang.model.element.Modifier.STATIC );
    if( !(m.sym instanceof Symbol.MethodSymbol) )
    {
      return tree;
    }
    Type returnType = ((Symbol.MethodSymbol)m.sym).getReturnType();
    Symbol.MethodSymbol reflectMethodSym = findReflectUtilMethod( tree, returnType, isStatic );

    List<Symbol.VarSymbol> parameters = ((Symbol.MethodSymbol)m.sym).getParameters();
    ArrayList<JCExpression> paramTypes = new ArrayList<>();
    for( Symbol.VarSymbol param: parameters )
    {
      JCExpression classExpr = makeClassExpr( tree, param.type );
      paramTypes.add( classExpr );
    }
    Symtab symTab = _tp.getSymtab();
    JCTree.JCNewArray paramTypesArray = make.NewArray(
      make.Type( symTab.classType ), List.nil(), List.from( paramTypes ) );
    paramTypesArray.type = new Type.ArrayType( symTab.classType, symTab.arrayClass );

    JCTree.JCNewArray argsArray = make.NewArray(
      make.Type( symTab.objectType ), List.nil(), tree.getArguments() );
    argsArray.type = new Type.ArrayType( symTab.objectType, symTab.arrayClass );

    ArrayList<JCExpression> newArgs = new ArrayList<>();
    newArgs.add( isStatic ? makeClassExpr( tree, m.selected.type ) : m.selected ); // receiver or class
    newArgs.add( make.Literal( m.sym.flatName().toString() ) ); // method name
    newArgs.add( paramTypesArray ); // param types
    newArgs.add( argsArray ); // args

    Symbol.ClassSymbol reflectMethodClassSym =
      IDynamicJdk.instance().getTypeElement( _tp.getContext(), _tp.getCompilationUnit(), ReflectionRuntimeMethods.class.getName() );

    JCTree.JCMethodInvocation reflectCall =
      make.Apply( List.nil(),
        memberAccess( make, javacElems, ReflectionRuntimeMethods.class.getName() + "." + reflectMethodSym.flatName().toString() ),
        List.from( newArgs ) );
    reflectCall.setPos( tree.pos );
    reflectCall.type = returnType;
    reflectCall.pos = tree.pos;
    JCTree.JCFieldAccess newMethodSelect = (JCTree.JCFieldAccess)reflectCall.getMethodSelect();
    newMethodSelect.sym = reflectMethodSym;
    newMethodSelect.type = reflectMethodSym.type;
    assignTypes( newMethodSelect.selected, reflectMethodClassSym );
    newMethodSelect.pos = tree.pos;
    return reflectCall;
  }
  return tree;
}
 
Example 12
Source File: ManAttr_8.java    From manifold with Apache License 2.0 4 votes vote down vote up
/**
 * Handles @Jailbreak
 */
@Override
public void visitApply( JCTree.JCMethodInvocation tree )
{
  if( !(tree.meth instanceof JCTree.JCFieldAccess) )
  {
    super.visitApply( tree );
    patchMethodType( tree );
    return;
  }

  if( JAILBREAK_PRIVATE_FROM_SUPERS )
  {
    _manLog.pushSuspendIssues( tree ); // since method-calls can be nested, we need a tree of stacks TreeNode(JCTree.JCFieldAccess, Stack<JCDiagnostic>>)
  }

  JCTree.JCFieldAccess fieldAccess = (JCTree.JCFieldAccess)tree.meth;
  try
  {
    super.visitApply( tree );
    patchMethodType( tree );

    if( JAILBREAK_PRIVATE_FROM_SUPERS )
    {
      if( fieldAccess.type instanceof Type.ErrorType )
      {
        if( shouldCheckSuperType( fieldAccess.selected.type ) && _manLog.isJailbreakSelect( fieldAccess ) )
        {
          // set qualifier type to supertype to handle private methods
          Type.ClassType oldType = (Type.ClassType)fieldAccess.selected.type;
          fieldAccess.selected.type = ((Symbol.ClassSymbol)oldType.tsym).getSuperclass();
          ((JCTree.JCIdent)fieldAccess.selected).sym.type = fieldAccess.selected.type;
          fieldAccess.type = null;
          fieldAccess.sym = null;
          tree.type = null;

          // retry with supertype
          visitApply( tree );

          // restore original type
          fieldAccess.selected.type = oldType;
          ((JCTree.JCIdent)fieldAccess.selected).sym.type = fieldAccess.selected.type;
        }
      }
      else
      {
        // apply any issues logged for the found method (only the top of the suspend stack)
        _manLog.recordRecentSuspendedIssuesAndRemoveOthers( tree );
      }
    }
  }
  finally
  {
    if( JAILBREAK_PRIVATE_FROM_SUPERS )
    {
      _manLog.popSuspendIssues( tree );
    }
  }
}
 
Example 13
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 4 votes vote down vote up
private Symbol.MethodSymbol findExtMethod( JCTree.JCMethodInvocation tree )
{
  Symbol sym = null;
  if( tree.meth instanceof JCTree.JCFieldAccess )
  {
    sym = ((JCTree.JCFieldAccess)tree.meth).sym;
  }
  else if( tree.meth instanceof JCTree.JCIdent )
  {
    sym = ((JCTree.JCIdent)tree.meth).sym;
  }

  if( sym == null || !sym.hasAnnotations() )
  {
    return null;
  }

  for( Attribute.Compound annotation: sym.getAnnotationMirrors() )
  {
    if( annotation.type.toString().equals( ExtensionMethod.class.getName() ) )
    {
      String extensionClass = (String)annotation.values.get( 0 ).snd.getValue();
      boolean isStatic = (boolean)annotation.values.get( 1 ).snd.getValue();
      BasicJavacTask javacTask = (BasicJavacTask)_tp.getJavacTask(); //JavacHook.instance() != null ? (JavacTaskImpl)JavacHook.instance().getJavacTask_PlainFileMgr() : ClassSymbols.instance( _sp.getModule() ).getJavacTask_PlainFileMgr();
      Pair<Symbol.ClassSymbol, JCTree.JCCompilationUnit> classSymbol = ClassSymbols.instance( _sp.getModule() ).getClassSymbol( javacTask, _tp, extensionClass );
      if( classSymbol == null )
      {
        // In module mode if a package in another module is not exported, classes in the package
        // will not be accessible to other modules, hence the null classSymbol
        continue;
      }

      Symbol.ClassSymbol extClassSym = classSymbol.getFirst();
      if( extClassSym == null )
      {
        // This can happen during bootstrapping with Dark Java classes from Manifold itself
        // So we short-circuit that here (ManClassFinder_9 or any other darkj class used during bootstrapping doesn't really need to use extensions)
        return null;
      }
      Types types = Types.instance( javacTask.getContext() );
      outer:
      for( Symbol elem: IDynamicJdk.instance().getMembers( extClassSym ) )
      {
        if( elem instanceof Symbol.MethodSymbol && elem.flatName().toString().equals( sym.name.toString() ) )
        {
          Symbol.MethodSymbol extMethodSym = (Symbol.MethodSymbol)elem;
          List<Symbol.VarSymbol> extParams = extMethodSym.getParameters();
          List<Symbol.VarSymbol> calledParams = ((Symbol.MethodSymbol)sym).getParameters();
          int thisOffset = isStatic ? 0 : 1;
          if( extParams.size() - thisOffset != calledParams.size() )
          {
            continue;
          }
          for( int i = thisOffset; i < extParams.size(); i++ )
          {
            Symbol.VarSymbol extParam = extParams.get( i );
            Symbol.VarSymbol calledParam = calledParams.get( i - thisOffset );
            if( !types.isSameType( types.erasure( extParam.type ), types.erasure( calledParam.type ) ) )
            {
              continue outer;
            }
          }
          return extMethodSym;
        }
      }
    }
  }
  return null;
}
 
Example 14
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 4 votes vote down vote up
private JCTree replaceWithReflection( JCTree.JCNewClass tree )
{
  if( tree.constructor == null )
  {
    return tree;
  }

  TreeMaker make = _tp.getTreeMaker();
  JavacElements javacElems = _tp.getElementUtil();

  Type type = ((JCTree.JCAnnotatedType)tree.clazz).underlyingType.type;

  if( tree.constructor instanceof Symbol.ClassSymbol )
  {
    //assert tree.constructor.kind == com.sun.tools.javac.code.Kinds.ERR;
    return tree;
  }

  List<Symbol.VarSymbol> parameters = ((Symbol.MethodSymbol)tree.constructor).getParameters();
  ArrayList<JCExpression> paramTypes = new ArrayList<>();
  for( Symbol.VarSymbol param: parameters )
  {
    paramTypes.add( makeClassExpr( tree, param.type ) );
  }
  Symtab symTab = _tp.getSymtab();
  JCTree.JCNewArray paramTypesArray = make.NewArray(
    make.Type( symTab.classType ), List.nil(), List.from( paramTypes ) );
  paramTypesArray.type = new Type.ArrayType( symTab.classType, symTab.arrayClass );

  JCTree.JCNewArray argsArray = make.NewArray(
    make.Type( symTab.objectType ), List.nil(), tree.getArguments() );
  argsArray.type = new Type.ArrayType( symTab.objectType, symTab.arrayClass );

  ArrayList<JCExpression> newArgs = new ArrayList<>();
  newArgs.add( makeClassExpr( tree, type ) ); // the class
  newArgs.add( paramTypesArray ); // param types
  newArgs.add( argsArray ); // args


  Symbol.ClassSymbol reflectMethodClassSym =
    IDynamicJdk.instance().getTypeElement( _tp.getContext(), _tp.getCompilationUnit(), ReflectionRuntimeMethods.class.getName() );

  Symbol.MethodSymbol reflectMethodSym = findReflectUtilConstructor( tree );
  JCTree.JCMethodInvocation reflectCall =
    make.Apply( List.nil(),
      memberAccess( make, javacElems, ReflectionRuntimeMethods.class.getName() + "." + reflectMethodSym.flatName().toString() ),
      List.from( newArgs ) );
  reflectCall.setPos( tree.pos );
  reflectCall.type = type;
  JCTree.JCFieldAccess newMethodSelect = (JCTree.JCFieldAccess)reflectCall.getMethodSelect();
  newMethodSelect.sym = reflectMethodSym;
  newMethodSelect.type = reflectMethodSym.type;
  assignTypes( newMethodSelect.selected, reflectMethodClassSym );

  return reflectCall;
}
 
Example 15
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 4 votes vote down vote up
private JCTree replaceWithReflection( JCTree.JCFieldAccess tree )
{
  TreeMaker make = _tp.getTreeMaker();
  JavacElements javacElems = _tp.getElementUtil();

  boolean isStatic = tree.sym.getModifiers().contains( javax.lang.model.element.Modifier.STATIC );
  if( tree.sym instanceof Symbol.MethodSymbol )
  {
    return tree;
  }

  Tree parent = _tp.getParent( tree );
  if( parent instanceof JCTree.JCAssign && ((JCTree.JCAssign)parent).lhs == tree ||
      parent instanceof JCTree.JCAssignOp && ((JCTree.JCAssignOp)parent).lhs == tree )
  {
    // handled in visitAssign() or visitAssignOp()
    return tree;
  }

  if( parent instanceof JCTree.JCUnary && ((JCTree.JCUnary)parent).arg == tree )
  {
    Tree.Kind kind = parent.getKind();

    if( kind != Tree.Kind.UNARY_MINUS && kind != Tree.Kind.UNARY_PLUS &&
        kind != Tree.Kind.LOGICAL_COMPLEMENT && kind != Tree.Kind.BITWISE_COMPLEMENT )
    {
      // supporting -, +, !, ~  not supporting --, ++
      _tp.report( (JCTree)parent, Diagnostic.Kind.ERROR, ExtIssueMsg.MSG_INCREMENT_OP_NOT_ALLOWED_REFLECTION.get() );
      return tree;
    }
  }

  Type type = tree.sym.type;
  if( type instanceof Type.ErrorType )
  {
    // No such field/method
    return tree;
  }

  Symbol.MethodSymbol reflectMethodSym = findFieldAccessReflectUtilMethod( tree, type, isStatic, false );

  ArrayList<JCExpression> newArgs = new ArrayList<>();
  newArgs.add( isStatic ? makeClassExpr( tree, tree.selected.type ) : tree.selected ); // receiver or class
  newArgs.add( make.Literal( tree.sym.flatName().toString() ) ); // field name

  Symbol.ClassSymbol reflectMethodClassSym =
    IDynamicJdk.instance().getTypeElement( _tp.getContext(), _tp.getCompilationUnit(), ReflectionRuntimeMethods.class.getName() );

  JCTree.JCMethodInvocation reflectCall =
    make.Apply( List.nil(),
      memberAccess( make, javacElems, ReflectionRuntimeMethods.class.getName() + "." + reflectMethodSym.flatName().toString() ),
      List.from( newArgs ) );
  reflectCall.setPos( tree.pos );
  reflectCall.type = type;
  JCTree.JCFieldAccess newMethodSelect = (JCTree.JCFieldAccess)reflectCall.getMethodSelect();
  newMethodSelect.sym = reflectMethodSym;
  newMethodSelect.type = reflectMethodSym.type;
  assignTypes( newMethodSelect.selected, reflectMethodClassSym );

  return reflectCall;
}
 
Example 16
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 4 votes vote down vote up
private JCTree replaceStructuralCall( JCTree.JCMethodInvocation theCall )
{
  JCExpression methodSelect = theCall.getMethodSelect();
  if( methodSelect instanceof JCTree.JCFieldAccess )
  {
    int pos = theCall.pos;

    Symtab symbols = _tp.getSymtab();
    Names names = Names.instance( _tp.getContext() );
    Symbol.ClassSymbol reflectMethodClassSym = IDynamicJdk.instance().getTypeElement( _tp.getContext(), _tp.getCompilationUnit(), RuntimeMethods.class.getName() );
    Symbol.MethodSymbol makeInterfaceProxyMethod = resolveMethod( theCall.pos(), names.fromString( "constructProxy" ), reflectMethodClassSym.type,
      List.from( new Type[]{symbols.objectType, symbols.classType} ) );

    JCTree.JCFieldAccess m = (JCTree.JCFieldAccess)methodSelect;
    TreeMaker make = _tp.getTreeMaker();
    JavacElements javacElems = _tp.getElementUtil();
    JCExpression thisArg = m.selected;

    ArrayList<JCExpression> newArgs = new ArrayList<>();
    newArgs.add( thisArg );
    JCTree.JCFieldAccess ifaceClassExpr = (JCTree.JCFieldAccess)memberAccess( make, javacElems, thisArg.type.tsym.getQualifiedName().toString() + ".class" );
    ifaceClassExpr.type = symbols.classType;
    ifaceClassExpr.sym = symbols.classType.tsym;
    ifaceClassExpr.pos = pos;
    assignTypes( ifaceClassExpr.selected, thisArg.type.tsym );
    ifaceClassExpr.selected.pos = pos;
    newArgs.add( ifaceClassExpr );

    JCTree.JCMethodInvocation makeProxyCall = make.Apply( List.nil(), memberAccess( make, javacElems, RuntimeMethods.class.getName() + ".constructProxy" ), List.from( newArgs ) );
    makeProxyCall.setPos( pos );
    makeProxyCall.type = thisArg.type;
    JCTree.JCFieldAccess newMethodSelect = (JCTree.JCFieldAccess)makeProxyCall.getMethodSelect();
    newMethodSelect.sym = makeInterfaceProxyMethod;
    newMethodSelect.type = makeInterfaceProxyMethod.type;
    newMethodSelect.pos = pos;
    assignTypes( newMethodSelect.selected, reflectMethodClassSym );
    newMethodSelect.selected.pos = pos;

    JCTypeCast cast = make.TypeCast( thisArg.type, makeProxyCall );
    cast.type = thisArg.type;
    cast.pos = pos;

    ((JCTree.JCFieldAccess)theCall.meth).selected = cast;

    theCall.pos = pos;

    return theCall;
  }
  return null;
}
 
Example 17
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 4 votes vote down vote up
private boolean isStructuralIteratorCall( JCTree.JCMethodInvocation tree )
{
  return tree.meth instanceof JCTree.JCFieldAccess &&
         ((JCTree.JCFieldAccess)tree.meth).sym.name.toString().equals( "iterator" ) &&
         isStructuralMethod( tree );
}
 
Example 18
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 4 votes vote down vote up
@Override
public void visitUnary( JCTree.JCUnary tree )
{
  super.visitUnary( tree );

  if( _tp.isGenerate() && !shouldProcessForGeneration() )
  {
    // Don't process tree during GENERATE, unless the tree was generated e.g., a bridge method
    return;
  }

  Symbol op = IDynamicJdk.instance().getOperator( tree );
  if( op instanceof OverloadOperatorSymbol ) // handle negation overload
  {
    TreeMaker make = _tp.getTreeMaker();

    // Handle operator overload expressions

    Symbol.MethodSymbol operatorMethod = (Symbol.MethodSymbol)op;
    while( operatorMethod instanceof OverloadOperatorSymbol )
    {
      operatorMethod = ((OverloadOperatorSymbol)operatorMethod).getMethod();
    }

    if( operatorMethod != null )
    {
      JCTree.JCMethodInvocation methodCall;
      JCExpression receiver = tree.getExpression();
      methodCall = make.Apply( List.nil(), make.Select( receiver, operatorMethod ), List.nil() );
      methodCall.setPos( tree.pos );
      methodCall.type = operatorMethod.getReturnType();

      // If methodCall is an extension method, rewrite it accordingly
      Symbol.MethodSymbol extMethod = findExtMethod( methodCall );
      if( extMethod != null )
      {
        // Replace with extension method call
        methodCall = replaceExtCall( methodCall, extMethod );
      }

      result = methodCall;
    }
  }
  else if( isJailbreakReceiver( tree ) )
  {
    Tree.Kind kind = tree.getKind();
    if( kind == Tree.Kind.POSTFIX_INCREMENT || kind == Tree.Kind.POSTFIX_DECREMENT ||
        kind == Tree.Kind.PREFIX_INCREMENT || kind == Tree.Kind.PREFIX_DECREMENT )
    {
      // ++, -- operators not supported with jailbreak access to fields, only direct assignment
      _tp.report( tree, Diagnostic.Kind.ERROR, ExtIssueMsg.MSG_INCREMENT_OP_NOT_ALLOWED_REFLECTION.get() );
      Types types = Types.instance( ((BasicJavacTask)_tp.getJavacTask()).getContext() );
      tree.type = types.createErrorType( tree.type );
    }
    result = tree;
  }
  else
  {
    result = tree;
  }
}