001 /* 002 * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered 003 * by the modified BSD License. You should have received a copy of the 004 * modified BSD license with this compiler. 005 * 006 * Copyright (c) 2005-2008, Torbjorn Ekman 007 * All rights reserved. 008 */ 009 010 aspect VariableArityParametersCodegen { 011 /* Invocations of a variable arity method may contain more actual argument 012 expressions than formal parameters. All the actual argument expressions that do 013 not correspond to the formal parameters preceding the variable arity parameter 014 will be evaluated and the results stored into an array that will be passed to 015 the method invocation (�15.12.4.2)*/ 016 refine Transformations public void MethodAccess.transformation() { 017 if(decl().isVariableArity() && !invokesVariableArityAsArray()) { 018 // arguments to normal parameters 019 List list = new List(); 020 for(int i = 0; i < decl().getNumParameter() - 1; i++) 021 list.add(getArg(i).fullCopy()); 022 // arguments to variable arity parameters 023 List last = new List(); 024 for(int i = decl().getNumParameter() - 1; i < getNumArg(); i++) 025 last.add(getArg(i).fullCopy()); 026 // build an array holding arguments 027 Access typeAccess = decl().lastParameter().type().elementType().createQualifiedAccess(); 028 for(int i = 0; i < decl().lastParameter().type().dimension(); i++) 029 typeAccess = new ArrayTypeAccess(typeAccess); 030 list.add(new ArrayCreationExpr(typeAccess, new Opt(new ArrayInit(last)))); 031 // replace argument list with augemented argument list 032 setArgList(list); 033 } 034 refined(); 035 } 036 037 refine Transformations public void ClassInstanceExpr.transformation() { 038 if(decl().isVariableArity() && !invokesVariableArityAsArray()) { 039 // arguments to normal parameters 040 List list = new List(); 041 for(int i = 0; i < decl().getNumParameter() - 1; i++) 042 list.add(getArg(i).fullCopy()); 043 // arguments to variable arity parameters 044 List last = new List(); 045 for(int i = decl().getNumParameter() - 1; i < getNumArg(); i++) 046 last.add(getArg(i).fullCopy()); 047 // build an array holding arguments 048 Access typeAccess = decl().lastParameter().type().elementType().createQualifiedAccess(); 049 for(int i = 0; i < decl().lastParameter().type().dimension(); i++) 050 typeAccess = new ArrayTypeAccess(typeAccess); 051 list.add(new ArrayCreationExpr(typeAccess, new Opt(new ArrayInit(last)))); 052 // replace argument list with augemented argument list 053 setArgList(list); 054 } 055 refined(); 056 } 057 058 refine Transformations public void ConstructorAccess.transformation() { 059 if(decl().isVariableArity() && !invokesVariableArityAsArray()) { 060 // arguments to normal parameters 061 List list = new List(); 062 for(int i = 0; i < decl().getNumParameter() - 1; i++) 063 list.add(getArg(i).fullCopy()); 064 // arguments to variable arity parameters 065 List last = new List(); 066 for(int i = decl().getNumParameter() - 1; i < getNumArg(); i++) 067 last.add(getArg(i).fullCopy()); 068 // build an array holding arguments 069 Access typeAccess = decl().lastParameter().type().elementType().createQualifiedAccess(); 070 for(int i = 0; i < decl().lastParameter().type().dimension(); i++) 071 typeAccess = new ArrayTypeAccess(typeAccess); 072 list.add(new ArrayCreationExpr(typeAccess, new Opt(new ArrayInit(last)))); 073 // replace argument list with augemented argument list 074 setArgList(list); 075 } 076 refined(); 077 } 078 079 public static final int Modifiers.ACC_VARARGS = 0x0080; 080 081 /** 082 * Add the ACC_VARARGS flag for variable arity methods. 083 */ 084 refine Flags eq MethodDecl.flags() { 085 int res = refined(); 086 if(isVariableArity()) 087 res |= Modifiers.ACC_VARARGS; 088 return res; 089 } 090 091 /** 092 * Add the ACC_VARARGS flag for variable arity constructors. 093 */ 094 refine Flags eq ConstructorDecl.flags() { 095 int res = refined(); 096 if(isVariableArity()) 097 res |= Modifiers.ACC_VARARGS; 098 return res; 099 } 100 }