001 /* Copyright (c) 2014, Erik Hogeman <Erik.Hogemn@gmail.com> 002 * All rights reserved. 003 * 004 * Redistribution and use in source and binary forms, with or without 005 * modification, are permitted provided that the following conditions are met: 006 * 007 * * Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * * Redistributions in binary form must reproduce the above copyright 010 * notice, this list of conditions and the following disclaimer in the 011 * documentation and/or other materials provided with the distribution. 012 * * Neither the name of the Lund University nor the names of its 013 * contributors may be used to endorse or promote products derived from 014 * this software without specific prior written permission. 015 * 016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 017 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 018 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 019 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 020 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 021 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 022 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 023 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 024 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 025 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 026 * POSSIBILITY OF SUCH DAMAGE. 027 */ 028 aspect Transformations { 029 public void LambdaExpr.transformation() { 030 toClass().transformation(); 031 } 032 033 public void ExprMethodReference.transformation() { 034 toClass().transformation(); 035 } 036 037 public void TypeMethodReference.transformation() { 038 toClass().transformation(); 039 } 040 041 public void ConstructorReference.transformation() { 042 toClass().transformation(); 043 } 044 045 // TEMPORARY REFINE TO PREVENT SUPERACCESSORS FROM BEING CREATED WHEN INTERFACE IS THE QUALIFIER 046 refine VariableArityParametersCodegen 047 public void MethodAccess.transformation() { 048 if (decl().isVariableArity() && !invokesVariableArityAsArray()) { 049 // arguments to normal parameters 050 List list = new List(); 051 for (int i = 0; i < decl().getNumParameter() - 1; i++) 052 list.add(getArg(i).treeCopyNoTransform()); 053 // arguments to variable arity parameters 054 List last = new List(); 055 for (int i = decl().getNumParameter() - 1; i < getNumArg(); i++) 056 last.add(getArg(i).treeCopyNoTransform()); 057 // build an array holding arguments 058 Access typeAccess = decl().lastParameter().type().elementType().createQualifiedAccess(); 059 for (int i = 0; i < decl().lastParameter().type().dimension(); i++) 060 typeAccess = new ArrayTypeAccess(typeAccess); 061 list.add(new ArrayCreationExpr(typeAccess, new Opt(new ArrayInit(last)))); 062 // replace argument list with augemented argument list 063 setArgList(list); 064 } 065 MethodDecl m = decl(); 066 067 068 /*if (!isQualified() && !m.isStatic()) { 069 TypeDecl typeDecl = hostType(); 070 while (typeDecl != null && !typeDecl.hasMethod(name())) { 071 typeDecl = typeDecl.enclosingType(); 072 } 073 ASTNode result = this.replaceWith(typeDecl.createQualifiedAccess().qualifiesAccess(new ThisAccess("this")).qualifiesAccess(new MethodAccess(name(), getArgList()))); 074 result.transformation(); 075 return; 076 }*/ 077 078 if (requiresAccessor()) { 079 /* Access to private methods in enclosing types: 080 The original MethodAccess is replaced with an access to an accessor method 081 built by createAccessor(). This method is built lazily and differs from 082 normal MethodDeclarations in the following ways: 083 1) The method in the class file should always be static and the signature 084 is thus changed to include a possible this reference as the first argument. 085 2) The method is always invoked using INVOKESTATIC 086 3) The flags must indicate that the method is static and package private 087 */ 088 super.transformation(); 089 this.replaceWith(decl().createAccessor(methodQualifierType()).createBoundAccess(getArgList())); 090 return; 091 } else if (!m.isStatic() && isQualified() 092 && prevExpr().isSuperAccess() 093 && !hostType().instanceOf(prevExpr().type()) 094 && !prevExpr().type().isInterfaceDecl()) { 095 decl().createSuperAccessor(superAccessorTarget()); 096 } 097 super.transformation(); 098 } 099 }