/* * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered * by the modified BSD License. You should have received a copy of the * modified BSD license with this compiler. * * Copyright (c) 2005-2008, Torbjorn Ekman * All rights reserved. */ aspect VariableArityParametersCodegen { /* Invocations of a variable arity method may contain more actual argument expressions than formal parameters. All the actual argument expressions that do not correspond to the formal parameters preceding the variable arity parameter will be evaluated and the results stored into an array that will be passed to the method invocation (15.12.4.2)*/ refine Transformations public void MethodAccess.transformation() { if(decl().isVariableArity() && !invokesVariableArityAsArray()) { // arguments to normal parameters List list = new List(); for(int i = 0; i < decl().getNumParameter() - 1; i++) list.add(getArg(i).fullCopy()); // arguments to variable arity parameters List last = new List(); for(int i = decl().getNumParameter() - 1; i < getNumArg(); i++) last.add(getArg(i).fullCopy()); // build an array holding arguments Access typeAccess = decl().lastParameter().type().elementType().createQualifiedAccess(); for(int i = 0; i < decl().lastParameter().type().dimension(); i++) typeAccess = new ArrayTypeAccess(typeAccess); list.add(new ArrayCreationExpr(typeAccess, new Opt(new ArrayInit(last)))); // replace argument list with augemented argument list setArgList(list); } refined(); } refine Transformations public void ClassInstanceExpr.transformation() { if(decl().isVariableArity() && !invokesVariableArityAsArray()) { // arguments to normal parameters List list = new List(); for(int i = 0; i < decl().getNumParameter() - 1; i++) list.add(getArg(i).fullCopy()); // arguments to variable arity parameters List last = new List(); for(int i = decl().getNumParameter() - 1; i < getNumArg(); i++) last.add(getArg(i).fullCopy()); // build an array holding arguments Access typeAccess = decl().lastParameter().type().elementType().createQualifiedAccess(); for(int i = 0; i < decl().lastParameter().type().dimension(); i++) typeAccess = new ArrayTypeAccess(typeAccess); list.add(new ArrayCreationExpr(typeAccess, new Opt(new ArrayInit(last)))); // replace argument list with augemented argument list setArgList(list); } refined(); } refine Transformations public void ConstructorAccess.transformation() { if(decl().isVariableArity() && !invokesVariableArityAsArray()) { // arguments to normal parameters List list = new List(); for(int i = 0; i < decl().getNumParameter() - 1; i++) list.add(getArg(i).fullCopy()); // arguments to variable arity parameters List last = new List(); for(int i = decl().getNumParameter() - 1; i < getNumArg(); i++) last.add(getArg(i).fullCopy()); // build an array holding arguments Access typeAccess = decl().lastParameter().type().elementType().createQualifiedAccess(); for(int i = 0; i < decl().lastParameter().type().dimension(); i++) typeAccess = new ArrayTypeAccess(typeAccess); list.add(new ArrayCreationExpr(typeAccess, new Opt(new ArrayInit(last)))); // replace argument list with augemented argument list setArgList(list); } refined(); } public static final int Modifiers.ACC_VARARGS = 0x0080; refine EmitJimple eq MethodDecl.sootTypeModifiers() { int res = refined(); if(isVariableArity()) res |= Modifiers.ACC_VARARGS; return res; } }