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    
029    aspect VariableScope {
030      inh lazy SimpleSet LambdaBody.lookupVariable(String name);
031      inh lazy SimpleSet InferredParameterDeclaration.lookupVariable(String name);
032    
033      eq DeclaredLambdaParameters.getParameter().lookupVariable(String name) =
034          parameterDeclaration(name);
035      eq InferredLambdaParameters.getParameter().lookupVariable(String name) =
036          parameterDeclaration(name);
037    
038      syn lazy SimpleSet DeclaredLambdaParameters.parameterDeclaration(String name) {
039        for (int i = 0; i < getNumParameter(); i++) {
040          if (getParameter(i).name().equals(name)) {
041            return (ParameterDeclaration) getParameter(i);
042          }
043        }
044        return SimpleSet.emptySet;
045      }
046    
047      syn lazy SimpleSet InferredLambdaParameters.parameterDeclaration(String name) {
048        for (int i = 0; i < getNumParameter(); i++) {
049          if (getParameter(i).name().equals(name)) {
050            return (InferredParameterDeclaration) getParameter(i);
051          }
052        }
053        return SimpleSet.emptySet;
054      }
055    
056      eq LambdaExpr.getLambdaBody().lookupVariable(String name) {
057        if (getLambdaParameters() instanceof DeclaredLambdaParameters) {
058          SimpleSet decls = ((DeclaredLambdaParameters) getLambdaParameters())
059              .parameterDeclaration(name);
060          if (!decls.isEmpty()) {
061            return decls;
062          }
063        } else if (getLambdaParameters() instanceof InferredLambdaParameters) {
064          SimpleSet decls = ((InferredLambdaParameters)getLambdaParameters())
065              .parameterDeclaration(name);
066          if (!decls.isEmpty()) {
067            return decls;
068          }
069        }
070        return lookupVariable(name);
071      }
072    }
073    
074    aspect VariableScopePropagation {
075      LambdaExpr implements VariableScope;
076    }