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 LambdaBody {
029      syn lazy boolean LambdaBody.isBlockBody();
030      syn lazy boolean LambdaBody.isExprBody();
031    
032      eq BlockLambdaBody.isBlockBody() = true;
033      eq BlockLambdaBody.isExprBody() = false;
034    
035      eq ExprLambdaBody.isBlockBody() = false;
036      eq ExprLambdaBody.isExprBody() = true;
037    }
038    
039    aspect ReturnCompatible {
040      syn lazy boolean BlockLambdaBody.voidCompatible();
041      syn lazy boolean BlockLambdaBody.valueCompatible();
042    
043      //15.27.2
044      eq BlockLambdaBody.voidCompatible() = noReturnsHasResult();
045      eq BlockLambdaBody.valueCompatible() = allReturnsHasResult() && !getBlock().canCompleteNormally();
046    
047      coll ArrayList<ReturnStmt> BlockLambdaBody.lambdaReturns()
048          [new ArrayList<ReturnStmt>()]
049          with add
050          root Program;
051    
052      ReturnStmt contributes this
053          when (enclosingLambda() != null) && (enclosingLambda().hostType() == hostType())
054          to BlockLambdaBody.lambdaReturns()
055          for (BlockLambdaBody)enclosingLambda().getLambdaBody();
056    
057      public boolean BlockLambdaBody.noReturnsHasResult() {
058        ArrayList<ReturnStmt> returnList = lambdaReturns();
059        for (int i = 0; i < returnList.size(); i++) {
060          if (returnList.get(i).hasResult()) {
061            return false;
062          }
063        }
064        return true;
065      }
066    
067      public boolean BlockLambdaBody.allReturnsHasResult() {
068        ArrayList<ReturnStmt> returnList = lambdaReturns();
069        for (int i = 0; i < returnList.size(); i++) {
070          if (!returnList.get(i).hasResult()) {
071            return false;
072          }
073        }
074        return true;
075      }
076    }