Changeset 4300 for trunk/ProjectFortress

Show
Ignore:
Timestamp:
10/31/09 15:34:55 (3 weeks ago)
Author:
jmaessen
Message:

[codegen, typechecking] Single inheritance of methods. Uses java
inheritance from boilerplate classes. Multiple inheritance is coming,
but will require wrappers for methods inherited from traits other than
the leftmost (enumerating exactly these methods could prove a bit
fiddly).

Fixed typechecker so that method applications that use an implicit
receiver (_RewriteFnApp nodes) are transformed into dotted method
applications (MethodInvocation nodes). This is done after type
checking in order to avoid some unusual corner cases in the type of
self in object expressions. As these expressions must be hoisted
before code generation, this is the least of our troubles on that
front.

Did some minor tweaks to conversions between java and Scala types to
use idioms for List conversion recommended by the Scala community;
this seems to speed compilation up noticeably during testing. Some
more care may be warranted here; more careful code generation
for FortressAst.scala in astgen may produce big payoffs in run time.

Location:
trunk/ProjectFortress
Files:
1 added
2 removed
14 modified
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/ProjectFortress/compiler_tests/SingleInheritance.fss

    r4254 r4300  
    2424  n():String = "O(" x.asString "," y.asString ").n " self.m("a","b") 
    2525  p():String = "O(" x.asString "," y.asString ").p " m("e","f") 
     26  q():String = n() 
    2627end 
    2728 
    2829run() = do 
    2930  o = O(1,2) 
     31  println(o.m("c","d")) 
    3032  println(o.n()) 
    3133  println(o.p()) 
    32   println(o.m("c","d")) 
     34  println(o.q()) 
    3335end 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/CompilerJUTest.scala

    r3561 r4300  
    1717package com.sun.fortress.compiler 
    1818 
    19 import _root_.java.util.Arrays 
    20 import _root_.java.util.LinkedList 
    2119import junit.framework.TestCase 
    2220import junit.framework.TestSuite 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/NamingCzar.java

    r4262 r4300  
    895895            } 
    896896            public String forVarType (VarType t) { 
    897                 //  
     897                // 
    898898                String s = t.getName().getText(); 
    899899                s = internalToDesc(s); 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/codegen/CodeGen.java

    r4291 r4300  
    177177            } 
    178178        } 
    179          
     179 
    180180        this.topLevelOverloads = 
    181181            sizePartitionedOverloads(ci.functions()); 
     
    184184        this.lexEnv = new BATree<String,VarCodeGen>(StringHashComparer.V); 
    185185        this.env = env; 
    186          
    187          
     186 
     187 
    188188        debug( "Compile: Compiling ", packageAndClassName ); 
    189189    } 
     
    338338 
    339339    private VarCodeGen getLocalVarOrNull( IdOrOp nm ) { 
    340         debug("getLocalVar: " + nm); 
     340        debug("getLocalVar: ", nm); 
    341341        VarCodeGen r = lexEnv.get(idOrOpToString(nm)); 
    342342        if (r != null) 
    343             debug("getLocalVar:" + nm + " VarCodeGen = " + r + " of class " + r.getClass()); 
     343            debug("getLocalVar:", nm, " VarCodeGen = ", r, " of class ", r.getClass()); 
    344344        else 
    345             debug("getLocalVar:" + nm + " VarCodeGen = null"); 
     345            debug("getLocalVar:", nm, " VarCodeGen = null"); 
    346346        return r; 
    347347    } 
     
    352352 
    353353        String file = Naming.mangleFortressIdentifier(unmangled_file_name); 
    354          
     354 
    355355        if (ProjectProperties.getBoolean("fortress.bytecode.verify", false)) 
    356356            CheckClassAdapter.verify(new ClassReader(cw.toByteArray()), true, pw); 
     
    609609        /* Need wrappers for the API, too. */ 
    610610        generateUnambiguousWrappersForApi(); 
    611          
     611 
    612612        // Must process top-level values next to make sure fields end up in scope. 
    613613        for (Decl d : x.getDecls()) { 
     
    708708        FnDecl y = x; 
    709709        x = (FnDecl) x.accept(new GenericNumberer(xlation)); 
    710          
     710 
    711711        // Get rewritten parts. 
    712712        FnHeader header = x.getHeader(); 
     
    714714        Type returnType = header.getReturnType().unwrap(); 
    715715        Expr body = x.getBody().unwrap(); 
    716   
     716 
    717717        String sig = 
    718718            NamingCzar.jvmSignatureFor(NodeUtil.getParamType(x), 
     
    781781        // methods. 
    782782        String mname; 
     783        int n = params.size(); 
    783784        if (selfIndex != NO_SELF) { 
    784785            sig = Naming.removeNthSigParameter(sig, selfIndex+1); 
     
    786787        } else { 
    787788            mname = nonCollidingSingleName(name, sig); 
     789            n++; 
    788790        } 
    789791 
     
    796798         * for our primitive type story. 
    797799         */ 
    798  
    799800 
    800801        // Dotted method; downcast self and 
     
    803804        InstantiatingClassloader.forwardingMethod(cw, mname, ACC_PUBLIC, 0, 
    804805                                                  springBoardClass, mname, INVOKESTATIC, 
    805                                                   sig, params.size(), true); 
     806                                                  sig, n, true); 
    806807    } 
    807808 
     
    851852        cg.generateActualMethodCode(modifiers, mname, sig, params, selfIndex, 
    852853                                    inAMethod, body); 
    853          
     854 
    854855        generateAllWrappersForFn(x, params, sig, modifiers, mname); 
    855856    } 
     
    868869            String mname) { 
    869870        CodeGen cg = new CodeGen(this); 
    870         /* This code generates forwarding wrappers for  
     871        /* This code generates forwarding wrappers for 
    871872         * the (local) unambiguous name of the function. 
    872873         */ 
    873                  
     874 
    874875        // unambiguous within component 
    875876        String wname = idOrOpToString(x.getUnambiguousName()); 
     
    898899                        function.getReturnType().unwrap(), 
    899900                        component.getName()); 
    900                  
     901 
    901902                String mname = idOrOpToString(function.name()); // entry.getKey(); 
    902903 
     
    919920        if (0 == (Opcodes.ACC_STATIC & modifiers)) 
    920921            return; 
    921          
     922 
    922923        mv = cw.visitCGMethod(modifiers, wname, sig, null, null); 
    923924        mv.visitCode(); 
     
    928929 
    929930        int i = 0; 
    930          
     931 
    931932        for (Param p : params) { 
    932933            // Type ty = p.getIdType().unwrap(); 
     
    936937 
    937938        mv.visitMethodInsn(Opcodes.INVOKESTATIC, packageAndClassName, mname, sig); 
    938          
     939 
    939940        methodReturnAndFinish(); 
    940941    } 
     
    13271328                         sig, params.size(), true); 
    13281329 
    1329          
     1330 
    13301331        generateAllWrappersForFn(x, params, sig, modifiers, mname); 
    1331          
     1332 
    13321333    } 
    13331334 
     
    13431344 
    13441345    /** 
     1346     * TODO: surely this is derivable from the arrow type, which maintains the selfParameterIndex? 
     1347     * Are those inconsistent with one another? 
    13451348     * @param params 
    13461349     * @return 
     
    13601363 
    13611364    public void forFnExpr(FnExpr x) { 
    1362         debug("forFnExpr " + x); 
     1365        debug("forFnExpr ", x); 
    13631366        FnHeader header = x.getHeader(); 
    13641367        Expr body = x.getBody(); 
     
    13791382        String className = NamingCzar.gensymArrowClassName(Naming.deDot(thisApi().getText())); 
    13801383 
    1381         debug("forFnExpr className = " + className + " desc = " + desc); 
     1384        debug("forFnExpr className = ", className, " desc = ", desc); 
    13821385        List<VarCodeGen> freeVars = getFreeVars(body); 
    13831386        cg.lexEnv = cg.createTaskLexEnvVariables(className, freeVars); 
     
    15121515        String arrow_type = NamingCzar.jvmTypeDesc(arrow, thisApi(), false); 
    15131516        String PCN = pc_and_m.getA() + "$" + 
    1514             
     1517 
    15151518            method_and_signature.getA() + 
    15161519            Naming.ENVELOPE + "$"+ // "ENVELOPE" 
     
    15301533     */ 
    15311534    public void forFunctionalRef(FunctionalRef x) { 
    1532         debug("forFunctionalRef " + x); 
     1535        debug("forFunctionalRef ", x); 
    15331536 
    15341537        List<StaticArg> sargs = x.getStaticArgs(); 
     
    15391542        com.sun.fortress.nodes.Type arrow = exprType(x); 
    15401543 
    1541         debug("forFunctionalRef " + x + " arrow = " + arrow); 
     1544        debug("forFunctionalRef ", x, " arrow = ", arrow); 
    15421545 
    15431546        Pair<String, String> calleeInfo = functionalRefToPackageClassAndMethod(x); 
     
    15541557 
    15551558            String arrow_type = NamingCzar.jvmTypeDesc(arrow, thisApi(), false); 
    1556             pkgClass = pkgClass + Naming.GEAR + "$" +  
     1559            pkgClass = pkgClass + Naming.GEAR + "$" + 
    15571560                    calleeInfo.getB() + 
    15581561                    decoration + 
     
    17891792        String [] superInterfaces = 
    17901793            NamingCzar.extendsClauseToInterfaces(extendsC, component.getName()); 
     1794        String abstractSuperclass; 
     1795        if (superInterfaces.length > 0) { 
     1796            abstractSuperclass = superInterfaces[0] + NamingCzar.springBoard; 
     1797        } else { 
     1798            abstractSuperclass = NamingCzar.internalObject; 
     1799        } 
    17911800        Id classId = NodeUtil.getName(x); 
    17921801        String classFile = 
     
    18441853        //                      classFile, null, NamingCzar.internalObject, new String[] { parent }); 
    18451854        cw.visit( Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_FINAL, 
    1846                   classFile, null, NamingCzar.internalObject, superInterfaces); 
     1855                  classFile, null, abstractSuperclass, superInterfaces); 
    18471856 
    18481857        if (!hasParameters) { 
     
    18541863 
    18551864        // Emit fields here, one per parameter. 
    1856         generateFieldsAndInitMethod(classFile, NamingCzar.internalObject, params); 
     1865        generateFieldsAndInitMethod(classFile, abstractSuperclass, params); 
    18571866 
    18581867        if (!hasParameters) { 
     
    22142223        String classFile = NamingCzar.makeInnerClassName(packageAndClassName, 
    22152224                                                         NodeUtil.getName(x).getText()); 
     2225        String abstractSuperclass; 
    22162226        traitOrObjectName = classFile; 
    22172227        if (classFile.equals("fortress/AnyType$Any")) { 
    22182228            superInterfaces = new String[0]; 
     2229            abstractSuperclass = NamingCzar.FValueType; 
     2230        } else { 
     2231            abstractSuperclass = superInterfaces[0] + NamingCzar.springBoard; 
    22192232        } 
    22202233        CodeGenClassWriter prev = cw; 
     
    22342247        // In general Springboard must not be directly instantiable. 
    22352248        cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, springBoardClass, 
    2236                  null, NamingCzar.FValueType, new String[0] ); 
     2249                 null, abstractSuperclass, new String[] { classFile } ); 
    22372250        debug("Start writing springboard class ", 
    22382251              springBoardClass); 
    2239         generateFieldsAndInitMethod(springBoardClass, NamingCzar.FValueType, 
     2252        generateFieldsAndInitMethod(springBoardClass, abstractSuperclass, 
    22402253                                    Collections.<Param>emptyList()); 
    22412254        debug("Finished init method ", springBoardClass); 
     
    22882301        } 
    22892302        if (!oinit.isSome()) { 
    2290             debug("VarDecl "+v+" skipping abs var decl."); 
     2303            debug("VarDecl ", v, " skipping abs var decl."); 
    22912304            return; 
    22922305        } 
     
    23002313        String classFile = NamingCzar.jvmTypeForToplevelDecl(var, packageAndClassName); 
    23012314        String tyDesc = NamingCzar.jvmTypeDesc(ty, thisApi()); 
    2302         debug("VarDeclPrePass "+var+" : "+ty+" = "+exp); 
     2315        debug("VarDeclPrePass ", var, " : ", ty, " = ", exp); 
    23032316        new CodeGen(this).generateVarDeclInnerClass(v, classFile, tyDesc, exp); 
    23042317 
     
    23422355 
    23432356    public void forMethodInvocation(MethodInvocation x) { 
     2357        debug("forMethodInvocation ", x, 
     2358              " obj = ", x.getObj(), 
     2359              " method = ", x.getMethod(), 
     2360              " static args = ", x.getStaticArgs(), 
     2361              " args = ", x.getArg()); 
    23442362        Id method = x.getMethod(); 
    23452363        Expr obj = x.getObj(); 
     
    24322450    public void for_RewriteFnApp(_RewriteFnApp x) { 
    24332451        debug("for_RewriteFnApp ", x, 
    2434                      " args = ", x.getArgument(), " function = ", x.getFunction() + 
    2435               " function class = " + x.getFunction()); 
     2452                     " args = ", x.getArgument(), " function = ", x.getFunction(),  
     2453              " function class = ", x.getFunction()); 
    24362454        // This is a little weird.  If a function takes no arguments the parser gives me a void literal expr 
    24372455        // however I don't want to be putting a void literal on the stack because it gets in the way. 
     
    25562574               if (cg != null) { 
    25572575                   /* Need to check if the overloaded function happens to match 
    2558                     * a name in an API that this component exports; if so,  
    2559                     * generate a forwarding wrapper from the  
     2576                    * a name in an API that this component exports; if so, 
     2577                    * generate a forwarding wrapper from the 
    25602578                    */ 
    25612579               } 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/codegen/SParallelismAnalyzer.scala

    r3935 r4300  
    5959    } 
    6060 
    61     override def walk(x: Any) = {  
    62         x match {  
    63           case sop@SOpExpr(_, op, args) => {  
     61    override def walk(x: Any) = { 
     62        x match { 
     63          case sop@SOpExpr(_, op, args) => { 
    6464               if (tallyArgs(args)) worthy += sop 
    6565               walk(args) 
    6666          } 
    67           case fnApp@S_RewriteFnApp(_, fun, STupleExpr(_, exprs, varargs, keywords, _)) => {  
     67          case fnApp@S_RewriteFnApp(_, fun, STupleExpr(_, exprs, varargs, keywords, _)) => { 
    6868               if (tallyArgs(exprs)) worthy += fnApp 
    6969          } 
    7070          case _ => super.walk(x) 
    7171        } 
    72     }       
     72    } 
    7373} 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/desugarer/VarRefContainer.java

    r3716 r4300  
    4949import edu.rice.cs.plt.tuple.Option; 
    5050 
     51/** Generate object to hold hoisted mutable variables that are shared by 
     52 *  an object expression and its enclosing context. 
     53 */ 
    5154public class VarRefContainer { 
    5255    private VarRef origVar; 
  • trunk/ProjectFortress/src/com/sun/fortress/interpreter/rewrite/DesugarerVisitor.java

    r4185 r4300  
    10311031        FnExpr fnExpr = ExprFactory.makeFnExpr(sp, params, (Expr) rewrittenExpr); 
    10321032 
    1033         return visitNode(ExprFactory.makeTightJuxt(NodeUtil.getSpan(s), fn, fnExpr)); 
     1033        return visitNode(ExprFactory.make_RewriteFnApp(NodeUtil.getSpan(s), fn, fnExpr)); 
    10341034    } 
    10351035 
  • trunk/ProjectFortress/src/com/sun/fortress/nodes_util/ExprFactory.java

    r4296 r4300  
    467467        ExprInfo info = NodeFactory.makeExprInfo(span, parenthesized, ty); 
    468468        return new OpRef(info, staticArgs, lexicalDepth, name, names, 
    469                 interp_overloadings, newOverloadings, 
    470                                         overloadingType); 
     469                         interp_overloadings, newOverloadings, 
     470                        overloadingType); 
    471471    } 
    472472 
     
    19951995 
    19961996    //Span in_span, boolean in_parenthesized, Id in_obj, List<StaticArg> in_staticArgs 
    1997         public static Expr make_RewriteObjectRef(boolean parenthesized, Id in_obj) { 
    1998                 return make_RewriteObjectRef(parenthesized, in_obj, Collections.<StaticArg>emptyList()); 
    1999         } 
     1997    public static Expr make_RewriteObjectRef(boolean parenthesized, Id in_obj) { 
     1998        return make_RewriteObjectRef(parenthesized, in_obj, Collections.<StaticArg>emptyList()); 
     1999    } 
    20002000 
    20012001    public static NonParenthesisDelimitedMI makeNonParenthesisDelimitedMI(Span span, 
  • trunk/ProjectFortress/src/com/sun/fortress/nodes_util/NodeUtil.java

    r4280 r4300  
    5858 
    5959    public static boolean isKeyword(Id id) { 
    60         String name = id.getText(); 
    61         return ( ! name.equals("self") && 
    62                 Fortress.FORTRESS_KEYWORDS.contains(name) ); 
     60        String name = id.getText(); 
     61        return ( ! name.equals("self") && 
     62                Fortress.FORTRESS_KEYWORDS.contains(name) ); 
    6363    } 
    6464 
    6565    public static void log(BufferedWriter writer, Span span, String msg) { 
    66         try { 
    67             if ( writer == null ) { 
    68                 String file = span.getFileName(); 
    69                 writer = Useful.filenameToBufferedWriter( file + ".preparserError.log" ); 
    70             } 
    71             writer.write( span + ":\n    " + msg + "\n" ); 
    72         } catch (IOException error) { 
    73             error("Writing to a log file for the parser failed!"); 
    74         } 
     66        try { 
     67            if ( writer == null ) { 
     68                String file = span.getFileName(); 
     69                writer = Useful.filenameToBufferedWriter( file + ".preparserError.log" ); 
     70            } 
     71            writer.write( span + ":\n    " + msg + "\n" ); 
     72        } catch (IOException error) { 
     73            error("Writing to a log file for the parser failed!"); 
     74        } 
    7575    } 
    7676 
     
    8484 
    8585    public static Span spanTwo(Span s1, Span s2) { 
    86         return new Span(s1.getBegin(), s2.getEnd()); 
     86        return new Span(s1.getBegin(), s2.getEnd()); 
    8787    } 
    8888 
    8989    public static Span spanTwo(ASTNode s1, ASTNode s2) { 
    90         return spanTwo(getSpan(s1), getSpan(s2)); 
     90        return spanTwo(getSpan(s1), getSpan(s2)); 
    9191    } 
    9292 
    9393    public static Span spanTwo(Expr e1, Expr e2) { 
    94         return spanTwo(getSpan(e1), getSpan(e2)); 
     94        return spanTwo(getSpan(e1), getSpan(e2)); 
    9595    } 
    9696 
     
    100100//     | node :: rest -> join node.node_span (span_all rest) 
    101101    public static Span spanAll(Object[] nodes, int size) { 
    102         if (size == 0) 
    103             return bug("Cannot make a span from an empty list of nodes."); 
    104         else { // size != 0 
    105             return new Span(getSpan((ASTNode)Array.get(nodes,0)).getBegin(), 
    106                             getSpan((ASTNode)Array.get(nodes,size-1)).getEnd()); 
    107         } 
     102        if (size == 0) 
     103            return bug("Cannot make a span from an empty list of nodes."); 
     104        else { // size != 0 
     105            return new Span(getSpan((ASTNode)Array.get(nodes,0)).getBegin(), 
     106                            getSpan((ASTNode)Array.get(nodes,size-1)).getEnd()); 
     107        } 
    108108    } 
    109109 
    110110    public static Span spanAll(Iterable<? extends ASTNode> nodes) { 
    111         if (IterUtil.isEmpty(nodes)) 
    112             return bug("Cannot make a span from an empty list of nodes."); 
    113         else { 
    114             return new Span(getSpan(IterUtil.first(nodes)).getBegin(), 
    115                             getSpan(IterUtil.last(nodes)).getEnd()); 
    116         } 
     111        if (IterUtil.isEmpty(nodes)) 
     112            return bug("Cannot make a span from an empty list of nodes."); 
     113        else { 
     114            return new Span(getSpan(IterUtil.first(nodes)).getBegin(), 
     115                            getSpan(IterUtil.last(nodes)).getEnd()); 
     116        } 
    117117    } 
    118118 
    119119    public static Span spanAll(SourceLoc defaultLoc, Iterable<? extends ASTNode> nodes) { 
    120         if (IterUtil.isEmpty(nodes)) { return new Span(defaultLoc, defaultLoc); } 
    121         else { 
    122             return new Span(getSpan(IterUtil.first(nodes)).getBegin(), 
    123                             getSpan(IterUtil.last(nodes)).getEnd()); 
    124         } 
     120        if (IterUtil.isEmpty(nodes)) { return new Span(defaultLoc, defaultLoc); } 
     121        else { 
     122            return new Span(getSpan(IterUtil.first(nodes)).getBegin(), 
     123                            getSpan(IterUtil.last(nodes)).getEnd()); 
     124        } 
    125125    } 
    126126 
     
    128128 
    129129    public static ASTNodeInfo getInfo(ASTNode n) { 
    130         return n.getInfo(); 
     130        return n.getInfo(); 
    131131    } 
    132132 
    133133    public static Span getSpan(ASTNode n) { 
    134         return n.getInfo().getSpan(); 
     134        return n.getInfo().getSpan(); 
    135135    } 
    136136 
    137137    public static boolean isTraitObjectDecl(ASTNode n) { 
    138         return (n instanceof TraitObjectDecl); 
     138        return (n instanceof TraitObjectDecl); 
    139139    } 
    140140 
     
    142142 
    143143    public static Span getSpan(Expr e) { 
    144         return e.getInfo().getSpan(); 
     144        return e.getInfo().getSpan(); 
    145145    } 
    146146 
    147147    public static boolean isParenthesized(Expr e) { 
    148         return e.getInfo().isParenthesized(); 
     148        return e.getInfo().isParenthesized(); 
    149149    } 
    150150 
    151151    public static Option<Type> getExprType(Expr e) { 
    152         return e.getInfo().getExprType(); 
     152        return e.getInfo().getExprType(); 
    153153    } 
    154154 
     
    156156 
    157157    public static Span getSpan(Type t) { 
    158         return t.getInfo().getSpan(); 
     158        return t.getInfo().getSpan(); 
    159159    } 
    160160 
    161161    public static boolean isParenthesized(Type t) { 
    162         return t.getInfo().isParenthesized(); 
     162        return t.getInfo().isParenthesized(); 
    163163    } 
    164164 
    165165    public static List<StaticParam> getStaticParams(Type t) { 
    166         return t.getInfo().getStaticParams(); 
     166        return t.getInfo().getStaticParams(); 
    167167    } 
    168168 
    169169    public static Option<WhereClause> getWhereClause(Type t) { 
    170         return t.getInfo().getWhereClause(); 
     170        return t.getInfo().getWhereClause(); 
    171171    } 
    172172 
     
    174174 
    175175    public static Modifiers getMods(TraitObjectDecl t) { 
    176         return t.getHeader().getMods(); 
     176        return t.getHeader().getMods(); 
    177177    } 
    178178 
    179179    public static Id getName(TraitObjectDecl t) { 
    180         return (Id)t.getHeader().getName(); 
     180        return (Id)t.getHeader().getName(); 
    181181    } 
    182182 
    183183    public static List<Decl> getDecls(TraitObjectDecl t) { 
    184         return t.getHeader().getDecls(); 
     184        return t.getHeader().getDecls(); 
    185185    } 
    186186 
    187187    public static List<StaticParam> getStaticParams(TraitObjectDecl t) { 
    188         return t.getHeader().getStaticParams(); 
     188        return t.getHeader().getStaticParams(); 
    189189    } 
    190190 
     
    204204 
    205205    public static Option<WhereClause> getWhereClause(TraitObjectDecl o) { 
    206         return o.getHeader().getWhereClause(); 
     206        return o.getHeader().getWhereClause(); 
    207207    } 
    208208 
    209209    public static List<TraitTypeWhere> getExtendsClause(TraitObjectDecl t) { 
    210         return t.getHeader().getExtendsClause(); 
     210        return t.getHeader().getExtendsClause(); 
    211211    } 
    212212 
    213213    public static List<BaseType> getExcludesClause(TraitObjectDecl t) { 
    214         if ( t instanceof TraitDecl ) 
    215             return ((TraitDecl)t).getExcludesClause(); 
    216         else 
    217             return bug("TraitDecl expected, but got " + t); 
     214        if ( t instanceof TraitDecl ) 
     215            return ((TraitDecl)t).getExcludesClause(); 
     216        else 
     217            return bug("TraitDecl expected, but got " + t); 
    218218    } 
    219219 
    220220    public static Option<List<NamedType>> getComprisesClause(TraitObjectDecl t) { 
    221         if ( t instanceof TraitDecl ) 
    222             return ((TraitDecl)t).getComprisesClause(); 
    223         else 
    224             return bug("TraitDecl expected, but got " + t); 
     221        if ( t instanceof TraitDecl ) 
     222            return ((TraitDecl)t).getComprisesClause(); 
     223        else 
     224            return bug("TraitDecl expected, but got " + t); 
    225225    } 
    226226 
    227227    public static boolean isComprisesEllipses(TraitObjectDecl t) { 
    228         if ( t instanceof TraitDecl ) 
    229             return ((TraitDecl)t).isComprisesEllipses(); 
    230         else { 
    231             bug("TraitDecl expected, but got " + t); 
    232             return false; 
    233         } 
     228        if ( t instanceof TraitDecl ) 
     229            return ((TraitDecl)t).isComprisesEllipses(); 
     230        else { 
     231            bug("TraitDecl expected, but got " + t); 
     232            return false; 
     233        } 
    234234    } 
    235235 
    236236    public static Option<List<Param>> getParams(TraitObjectDecl o) { 
    237         if ( o instanceof ObjectDecl ) 
    238             return ((ObjectDecl)o).getParams(); 
    239         else 
    240             return bug("ObjectDecl expected, but got " + o); 
     237        if ( o instanceof ObjectDecl ) 
     238            return ((ObjectDecl)o).getParams(); 
     239        else 
     240            return bug("ObjectDecl expected, but got " + o); 
    241241    } 
    242242 
    243243    /* Getters for TraitDecl */ 
    244244    public static List<BaseType> getExcludesClause(TraitDecl t) { 
    245         return t.getExcludesClause(); 
     245        return t.getExcludesClause(); 
    246246    } 
    247247 
    248248    public static Option<List<NamedType>> getComprisesClause(TraitDecl t) { 
    249         return t.getComprisesClause(); 
     249        return t.getComprisesClause(); 
    250250    } 
    251251 
    252252    /* Getters for ObjectDecl */ 
    253253    public static Option<List<Param>> getParams(ObjectDecl o) { 
    254         return o.getParams(); 
     254        return o.getParams(); 
    255255    } 
    256256 
    257257    public static Option<List<Type>> getThrowsClause(ObjectDecl o) { 
    258         return o.getHeader().getThrowsClause(); 
     258        return o.getHeader().getThrowsClause(); 
    259259    } 
    260260 
    261261    public static Option<Contract> getContract(ObjectDecl o) { 
    262         return o.getHeader().getContract(); 
     262        return o.getHeader().getContract(); 
    263263    } 
    264264 
    265265    public static List<Decl> getDecls(ObjectDecl o) { 
    266         return o.getHeader().getDecls(); 
     266        return o.getHeader().getDecls(); 
    267267    } 
    268268 
    269269    public static List<TraitTypeWhere> getExtendsClause(ObjectDecl o) { 
    270         return o.getHeader().getExtendsClause(); 
     270        return o.getHeader().getExtendsClause(); 
    271271    } 
    272272 
    273273    /* Getters for ObjectExpr */ 
    274274    public static List<Decl> getDecls(ObjectExpr o) { 
    275         return o.getHeader().getDecls(); 
     275        return o.getHeader().getDecls(); 
    276276    } 
    277277 
    278278    public static List<TraitTypeWhere> getExtendsClause(ObjectExpr o) { 
    279         return o.getHeader().getExtendsClause(); 
     279        return o.getHeader().getExtendsClause(); 
    280280    } 
    281281 
    282282    /* Getters for FnDecl */ 
    283283    public static Modifiers getMods(FnDecl f) { 
    284         return f.getHeader().getMods(); 
     284        return f.getHeader().getMods(); 
    285285    } 
    286286 
    287287    public static IdOrOpOrAnonymousName getName(FnDecl f) { 
    288         return f.getHeader().getName(); 
     288        return f.getHeader().getName(); 
    289289    } 
    290290 
    291291    public static List<StaticParam> getStaticParams(FnDecl f) { 
    292         return f.getHeader().getStaticParams(); 
     292        return f.getHeader().getStaticParams(); 
    293293    } 
    294294 
    295295    public static Option<WhereClause> getWhereClause(FnDecl f) { 
    296         return f.getHeader().getWhereClause(); 
     296        return f.getHeader().getWhereClause(); 
    297297    } 
    298298 
    299299    public static List<Param> getParams(FnDecl f) { 
    300         return f.getHeader().getParams(); 
     300        return f.getHeader().getParams(); 
    301301    } 
    302302 
    303303    public static Type getParamType(Param p) { 
    304         if ( p.getIdType().isSome() ) 
    305             return p.getIdType().unwrap(); 
    306         else if ( p.getVarargsType().isSome() ) 
    307             return NodeFactory.makeVarargsType(getSpan(p), 
    308                                                p.getVarargsType().unwrap()); 
    309         else 
    310             return bug(getSpan(p) + "\n    Type is not inferred."); 
     304        if ( p.getIdType().isSome() ) 
     305            return p.getIdType().unwrap(); 
     306        else if ( p.getVarargsType().isSome() ) 
     307            return NodeFactory.makeVarargsType(getSpan(p), 
     308                                               p.getVarargsType().unwrap()); 
     309        else 
     310            return bug(getSpan(p) + "\n    Type is not inferred."); 
    311311    } 
    312312 
    313313    public static Type getParamType(List<Param> params, Span span) { 
    314         if ( params.isEmpty() ) return NodeFactory.makeVoidType(span); 
    315         else if ( params.size() == 1 ) return getParamType(params.get(0)); 
    316         else { // if ( params.size() > 1 ) 
    317             List<Type> types = new ArrayList<Type>( params.size() ); 
    318             for ( Param p : params ) { 
    319                 types.add( getParamType(p) ); 
    320             } 
    321             return NodeFactory.makeTupleType(span, types); 
    322         } 
     314        if ( params.isEmpty() ) return NodeFactory.makeVoidType(span); 
     315        else if ( params.size() == 1 ) return getParamType(params.get(0)); 
     316        else { // if ( params.size() > 1 ) 
     317            List<Type> types = new ArrayList<Type>( params.size() ); 
     318            for ( Param p : params ) { 
     319                types.add( getParamType(p) ); 
     320            } 
     321            return NodeFactory.makeTupleType(span, types); 
     322        } 
    323323    } 
    324324 
    325325    public static Option<Type> getParamType(ObjectDecl o) { 
    326         if ( o.getParams().isSome() ) { 
    327             return Option.<Type>some(getParamType(o.getParams().unwrap(), getSpan(o))); 
    328         } else return Option.<Type>none(); 
     326        if ( o.getParams().isSome() ) { 
     327            return Option.<Type>some(getParamType(o.getParams().unwrap(), getSpan(o))); 
     328        } else return Option.<Type>none(); 
    329329    } 
    330330 
    331331    public static Type getParamType(FnDecl f) { 
    332         return getParamType(getParams(f), getSpan(f)); 
     332        return getParamType(getParams(f), getSpan(f)); 
    333333    } 
    334334 
    335335    public static Option<Type> getReturnType(FnDecl f) { 
    336         return f.getHeader().getReturnType(); 
     336        return f.getHeader().getReturnType(); 
    337337    } 
    338338 
    339339    public static Option<List<Type>> getThrowsClause(FnDecl f) { 
    340         return f.getHeader().getThrowsClause(); 
     340        return f.getHeader().getThrowsClause(); 
    341341    } 
    342342 
    343343    public static Option<Contract> getContract(FnDecl f) { 
    344         return f.getHeader().getContract(); 
     344        return f.getHeader().getContract(); 
    345345    } 
    346346 
    347347    /* Getters for FnExpr */ 
    348348    public static IdOrOpOrAnonymousName getName(FnExpr f) { 
    349         return f.getHeader().getName(); 
     349        return f.getHeader().getName(); 
    350350    } 
    351351 
    352352    public static List<StaticParam> getStaticParams(FnExpr f) { 
    353         return f.getHeader().getStaticParams(); 
     353        return f.getHeader().getStaticParams(); 
    354354    } 
    355355 
    356356    public static Option<WhereClause> getWhereClause(FnExpr f) { 
    357         return f.getHeader().getWhereClause(); 
     357        return f.getHeader().getWhereClause(); 
    358358    } 
    359359 
    360360    public static List<Param> getParams(FnExpr f) { 
    361         return f.getHeader().getParams(); 
     361        return f.getHeader().getParams(); 
    362362    } 
    363363 
    364364    public static Option<Type> getReturnType(FnExpr f) { 
    365         return f.getHeader().getReturnType(); 
     365        return f.getHeader().getReturnType(); 
    366366    } 
    367367 
    368368    public static Option<List<Type>> getThrowsClause(FnExpr f) { 
    369         return f.getHeader().getThrowsClause(); 
     369        return f.getHeader().getThrowsClause(); 
    370370    } 
    371371 
    372372    /* Getter for Generic */ 
    373373    public static List<StaticParam> getStaticParams(Generic g) { 
    374         return g.getHeader().getStaticParams(); 
     374        return g.getHeader().getStaticParams(); 
    375375    } 
    376376 
    377377    /* Getters for ObjectConstructor */ 
    378378    public static Option<List<Param>> getParams(ObjectConstructor g) { 
    379         return g.getParams(); 
     379        return g.getParams(); 
    380380    } 
    381381 
    382382    public static List<Decl> getDecls(ObjectConstructor g) { 
    383         return g.getHeader().getDecls(); 
     383        return g.getHeader().getDecls(); 
    384384    } 
    385385 
    386386    public static List<TraitTypeWhere> getExtendsClause(ObjectConstructor g) { 
    387         return g.getHeader().getExtendsClause(); 
     387        return g.getHeader().getExtendsClause(); 
    388388    } 
    389389 
    390390    /* Getters for Applicable */ 
    391391    public static IdOrOpOrAnonymousName getName(Applicable a) { 
    392         return a.getHeader().getName(); 
     392        return a.getHeader().getName(); 
    393393    } 
    394394 
    395395    public static List<StaticParam> getStaticParams(Applicable a) { 
    396         return a.getHeader().getStaticParams(); 
     396        return a.getHeader().getStaticParams(); 
    397397    } 
    398398 
    399399    public static List<Param> getParams(Applicable a) { 
    400         return a.getHeader().getParams(); 
     400        return a.getHeader().getParams(); 
    401401    } 
    402402 
    403403    public static Option<Type> getReturnType(Applicable a) { 
    404         return a.getHeader().getReturnType(); 
     404        return a.getHeader().getReturnType(); 
    405405    } 
    406406 
    407407    public static Option<Type> getSelfType(ArrowType a) { 
    408         Option<MethodInfo> mi = a.getMethodInfo(); 
    409         if (mi.isNone()) return Option.<Type>none(); 
    410         return Option.some(mi.unwrap().getSelfType()); 
     408        Option<MethodInfo> mi = a.getMethodInfo(); 
     409        if (mi.isNone()) return Option.<Type>none(); 
     410        return Option.some(mi.unwrap().getSelfType()); 
    411411    } 
    412412 
    413413    public static Option<Integer> getSelfPosition(ArrowType a) { 
    414         Option<MethodInfo> mi = a.getMethodInfo(); 
    415         if (mi.isNone()) return Option.<Integer>none(); 
    416         return Option.some(mi.unwrap().getSelfPosition()); 
     414        Option<MethodInfo> mi = a.getMethodInfo(); 
     415        if (mi.isNone()) return Option.<Integer>none(); 
     416        return Option.some(mi.unwrap().getSelfPosition()); 
    417417    } 
    418418 
    419419    public static Option<WhereClause> getWhereClause(Applicable a) { 
    420         return a.getHeader().getWhereClause(); 
     420        return a.getHeader().getWhereClause(); 
    421421    } 
    422422 
    423423    public static boolean isOpParam(StaticParam p) { 
    424         return p.getKind() instanceof KindOp; 
     424        return p.getKind() instanceof KindOp; 
    425425    } 
    426426 
    427427    public static boolean isTypeParam(StaticParam p) { 
    428         return p.getKind() instanceof KindType; 
     428        return p.getKind() instanceof KindType; 
    429429    } 
    430430 
    431431    public static boolean isIntParam(StaticParam p) { 
    432         return ( p.getKind() instanceof KindInt || 
    433                 p.getKind() instanceof KindNat ); 
     432        return ( p.getKind() instanceof KindInt || 
     433                p.getKind() instanceof KindNat ); 
    434434    } 
    435435 
    436436    public static boolean isNatParam(StaticParam p) { 
    437         return p.getKind() instanceof KindNat; 
     437        return p.getKind() instanceof KindNat; 
    438438    } 
    439439 
    440440    public static boolean isBoolParam(StaticParam p) { 
    441         return p.getKind() instanceof KindBool; 
     441        return p.getKind() instanceof KindBool; 
    442442    } 
    443443 
    444444    public static boolean isDimParam(StaticParam p) { 
    445         return p.getKind() instanceof KindDim; 
     445        return p.getKind() instanceof KindDim; 
    446446    } 
    447447 
    448448    public static boolean isUnitParam(StaticParam p) { 
    449         return p.getKind() instanceof KindUnit; 
     449        return p.getKind() instanceof KindUnit; 
    450450    } 
    451451 
    452452    public static List<_RewriteObjectExpr> getObjectExprs(Component comp) { 
    453         for ( Decl d : comp.getDecls() ) { 
    454             if ( d instanceof _RewriteObjectExprDecl ) 
    455                 return ((_RewriteObjectExprDecl)d).getObjectExprs(); 
    456         } 
    457         return new ArrayList<_RewriteObjectExpr>(); 
     453        for ( Decl d : comp.getDecls() ) { 
     454            if ( d instanceof _RewriteObjectExprDecl ) 
     455                return ((_RewriteObjectExprDecl)d).getObjectExprs(); 
     456        } 
     457        return new ArrayList<_RewriteObjectExpr>(); 
    458458    } 
    459459 
    460460    public static List<String> getFunctionalMethodNames(Component comp) { 
    461         for ( Decl d : comp.getDecls() ) { 
    462             if ( d instanceof _RewriteFunctionalMethodDecl ) 
    463                 return ((_RewriteFunctionalMethodDecl)d).getFunctionalMethodNames(); 
    464         } 
    465         return new ArrayList<String>(); 
     461        for ( Decl d : comp.getDecls() ) { 
     462            if ( d instanceof _RewriteFunctionalMethodDecl ) 
     463                return ((_RewriteFunctionalMethodDecl)d).getFunctionalMethodNames(); 
     464        } 
     465        return new ArrayList<String>(); 
    466466    } 
    467467 
    468468    private static boolean beginComment( String token ) { 
    469         return (token.length() >= 2 && 
    470                 token.substring(0,2).equals("(*")); 
     469        return (token.length() >= 2 && 
     470                token.substring(0,2).equals("(*")); 
    471471    } 
    472472 
    473473    private static boolean endComment( String token ) { 
    474         return (token.length() >= 2 && 
    475                 token.substring(token.length()-2,token.length()).equals("*)")); 
     474        return (token.length() >= 2 && 
     475                token.substring(token.length()-2,token.length()).equals("*)")); 
    476476    } 
    477477 
    478478    private static boolean lineComment( String token ) { 
    479         return (token.length() == 3 && 
    480                 token.equals("(*)")); 
     479        return (token.length() == 3 && 
     480                token.equals("(*)")); 
    481481    } 
    482482 
    483483    private static boolean blankOrComment( String line ) { 
    484         if ( line.equals("") ) 
    485             return true; 
    486         else { 
    487             String[] split = line.split(" "); 
    488             return beginComment(split[0]); 
    489         } 
     484        if ( line.equals("") ) 
     485            return true; 
     486        else { 
     487            String[] split = line.split(" "); 
     488            return beginComment(split[0]); 
     489        } 
    490490    } 
    491491 
    492492    /* Getters for VarDecl */ 
    493493    public static Modifiers getMods(BufferedWriter writer, VarDecl v) { 
    494         if ( v.getLhs().isEmpty() ) { 
    495             log(writer, getSpan(v), 
    496                 "Variable declaration does not declare any: " + v); 
    497             return Modifiers.None; 
    498         } else 
    499             return v.getLhs().get(0).getMods(); 
     494        if ( v.getLhs().isEmpty() ) { 
     495            log(writer, getSpan(v), 
     496                "Variable declaration does not declare any: " + v); 
     497            return Modifiers.None; 
     498        } else 
     499            return v.getLhs().get(0).getMods(); 
    500500    } 
    501501 
    502502    /* Getters for LocalVarDecl */ 
    503503    public static Modifiers getMods(BufferedWriter writer, LocalVarDecl v) { 
    504         if ( v.getLhs().isEmpty() ) { 
    505             log(writer, getSpan(v), 
    506                 "Variable declaration does not declare any: " + v); 
    507             return Modifiers.None; 
    508         } else 
    509             return v.getLhs().get(0).getMods(); 
     504        if ( v.getLhs().isEmpty() ) { 
     505            log(writer, getSpan(v), 
     506                "Variable declaration does not declare any: " + v); 
     507            return Modifiers.None; 
     508        } else 
     509            return v.getLhs().get(0).getMods(); 
    510510    } 
    511511 
    512512    /* get the declared name of a component or api */ 
    513513    public static APIName apiName( String path ) throws UserError, IOException { 
    514         String absolutePath = new File(path).getCanonicalPath(); 
    515         try { 
    516             File file = new File(path).getCanonicalFile(); 
    517             String filename = new File(path).getName(); 
    518             try { 
    519                 filename = filename.substring(0, filename.length()-4); 
    520                 BufferedReader br = Useful.utf8BufferedFileReader(file); 
    521                 // skip comments and blank lines 
    522                 int lineNo = 0; 
    523                 int commentDepth = 0; 
    524                 String line = br.readLine(); lineNo++; 
    525                 while ( blankOrComment(line) || commentDepth != 0 ) { 
    526                     if ( line.equals("") ) { 
    527                         line = br.readLine(); lineNo++; 
    528                     } else { 
    529                         String[] split = line.split(" "); 
    530                         for ( String token : split ) { 
    531                             if ( lineComment(token) ) { 
    532                                 line = ""; 
    533                                 break; 
    534                             } else if ( beginComment(token) ) { 
    535                                 commentDepth++; line = ""; 
    536                             } else if ( endComment(token) ) { 
    537                                 commentDepth--; line = ""; 
    538                             } else if ( commentDepth == 0 ) { 
    539                                 line += token; 
    540                                 line += " "; 
    541                             } 
    542                         } 
    543                         if ( commentDepth == 0 && ! line.equals("") ) break; 
    544                         else line = br.readLine(); lineNo++; 
    545                     } 
    546                 } 
    547                 br.close(); 
    548                 // line is the first non-comment/non-blank line 
    549                 String[] split = line.split(" "); 
    550                 String name; 
    551                 if ( split[0].equals("component") || split[0].equals("api") ) { 
    552                     Span span = NodeFactory.makeSpan(absolutePath, 
    553                                                      lineNo, split[0].length()+2, 
    554                                                      split[0].length()+split[1].length()+1); 
    555                     name = split[1]; 
    556                     if ( ! name.equals(filename) ) 
    557                         return error(span, 
    558                                      "    Component/API names must match their enclosing file names." + 
    559                                      "\n    File name: " + absolutePath + 
    560                                      "\n    Component/API name: " + name); 
    561                 } else name = filename; 
    562                 return NodeFactory.makeAPIName(NodeFactory.parserSpan, name); 
    563             } catch (NullPointerException ex) { 
    564                 return NodeFactory.makeAPIName(NodeFactory.parserSpan, filename); 
    565             } 
    566         } catch (FileNotFoundException ex) { 
    567             throw new UserError("Cannot find file " + absolutePath); 
    568         } 
     514        String absolutePath = new File(path).getCanonicalPath(); 
     515        try { 
     516            File file = new File(path).getCanonicalFile(); 
     517            String filename = new File(path).getName(); 
     518            try { 
     519                filename = filename.substring(0, filename.length()-4); 
     520                BufferedReader br = Useful.utf8BufferedFileReader(file); 
     521                // skip comments and blank lines 
     522                int lineNo = 0; 
     523                int commentDepth = 0; 
     524                String line = br.readLine(); lineNo++; 
     525                while ( blankOrComment(line) || commentDepth != 0 ) { 
     526                    if ( line.equals("") ) { 
     527                        line = br.readLine(); lineNo++; 
     528                    } else { 
     529                        String[] split = line.split(" "); 
     530                        for ( String token : split ) { 
     531                            if ( lineComment(token) ) { 
     532                                line = ""; 
     533                                break; 
     534                            } else if ( beginComment(token) ) { 
     535                                commentDepth++; line = ""; 
     536                            } else if ( endComment(token) ) { 
     537                                commentDepth--; line = ""; 
     538                            } else if ( commentDepth == 0 ) { 
     539                                line += token; 
     540                                line += " "; 
     541                            } 
     542                        } 
     543                        if ( commentDepth == 0 && ! line.equals("") ) break; 
     544                        else line = br.readLine(); lineNo++; 
     545                    } 
     546                } 
     547                br.close(); 
     548                // line is the first non-comment/non-blank line 
     549                String[] split = line.split(" "); 
     550                String name; 
     551                if ( split[0].equals("component") || split[0].equals("api") ) { 
     552                    Span span = NodeFactory.makeSpan(absolutePath, 
     553                                                     lineNo, split[0].length()+2, 
     554                                                     split[0].length()+split[1].length()+1); 
     555                    name = split[1]; 
     556                    if ( ! name.equals(filename) ) 
     557                        return error(span, 
     558                                     "    Component/API names must match their enclosing file names." + 
     559                                     "\n    File name: " + absolutePath + 
     560                                     "\n    Component/API name: " + name); 
     561                } else name = filename; 
     562                return NodeFactory.makeAPIName(NodeFactory.parserSpan, name); 
     563            } catch (NullPointerException ex) { 
     564                return NodeFactory.makeAPIName(NodeFactory.parserSpan, filename); 
     565            } 
     566        } catch (FileNotFoundException ex) { 
     567            throw new UserError("Cannot find file " + absolutePath); 
     568        } 
    569569    } 
    570570 
    571571    public static Iterable<Id> getIds(final Id qName) { 
    572         return qName.getApiName().apply(new OptionVisitor<APIName, Iterable<Id>>() { 
    573             public Iterable<Id> forSome(APIName apiName) { 
    574                 return IterUtil.compose(apiName.getIds(), qName); 
    575             } 
    576             public Iterable<Id> forNone() { 
    577                 return IterUtil.singleton(qName); 
    578             } 
    579         }); 
     572        return qName.getApiName().apply(new OptionVisitor<APIName, Iterable<Id>>() { 
     573            public Iterable<Id> forSome(APIName apiName) { 
     574                return IterUtil.compose(apiName.getIds(), qName); 
     575            } 
     576            public Iterable<Id> forNone() { 
     577                return IterUtil.singleton(qName); 
     578            } 
     579        }); 
    580580    } 
    581581 
     
    587587     */ 
    588588    public static int selfParameterIndex(Applicable d) { 
    589         int i = 0; 
    590         for (Param p : getParams(d)) { 
    591             Id name = p.getName(); 
    592                 if (WellKnownNames.defaultSelfName.equals(nameString(name))) { 
    593                 return i; 
    594             } 
    595             i++; 
    596         } 
    597         return -1; 
     589        int i = 0; 
     590        for (Param p : getParams(d)) { 
     591            Id name = p.getName(); 
     592                if (WellKnownNames.defaultSelfName.equals(nameString(name))) { 
     593                return i; 
     594            } 
     595            i++; 
     596        } 
     597        return -1; 
    598598    } 
    599599 
    600600    /* for Applicable ******************************************************/ 
    601601    public static String nameAsMethod(Applicable app) { 
    602         String name = nameString(getName(app)); 
    603             int spi = selfParameterIndex(app); 
    604             if (spi >= 0) 
    605                 return "rm$" + spi + "$" + name; 
    606             else 
    607                 return name; 
     602        String name = nameString(getName(app)); 
     603            int spi = selfParameterIndex(app); 
     604            if (spi >= 0) 
     605                return "rm$" + spi + "$" + name; 
     606            else 
     607                return name; 
    608608 
    609609    } 
    610610 
    611611    public static Option<Expr> getBody(Applicable def) { 
    612         if (def instanceof FnDecl) { return ((FnDecl)def).getBody(); } 
    613         else if (def instanceof FnExpr) { return Option.some(((FnExpr)def).getBody()); } 
    614         else { return Option.none(); } 
     612        if (def instanceof FnDecl) { return ((FnDecl)def).getBody(); } 
     613        else if (def instanceof FnExpr) { return Option.some(((FnExpr)def).getBody()); } 
     614        else { return Option.none(); } 
    615615    } 
    616616 
    617617    public static boolean hasVarargs(Type t) { 
    618         if ( isTupleType(t) ) 
    619             return hasVarargs((TupleType)t); 
    620         else { 
    621             bug("TupleType expected, but got " + t); 
    622             return false; 
    623         } 
     618        if ( isTupleType(t) ) 
     619            return hasVarargs((TupleType)t); 
     620        else { 
     621            bug("TupleType expected, but got " + t); 
     622            return false; 
     623        } 
    624624    } 
    625625 
    626626    public static boolean hasKeywords(Type t) { 
    627         if ( isTupleType(t) ) 
    628             return hasKeywords((TupleType)t); 
    629         else { 
    630             bug("TupleType expected, but got " + t); 
    631             return false; 
    632         } 
     627        if ( isTupleType(t) ) 
     628            return hasKeywords((TupleType)t); 
     629        else { 
     630            bug("TupleType expected, but got " + t); 
     631            return false; 
     632        } 
    633633    } 
    634634 
    635635    public static boolean hasVarargs(TupleType t) { 
    636         return t.getVarargs().isSome(); 
     636        return t.getVarargs().isSome(); 
    637637    } 
    638638 
    639639    public static boolean hasKeywords(TupleType t) { 
    640         return ! t.getKeywords().isEmpty(); 
     640        return ! t.getKeywords().isEmpty(); 
    641641    } 
    642642 
    643643    public static boolean isVarargsParam(Param p) { 
    644         return p.getVarargsType().isSome(); 
     644        return p.getVarargsType().isSome(); 
    645645    } 
    646646 
    647647    public static boolean isKeywordParam(Param p) { 
    648         return p.getDefaultExpr().isSome(); 
     648        return p.getDefaultExpr().isSome(); 
    649649    } 
    650650 
    651651    public static boolean isSingletonObject(VarRef v) { 
    652         return (! v.getStaticArgs().isEmpty()); 
     652        return (! v.getStaticArgs().isEmpty()); 
    653653    } 
    654654 
    655655    public static boolean isGenericSingletonType(TraitType t) { 
    656         return (! t.getStaticParams().isEmpty()); 
     656        return (! t.getStaticParams().isEmpty()); 
    657657    } 
    658658 
    659659    public static boolean isVoidType(Type t) { 
    660         if ( t instanceof TupleType ) { 
    661             TupleType _t = (TupleType)t; 
    662             return ( _t.getElements().isEmpty() && 
    663                      _t.getVarargs().isNone() && 
    664                      _t.getKeywords().isEmpty() ); 
    665         } else 
    666             return false; 
     660        if ( t instanceof TupleType ) { 
     661            TupleType _t = (TupleType)t; 
     662            return ( _t.getElements().isEmpty() && 
     663                     _t.getVarargs().isNone() && 
     664                     _t.getKeywords().isEmpty() ); 
     665        } else 
     666            return false; 
    667667    } 
    668668 
    669669    public static boolean isTupleType(Type t) { 
    670         return ( t instanceof TupleType ); 
     670        return ( t instanceof TupleType ); 
    671671    } 
    672672 
    673673    public static int getTupleTypeSize(Type t) { 
    674         if ( isTupleType(t) ) 
    675             return ((TupleType)t).getElements().size(); 
    676         else { 
    677             bug("TupleType expected, but got " + t); 
    678             return 0; 
    679         } 
     674        if ( isTupleType(t) ) 
     675            return ((TupleType)t).getElements().size(); 
     676        else { 
     677            bug("TupleType expected, but got " + t); 
     678            return 0; 
     679        } 
    680680    } 
    681681 
    682682    public static Type getTupleTypeElem(Type t, int i) { 
    683         if ( isTupleType(t) ) 
    684             return ((TupleType)t).getElements().get(i); 
    685         else 
    686             return bug("TupleType expected, but got " + t); 
     683        if ( isTupleType(t) ) 
     684            return ((TupleType)t).getElements().get(i); 
     685        else 
     686            return bug("TupleType expected, but got " + t); 
    687687    } 
    688688 
    689689    public static boolean differentArity(TupleType first, TupleType second) { 
    690         return ( isVoidType(first) && ! isVoidType(second) ) || 
    691                ( isVoidType(second) && ! isVoidType(first) ) || 
    692                ( first.getVarargs().isNone()   && second.getVarargs().isNone() && 
    693                 first.getKeywords().isEmpty() && second.getKeywords().isEmpty() && 
    694                 first.getElements().size() != second.getElements().size() ); 
     690        return ( isVoidType(first) && ! isVoidType(second) ) || 
     691               ( isVoidType(second) && ! isVoidType(first) ) || 
     692               ( first.getVarargs().isNone()   && second.getVarargs().isNone() && 
     693                first.getKeywords().isEmpty() && second.getKeywords().isEmpty() && 
     694                first.getElements().size() != second.getElements().size() ); 
    695695    } 
    696696 
    697697    /* for Param ***********************************************************/ 
    698698    public static boolean isMultifix(List<Param> params) { 
    699         for (Param p : params) { 
    700             if ( isVarargsParam(p) ) 
    701                 return true; 
    702         } 
    703         return (params.size() > 2); 
     699        for (Param p : params) { 
     700            if ( isVarargsParam(p) ) 
     701                return true; 
     702        } 
     703        return (params.size() > 2); 
    704704    } 
    705705 
    706706    public static boolean isMutable(Param p) { 
    707         return p.getMods().isMutable(); 
     707        return p.getMods().isMutable(); 
    708708    } 
    709709 
    710710    public final static NodeVisitor<String> nameSuffixGetter = 
    711         new NodeAbstractVisitor<String>() { 
    712         @Override public String forAPIName(APIName n) { 
    713             return n.getText(); 
    714             } 
    715         public String forId(Id n) { 
    716             return n.getText(); 
    717         } 
    718         public String forOp(Op n) { 
    719             if ( n.isEnclosing() ) 
    720                 return n.getText(); 
    721             else return OprUtil.fixityDecorator(n.getFixity(), n.getText()); 
    722         } 
    723         public String forAnonymousFnName(AnonymousFnName n) { 
    724             return getSpan(n).toString(); 
    725         } 
     711        new NodeAbstractVisitor<String>() { 
     712        @Override public String forAPIName(APIName n) { 
     713            return n.getText(); 
     714            } 
     715        public String forId(Id n) { 
     716            return n.getText(); 
     717        } 
     718        public String forOp(Op n) { 
     719            if ( n.isEnclosing() ) 
     720                return n.getText(); 
     721            else return OprUtil.fixityDecorator(n.getFixity(), n.getText()); 
     722        } 
     723        public String forAnonymousFnName(AnonymousFnName n) { 
     724            return getSpan(n).toString(); 
     725        } 
    726726    }; 
    727727 
    728728    public static String nameSuffixString(AbstractNode n) { 
    729         return n.accept(nameSuffixGetter); 
     729        return n.accept(nameSuffixGetter); 
    730730    } 
    731731 
    732732    private final static NodeVisitor<String> nameGetter = 
    733         new NodeAbstractVisitor<String>() { 
    734  
    735         @Override public String forAPIName(APIName n) { 
    736             return n.getText(); 
    737             } 
    738         @Override public String forIdOrOpOrAnonymousName(IdOrOpOrAnonymousName n) { 
    739             return nameString(n); 
    740             } 
    741         public String forId(Id n) { 
    742             final String last = n.getText(); 
    743             Option<APIName> odn = n.getApiName(); 
    744             return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 
    745         } 
    746         public String forOp(Op n) { 
    747             if ( n.isEnclosing() ) { 
    748                 Option<APIName> odn = n.getApiName(); 
    749                 String last = n.getText(); 
    750                 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 
    751             } else { 
    752                 Option<APIName> odn = n.getApiName(); 
    753                 String last = OprUtil.fixityDecorator(n.getFixity(), n.getText()); 
    754                 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 
    755             } 
    756         } 
    757         public String forAnonymousFnName(AnonymousFnName n) { 
    758             return getSpan(n).toString(); 
    759         } 
    760         public String forConstructorFnName(ConstructorFnName n) { 
    761             // TODO Auto-generated method stub 
    762             return nameString(n); 
    763         } 
     733        new NodeAbstractVisitor<String>() { 
     734 
     735        @Override public String forAPIName(APIName n) { 
     736            return n.getText(); 
     737            } 
     738        @Override public String forIdOrOpOrAnonymousName(IdOrOpOrAnonymousName n) { 
     739            return nameString(n); 
     740            } 
     741        public String forId(Id n) { 
     742            final String last = n.getText(); 
     743            Option<APIName> odn = n.getApiName(); 
     744            return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 
     745        } 
     746        public String forOp(Op n) { 
     747            if ( n.isEnclosing() ) { 
     748                Option<APIName> odn = n.getApiName(); 
     749                String last = n.getText(); 
     750                return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 
     751            } else { 
     752                Option<APIName> odn = n.getApiName(); 
     753                String last = OprUtil.fixityDecorator(n.getFixity(), n.getText()); 
     754                return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 
     755            } 
     756        } 
     757        public String forAnonymousFnName(AnonymousFnName n) { 
     758            return getSpan(n).toString(); 
     759        } 
     760        public String forConstructorFnName(ConstructorFnName n) { 
     761            // TODO Auto-generated method stub 
     762            return nameString(n); 
     763        } 
    764764    }; 
    765765 
    766766    public static Modifiers getMods(LValue f) { 
    767         return f.getMods(); 
     767        return f.getMods(); 
    768768    } 
    769769 
    770770    /* nameString *************************************************************/ 
    771771    public static String nameString(Name n) { 
    772         return n.accept(nameGetter); 
     772        return n.accept(nameGetter); 
    773773    } 
    774774 
    775775    public static String nameString(IdOrOpOrAnonymousName n) { 
    776         return n.accept(nameGetter); 
     776        return n.accept(nameGetter); 
    777777    } 
    778778 
    779779    public static String nameString(APIName n) { 
    780         return n.getText(); 
     780        return n.getText(); 
    781781//        Iterable<String> ns = IterUtil.map(n.getIds(), IdToStringFn); 
    782782//      return IterUtil.toString(ns, "", ".", ""); 
     
    784784 
    785785    public static String dirString(APIName n) { 
    786         Iterable<String> ns = IterUtil.map(n.getIds(), IdToStringFn); 
    787         // NOT File.separator -- that is unnecessary and confusing. 
    788         return IterUtil.toString(ns, "", "/", ""); 
     786        Iterable<String> ns = IterUtil.map(n.getIds(), IdToStringFn); 
     787        // NOT File.separator -- that is unnecessary and confusing. 
     788        return IterUtil.toString(ns, "", "/", ""); 
    789789    } 
    790790 
    791791    public static String shortNameString(Id n) { 
    792         final String last = n.getText(); 
    793         Option<APIName> odn = n.getApiName(); 
    794         if (odn.isSome()) { 
    795             APIName _odn = odn.unwrap(); 
    796             if (_odn.getText().equals(WellKnownNames.fortressBuiltin()) 
    797                 || _odn.getText().equals(WellKnownNames.fortressLibrary())) { 
    798                 return last; 
    799             } else { 
    800                 return nameString(odn.unwrap()) + "." + last; 
    801             } 
    802         } else { 
    803             return last; 
    804         } 
     792        final String last = n.getText(); 
     793        Option<APIName> odn = n.getApiName(); 
     794        if (odn.isSome()) { 
     795            APIName _odn = odn.unwrap(); 
     796            if (_odn.getText().equals(WellKnownNames.fortressBuiltin()) 
     797                || _odn.getText().equals(WellKnownNames.fortressLibrary())) { 
     798                return last; 
     799            } else { 
     800                return nameString(odn.unwrap()) + "." + last; 
     801            } 
     802        } else { 
     803            return last; 
     804        } 
    805805    } 
    806806 
    807807    public static String nameString(Id n) { 
    808         final String last = n.getText(); 
    809         Option<APIName> odn = n.getApiName(); 
    810         return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 
     808        final String last = n.getText(); 
     809        Option<APIName> odn = n.getApiName(); 
     810        return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 
    811811    } 
    812812 
    813813    public static String nameString(Op n) { 
    814         if ( n.isEnclosing() ) 
    815             return n.getText(); 
    816         else return OprUtil.fixityDecorator(n.getFixity(), n.getText()); 
     814        if ( n.isEnclosing() ) 
     815            return n.getText(); 
     816        else return OprUtil.fixityDecorator(n.getFixity(), n.getText()); 
    817817    } 
    818818    public static String nameString(AnonymousFnName n) { 
    819         return getSpan(n).toString(); 
     819        return getSpan(n).toString(); 
    820820    } 
    821821    public static String nameString(ConstructorFnName n) { 
    822         // TODO Auto-generated method stub 
    823         return stringName(n.getConstructor()); 
     822        // TODO Auto-generated method stub 
     823        return stringName(n.getConstructor()); 
    824824    } 
    825825 
    826826    private static final Fn<Name, String> NameToStringFn = new Fn<Name, String>() { 
    827         public String apply(Name n) { return nameString(n); } 
     827        public String apply(Name n) { return nameString(n); } 
    828828    }; 
    829829 
    830830    public static String namesString(Iterable<? extends Name> names) { 
    831         return IterUtil.toString(IterUtil.map(names, NameToStringFn), "", ", ", ""); 
     831        return IterUtil.toString(IterUtil.map(names, NameToStringFn), "", ", ", ""); 
    832832    } 
    833833 
    834834    /* getName *************************************************************/ 
    835835    public static String getName(StaticParam param) { 
    836         if ( isOpParam(param) ) 
    837             return nameString(param.getName()); 
    838         else 
    839             return param.getName().getText(); 
     836        if ( isOpParam(param) ) 
     837            return nameString(param.getName()); 
     838        else 
     839            return param.getName().getText(); 
    840840    } 
    841841 
    842842    private final static NodeAbstractVisitor<String> stringNameVisitor = 
    843         new NodeAbstractVisitor<String>() { 
    844         @Override 
    845             public String forId(Id that) { 
    846                 return that.getText(); 
    847             } 
    848             @Override 
    849             public String forOp(Op that) { 
    850                 if ( that.isEnclosing() ) 
    851                     return that.getText(); 
    852                 else return OprUtil.fixityDecorator(that.getFixity(), that.getText()); 
    853             } 
    854             @Override 
    855         public String forDimDecl(DimDecl node) { 
    856             return nameString(node.getDimId()); 
    857         } 
    858             @Override 
    859         public String forUnitDecl(UnitDecl node) { 
    860             List<Id> ids = node.getUnits(); 
    861             if (ids.size() < 1) 
    862                 return bug("Unit declarations should have a name."); 
    863             else return nameString(ids.get(0)); 
    864         } 
    865             @Override 
    866         public String forFnDecl(FnDecl node) { 
    867             return nameString(getName(node)); 
    868         } 
    869             @Override 
    870         public String forIdOrOpOrAnonymousName(IdOrOpOrAnonymousName node) { 
    871             return nameString(node); 
    872         } 
    873             @Override 
    874         public String forObjectDecl(ObjectDecl node) { 
    875             return getName(node).getText(); 
    876         } 
    877             @Override 
    878         public String for_RewriteObjectExpr(_RewriteObjectExpr node) { 
    879             return node.getGenSymName(); 
    880         } 
    881             @Override 
    882         public String forTraitDecl(TraitDecl node) { 
    883             return getName(node).getText(); 
    884         } 
    885             @Override 
    886         public String forTypeAlias(TypeAlias node) { 
    887             return node.getName().getText(); 
    888         } 
    889             @Override 
    890         public String forOpRef(OpRef node) { 
    891             return node.getOriginalName().accept(this); 
    892         } 
    893             @Override 
    894         public String forVarRef(VarRef node) { 
    895             return node.getVarId().accept(this); 
    896         } 
    897  
    898             @Override 
    899         public String defaultCase(Node node) { 
    900             return node.getClass().getSimpleName(); 
    901         } 
     843        new NodeAbstractVisitor<String>() { 
     844        @Override 
     845            public String forId(Id that) { 
     846                return that.getText(); 
     847            } 
     848            @Override 
     849            public String forOp(Op that) { 
     850                if ( that.isEnclosing() ) 
     851                    return that.getText(); 
     852                else return OprUtil.fixityDecorator(that.getFixity(), that.getText()); 
     853            } 
     854            @Override 
     855        public String forDimDecl(DimDecl node) { 
     856            return nameString(node.getDimId()); 
     857        } 
     858            @Override 
     859        public String forUnitDecl(UnitDecl node) { 
     860            List<Id> ids = node.getUnits(); 
     861            if (ids.size() < 1) 
     862                return bug("Unit declarations should have a name."); 
     863            else return nameString(ids.get(0)); 
     864        } 
     865            @Override 
     866        public String forFnDecl(FnDecl node) { 
     867            return nameString(getName(node)); 
     868        } 
     869            @Override 
     870        public String forIdOrOpOrAnonymousName(IdOrOpOrAnonymousName node) { 
     871            return nameString(node); 
     872        } 
     873            @Override 
     874        public String forObjectDecl(ObjectDecl node) { 
     875            return getName(node).getText(); 
     876        } 
     877            @Override 
     878        public String for_RewriteObjectExpr(_RewriteObjectExpr node) { 
     879            return node.getGenSymName(); 
     880        } 
     881            @Override 
     882        public String forTraitDecl(TraitDecl node) { 
     883            return getName(node).getText(); 
     884        } 
     885            @Override 
     886        public String forTypeAlias(TypeAlias node) { 
     887            return node.getName().getText(); 
     888        } 
     889            @Override 
     890        public String forOpRef(OpRef node) { 
     891            return node.getOriginalName().accept(this); 
     892        } 
     893            @Override 
     894        public String forVarRef(VarRef node) { 
     895            return node.getVarId().accept(this); 
     896        } 
     897 
     898            @Override 
     899        public String defaultCase(Node node) { 
     900            return node.getClass().getSimpleName(); 
     901        } 
    902902    }; 
    903903 
     
    905905    /* stringName **********************************************************/ 
    906906    public static String stringName(Node the_node) { 
    907         return the_node.accept(stringNameVisitor); 
     907        return the_node.accept(stringNameVisitor); 
    908908    } 
    909909 
    910910    /* stringNames *********************************************************/ 
    911911    public static IterableOnce<String> stringNames(LValue lv) { 
    912         return new UnitIterable<String>(lv.getName().getText()); 
     912        return new UnitIterable<String>(lv.getName().getText()); 
    913913    } 
    914914 
    915915    public static IterableOnce<String> stringNames(Decl decl) { 
    916         return decl.accept(new NodeAbstractVisitor<IterableOnce<String>>() { 
    917             public IterableOnce<String> forDimDecl(DimDecl d) { 
    918                 return new UnitIterable<String>(d.getDimId().getText()); 
    919             } 
    920             public IterableOnce<String> forUnitDecl(UnitDecl d) { 
    921             List<Id> ids = d.getUnits(); 
    922             if (ids.size() < 1) 
    923                 return bug("Unit declarations should have a name."); 
    924             else return new UnitIterable<String>(nameString(ids.get(0))); 
    925             } 
    926             public IterableOnce<String> forFnExpr(FnExpr d) { 
    927                 return new UnitIterable<String>(nameString(d.getHeader().getName())); 
    928             } 
    929             public IterableOnce<String> forFnDecl(FnDecl d) { 
    930                 return new UnitIterable<String>(nameString(getName(d))); 
    931             } 
    932             public IterableOnce<String> forLetFn(LetFn d) { 
    933                 return new UnitIterable<String>(d.getClass().getSimpleName()); 
    934             } 
    935             public IterableOnce<String> forLocalVarDecl(LocalVarDecl d) { 
    936                 return new IterableOnceForLValueList(d.getLhs()); 
    937             } 
    938             public IterableOnce<String> forObjectDecl(ObjectDecl d) { 
    939                 return new UnitIterable<String>(getName(d).getText()); 
    940             } 
    941             public IterableOnce<String> for_RewriteObjectExpr(_RewriteObjectExpr d) { 
    942                 return new UnitIterable<String>(d.getGenSymName()); 
    943             } 
    944             public IterableOnce<String> forPropertyDecl(PropertyDecl d) { 
    945                 return d.getName().apply(new OptionVisitor<Id, IterableOnce<String>>() { 
    946                     public IterableOnce<String> forSome(Id name) { 
    947                         return new UnitIterable<String>(name.getText()); 
    948                     } 
    949                     public IterableOnce<String> forNone() { 
    950                         return new UnitIterable<String>("_"); 
    951                     } 
    952                 }); 
    953             } 
    954             public IterableOnce<String> forTestDecl(TestDecl d) { 
    955                 return new UnitIterable<String>(d.getName().getText()); 
    956             } 
    957             public IterableOnce<String> forTraitDecl(TraitDecl d) { 
    958                 return new UnitIterable<String>(getName(d).getText()); 
    959             } 
    960             public IterableOnce<String> forTypeAlias(TypeAlias d) { 
    961                 return new UnitIterable<String>(d.getName().getText()); 
    962             } 
    963             public IterableOnce<String> forVarDecl(VarDecl d) { 
    964                 return new IterableOnceForLValueList(d.getLhs()); 
    965             } 
    966             public IterableOnce<String> forGrammarDecl(GrammarDecl d) { 
    967                 return new UnitIterable<String>(d.getName().getText()); 
    968             } 
    969             public IterableOnce<String> for_RewriteFnOverloadDecl(_RewriteFnOverloadDecl d) { 
    970                 return new UnitIterable<String>(nameString(d.getName())); 
    971             } 
    972         }); 
     916        return decl.accept(new NodeAbstractVisitor<IterableOnce<String>>() { 
     917            public IterableOnce<String> forDimDecl(DimDecl d) { 
     918                return new UnitIterable<String>(d.getDimId().getText()); 
     919            } 
     920            public IterableOnce<String> forUnitDecl(UnitDecl d) { 
     921            List<Id> ids = d.getUnits(); 
     922            if (ids.size() < 1) 
     923                return bug("Unit declarations should have a name."); 
     924            else return new UnitIterable<String>(nameString(ids.get(0))); 
     925            } 
     926            public IterableOnce<String> forFnExpr(FnExpr d) { 
     927                return new UnitIterable<String>(nameString(d.getHeader().getName())); 
     928            } 
     929            public IterableOnce<String> forFnDecl(FnDecl d) { 
     930                return new UnitIterable<String>(nameString(getName(d))); 
     931            } 
     932            public IterableOnce<String> forLetFn(LetFn d) { 
     933                return new UnitIterable<String>(d.getClass().getSimpleName()); 
     934            } 
     935            public IterableOnce<String> forLocalVarDecl(LocalVarDecl d) { 
     936                return new IterableOnceForLValueList(d.getLhs()); 
     937            } 
     938            public IterableOnce<String> forObjectDecl(ObjectDecl d) { 
     939                return new UnitIterable<String>(getName(d).getText()); 
     940            } 
     941            public IterableOnce<String> for_RewriteObjectExpr(_RewriteObjectExpr d) { 
     942                return new UnitIterable<String>(d.getGenSymName()); 
     943            } 
     944            public IterableOnce<String> forPropertyDecl(PropertyDecl d) { 
     945                return d.getName().apply(new OptionVisitor<Id, IterableOnce<String>>() { 
     946                    public IterableOnce<String> forSome(Id name) { 
     947                        return new UnitIterable<String>(name.getText()); 
     948                    } 
     949                    public IterableOnce<String> forNone() { 
     950                        return new UnitIterable<String>("_"); 
     951                    } 
     952                }); 
     953            } 
     954            public IterableOnce<String> forTestDecl(TestDecl d) { 
     955                return new UnitIterable<String>(d.getName().getText()); 
     956            } 
     957            public IterableOnce<String> forTraitDecl(TraitDecl d) { 
     958                return new UnitIterable<String>(getName(d).getText()); 
     959            } 
     960            public IterableOnce<String> forTypeAlias(TypeAlias d) { 
     961                return new UnitIterable<String>(d.getName().getText()); 
     962            } 
     963            public IterableOnce<String> forVarDecl(VarDecl d) { 
     964                return new IterableOnceForLValueList(d.getLhs()); 
     965            } 
     966            public IterableOnce<String> forGrammarDecl(GrammarDecl d) { 
     967                return new UnitIterable<String>(d.getName().getText()); 
     968            } 
     969            public IterableOnce<String> for_RewriteFnOverloadDecl(_RewriteFnOverloadDecl d) { 
     970                return new UnitIterable<String>(nameString(d.getName())); 
     971            } 
     972        }); 
    973973    } 
    974974 
    975975    /* dump ****************************************************************/ 
    976976    public static String dump(AbstractNode n) { 
    977         try { 
    978             StringBuffer sb = new StringBuffer(); 
    979             dump(sb, n); 
    980             return sb.toString(); 
    981         } catch (Throwable ex) { 
    982             return "Exception " + ex + " during dump"; 
    983         } 
     977        try { 
     978            StringBuffer sb = new StringBuffer(); 
     979            dump(sb, n); 
     980            return sb.toString(); 
     981        } catch (Throwable ex) { 
     982            return "Exception " + ex + " during dump"; 
     983        } 
    984984    } 
    985985 
     
    988988     */ 
    989989    public static void dump(Appendable appendable, AbstractNode n) throws IOException { 
    990         Printer p = new Printer(true, true, true); 
    991         p.dump(n, appendable, 0); 
     990        Printer p = new Printer(true, true, true); 
     991        p.dump(n, appendable, 0); 
    992992    } 
    993993 
    994994    public static <T> T NYI(String s) { 
    995         return (T)bug("AST." + s + " NYI"); 
     995        return (T)bug("AST." + s + " NYI"); 
    996996    } 
    997997 
    998998    /* Boolean functions for FnDecls. */ 
    999999    public static boolean isGetter(FnDecl decl) { 
    1000         return getMods(decl).isGetter(); 
     1000        return getMods(decl).isGetter(); 
    10011001    } 
    10021002 
    10031003    public static boolean isSetter(FnDecl decl) { 
    1004         return getMods(decl).isSetter(); 
     1004        return getMods(decl).isSetter(); 
    10051005    } 
    10061006 
    10071007    public static boolean isOp(FnDecl decl) { 
    1008         return getName(decl) instanceof Op; 
     1008        return getName(decl) instanceof Op; 
    10091009    } 
    10101010 
    10111011    /* for APIName ******************************************************/ 
    10121012    private static final Fn<Id, String> IdToStringFn = new Fn<Id, String>() { 
    1013         public String apply(Id x) { 
    1014             return stringName(x); 
    1015         } 
     1013        public String apply(Id x) { 
     1014            return stringName(x); 
     1015        } 
    10161016    }; 
    10171017 
    10181018    public static List<String> toStrings(APIName n) { 
    1019         return Useful.applyToAll(n.getIds(), IdToStringFn); 
     1019        return Useful.applyToAll(n.getIds(), IdToStringFn); 
    10201020    } 
    10211021 
    10221022    /* for TraitTypeWhere **************************************************/ 
    10231023    public static List<BaseType> getTypes(List<TraitTypeWhere> l) { 
    1024         List<BaseType> t = new ArrayList<BaseType>(l.size()); 
    1025         for (TraitTypeWhere tw : l) { 
    1026             t.add(tw.getBaseType()); 
    1027         } 
    1028         return t; 
     1024        List<BaseType> t = new ArrayList<BaseType>(l.size()); 
     1025        for (TraitTypeWhere tw : l) { 
     1026            t.add(tw.getBaseType()); 
     1027        } 
     1028        return t; 
    10291029    } 
    10301030 
    10311031    /* for Type and StaticExpr **********************************************/ 
    10321032    public static void validTraitTypes(BufferedWriter writer, 
    1033                                        List<? extends BaseType> types) { 
    1034         for (BaseType ty: types) { 
    1035             if ( ty instanceof NamedType && 
    1036                 validOp(((NamedType)ty).getName().getText()) ) 
    1037                 log(writer, getSpan(ty), "Operator name, " + 
    1038                     ((NamedType)ty).getName().getText() + 
    1039                     ", is not a valid type name."); 
    1040         } 
     1033                                       List<? extends BaseType> types) { 
     1034        for (BaseType ty: types) { 
     1035            if ( ty instanceof NamedType && 
     1036                validOp(((NamedType)ty).getName().getText()) ) 
     1037                log(writer, getSpan(ty), "Operator name, " + 
     1038                    ((NamedType)ty).getName().getText() + 
     1039                    ", is not a valid type name."); 
     1040        } 
    10411041    } 
    10421042 
    10431043    public static void validTraitTypeWheres(BufferedWriter writer, 
    1044                                             List<TraitTypeWhere> types) { 
    1045         for (TraitTypeWhere typ: types) { 
    1046             BaseType ty = typ.getBaseType(); 
    1047             if ( ty instanceof NamedType && 
    1048                 validOp(((NamedType)ty).getName().getText()) ) 
    1049                 log(writer, getSpan(ty), "Operator name, " + 
    1050                     ((NamedType)ty).getName().getText() + 
    1051                     ", is not a valid type name."); 
    1052         } 
     1044                                            List<TraitTypeWhere> types) { 
     1045        for (TraitTypeWhere typ: types) { 
     1046            BaseType ty = typ.getBaseType(); 
     1047            if ( ty instanceof NamedType && 
     1048                validOp(((NamedType)ty).getName().getText()) ) 
     1049                log(writer, getSpan(ty), "Operator name, " + 
     1050                    ((NamedType)ty).getName().getText() + 
     1051                    ", is not a valid type name."); 
     1052        } 
    10531053    } 
    10541054 
    10551055    public static boolean isExponentiation(Type type) { 
    1056         return (type instanceof ArrayType || 
    1057                 type instanceof MatrixType || 
    1058                 type instanceof DimExponent); 
     1056        return (type instanceof ArrayType || 
     1057                type instanceof MatrixType || 
     1058                type instanceof DimExponent); 
    10591059    } 
    10601060    public static boolean isExponentiation(IntExpr staticExpr) { 
    1061         return (staticExpr instanceof IntBinaryOp && 
    1062                 ((IntBinaryOp)staticExpr).getOp().getText().equals("^")); 
     1061        return (staticExpr instanceof IntBinaryOp && 
     1062                ((IntBinaryOp)staticExpr).getOp().getText().equals("^")); 
    10631063    } 
    10641064 
    10651065    public static String nameString(BoolRef vre) { 
    1066         return nameString(vre.getName()); 
     1066        return nameString(vre.getName()); 
    10671067    } 
    10681068    public static String nameString(IntRef vre) { 
    1069         return nameString(vre.getName()); 
     1069        return nameString(vre.getName()); 
    10701070    } 
    10711071 
    10721072    /* for Literals ********************************************************/ 
    10731073    public static boolean validRadix(BufferedWriter writer, 
    1074                                      Span span, String radix) { 
    1075         String[] all = new String[]{"2","3","4","5","6","7","8","9","10", 
    1076                                     "11","12","13","14","15","16"}; 
    1077         List<String> validRadix = new LinkedList<String>(java.util.Arrays.asList(all)); 
    1078         if (! validRadix.contains( radix )) { 
    1079             log(writer, span, "Syntax Error: the radix of " + 
    1080                 "a numeral must be an integer from 2 to 16."); 
    1081             return false; 
    1082         } else return true; 
     1074                                     Span span, String radix) { 
     1075        String[] all = new String[]{"2","3","4","5","6","7","8","9","10", 
     1076                                    "11","12","13","14","15","16"}; 
     1077        List<String> validRadix = new LinkedList<String>(java.util.Arrays.asList(all)); 
     1078        if (! validRadix.contains( radix )) { 
     1079            log(writer, span, "Syntax Error: the radix of " + 
     1080                "a numeral must be an integer from 2 to 16."); 
     1081            return false; 
     1082        } else return true; 
    10831083    } 
    10841084 
    10851085    public static boolean validIntLiteral(String numeral) { 
    1086         for (int index = 0; index < numeral.length(); index++) { 
    1087             if (numeral.charAt(index) == '.') 
    1088                 return false; 
    1089         } 
    1090         return true; 
     1086        for (int index = 0; index < numeral.length(); index++) { 
     1087            if (numeral.charAt(index) == '.') 
     1088                return false; 
     1089        } 
     1090        return true; 
    10911091    } 
    10921092 
    10931093    public static void validNumericLiteral(BufferedWriter writer, 
    1094                                            Span span, String numeral) { 
    1095         int numberOfDots = 0; 
    1096         for (int index = 0; index < numeral.length(); index++) { 
    1097             char c = numeral.charAt(index); 
    1098             if (Character.isLetter(c)) 
    1099                 log(writer, span, "Syntax Error: a numeral contains " + 
    1100                     "letters and does not have a radix specifier."); 
    1101             if (c == '.') numberOfDots++; 
    1102         } 
    1103         if (numberOfDots > 1) 
    1104             log(writer, span, "Syntax Error: a numeral contains more " + 
    1105                 "than one `.' character."); 
     1094                                           Span span, String numeral) { 
     1095        int numberOfDots = 0; 
     1096        for (int index = 0; index < numeral.length(); index++) { 
     1097            char c = numeral.charAt(index); 
     1098            if (Character.isLetter(c)) 
     1099                log(writer, span, "Syntax Error: a numeral contains " + 
     1100                    "letters and does not have a radix specifier."); 
     1101            if (c == '.') numberOfDots++; 
     1102        } 
     1103        if (numberOfDots > 1) 
     1104            log(writer, span, "Syntax Error: a numeral contains more " + 
     1105                "than one `.' character."); 
    11061106    } 
    11071107 
    11081108    public static void validNumericLiteral(BufferedWriter writer, 
    1109                                            Span span, String numeral, 
    1110                                            String radix) { 
    1111         int radixNumber = radix2Number(radix); 
    1112         if (radixNumber == -1) 
    1113             log(writer, span, "Syntax Error: the radix of " + 
    1114                 "a numeral should be an integer from 2 to 16."); 
    1115         boolean sawUpperCase = false; 
    1116         boolean sawLowerCase = false; 
    1117         boolean sawAb = false; 
    1118         boolean sawXe = false; 
    1119         int numberOfDots = 0; 
    1120         for (int index = 0; index < numeral.length(); index++) { 
    1121             char c = numeral.charAt(index); 
    1122             if (c == '.') numberOfDots++; 
    1123             if (Character.isUpperCase(c)) { 
    1124                 if (sawLowerCase) 
    1125                     log(writer, span, "Syntax Error: a numeral " + 
    1126                         "contains both uppercase and lowercase letters."); 
    1127                 else sawUpperCase = true; 
    1128             } else if (Character.isLowerCase(c)) { 
    1129                 if (sawUpperCase) 
    1130                     log(writer, span, "Syntax Error: a numeral " + 
    1131                         "contains both uppercase and lowercase letters."); 
    1132                 else sawLowerCase = true; 
    1133             } 
    1134             if (radixNumber == 12) { 
    1135                 if (!validDigitOrLetterIn12(c) 
    1136                     && c != '.' && c != '\'' && c != '\u202F') { 
     1109                                           Span span, String numeral, 
     1110                                           String radix) { 
     1111        int radixNumber = radix2Number(radix); 
     1112        if (radixNumber == -1) 
     1113            log(writer, span, "Syntax Error: the radix of " + 
     1114                "a numeral should be an integer from 2 to 16."); 
     1115        boolean sawUpperCase = false; 
     1116        boolean sawLowerCase = false; 
     1117        boolean sawAb = false; 
     1118        boolean sawXe = false; 
     1119        int numberOfDots = 0; 
     1120        for (int index = 0; index < numeral.length(); index++) { 
     1121            char c = numeral.charAt(index); 
     1122            if (c == '.') numberOfDots++; 
     1123            if (Character.isUpperCase(c)) { 
     1124                if (sawLowerCase) 
     1125                    log(writer, span, "Syntax Error: a numeral " + 
     1126                        "contains both uppercase and lowercase letters."); 
     1127                else sawUpperCase = true; 
     1128            } else if (Character.isLowerCase(c)) { 
     1129                if (sawUpperCase) 
     1130                    log(writer, span, "Syntax Error: a numeral " + 
     1131                        "contains both uppercase and lowercase letters."); 
     1132                else sawLowerCase = true; 
     1133            } 
     1134            if (radixNumber == 12) { 
     1135                if (!validDigitOrLetterIn12(c) 
     1136                    && c != '.' && c != '\'' && c != '\u202F') { 
    11371137    log(writer, span, "Syntax Error: a numeral " + 
    1138                         "has radix 12 and contains letters other " + 
    1139                         "than A, B, X, E, a, b, x or e."); 
    1140                 } 
    1141                 if (c == 'A' || c == 'a' || c == 'B' || c == 'b') { 
    1142                     if (sawXe) 
    1143                         log(writer, span, "Syntax Error: a numeral " + 
    1144                             "has radix 12 and contains at least one " + 
    1145                             "A, B, a or b and at least one X, E, x or e."); 
    1146                     else sawAb = true; 
    1147                 } else if (c == 'X' || c == 'x' || c == 'E' || c == 'e') { 
    1148                     if (sawAb) 
    1149                         log(writer, span, "Syntax Error: a numeral " + 
    1150                             "has radix 12 and contains at least one " + 
    1151                             "A, B, a or b and at least one X, E, x or e."); 
    1152                     else sawXe = true; 
    1153                 } 
    1154             } 
    1155             // The numeral has a radix other than 12. 
    1156             else if (!validDigitOrLetter(c, radixNumber) 
    1157                      && c != '.' && c != '\'' && c != '\u202F') { 
    1158                 log(writer, span, "Syntax Error: a numeral has a radix " + 
    1159                     "specifier and contains a digit or letter that " + 
    1160                     "denotes a value greater than or equal to the " + 
    1161                     "numeral's radix."); 
    1162             } 
    1163         } 
    1164         if (numberOfDots > 1) 
    1165             log(writer, span, "Syntax Error: a numeral contains more " + 
    1166                 "than one `.' character."); 
     1138                        "has radix 12 and contains letters other " + 
     1139                        "than A, B, X, E, a, b, x or e."); 
     1140                } 
     1141                if (c == 'A' || c == 'a' || c == 'B' || c == 'b') { 
     1142                    if (sawXe) 
     1143                        log(writer, span, "Syntax Error: a numeral " + 
     1144                            "has radix 12 and contains at least one " + 
     1145                            "A, B, a or b and at least one X, E, x or e."); 
     1146                    else sawAb = true; 
     1147                } else if (c == 'X' || c == 'x' || c == 'E' || c == 'e') { 
     1148                    if (sawAb) 
     1149                        log(writer, span, "Syntax Error: a numeral " + 
     1150                            "has radix 12 and contains at least one " + 
     1151                            "A, B, a or b and at least one X, E, x or e."); 
     1152                    else sawXe = true; 
     1153                } 
     1154            } 
     1155            // The numeral has a radix other than 12. 
     1156            else if (!validDigitOrLetter(c, radixNumber) 
     1157                     && c != '.' && c != '\'' && c != '\u202F') { 
     1158                log(writer, span, "Syntax Error: a numeral has a radix " + 
     1159                    "specifier and contains a digit or letter that " + 
     1160                    "denotes a value greater than or equal to the " + 
     1161                    "numeral's radix."); 
     1162            } 
     1163        } 
     1164        if (numberOfDots > 1) 
     1165            log(writer, span, "Syntax Error: a numeral contains more " + 
     1166                "than one `.' character."); 
    11671167    } 
    11681168 
    11691169    public static int radix2Number(String radix) { 
    1170         if (radix.equals("2") || radix.equals("TWO")) { 
    1171             return 2; 
    1172         } else if (radix.equals("3") || radix.equals("THREE")) { 
    1173             return 3; 
    1174         } else if (radix.equals("4") || radix.equals("FOUR")) { 
    1175             return 4; 
    1176         } else if (radix.equals("5") || radix.equals("FIVE")) { 
    1177             return 5; 
    1178         } else if (radix.equals("6") || radix.equals("SIX")) { 
    1179             return 6; 
    1180         } else if (radix.equals("7") || radix.equals("SEVEN")) { 
    1181             return 7; 
    1182         } else if (radix.equals("8") || radix.equals("EIGHT")) { 
    1183             return 8; 
    1184         } else if (radix.equals("9") || radix.equals("NINE")) { 
    1185             return 9; 
    1186         } else if (radix.equals("10") || radix.equals("TEN")) { 
    1187             return 10; 
    1188         } else if (radix.equals("11") || radix.equals("ELEVEN")) { 
    1189             return 11; 
    1190         } else if (radix.equals("12") || radix.equals("TWELVE")) { 
    1191             return 12; 
    1192         } else if (radix.equals("13") || radix.equals("THIRTEEN")) { 
    1193             return 13; 
    1194         } else if (radix.equals("14") || radix.equals("FOURTEEN")) { 
    1195             return 14; 
    1196         } else if (radix.equals("15") || radix.equals("FIFTEEN")) { 
    1197             return 15; 
    1198         } else if (radix.equals("16") || radix.equals("SIXTEEN")) { 
    1199             return 16; 
    1200         } else { 
    1201             /* radix is not valid. */ 
    1202             return -1; 
    1203         } 
     1170        if (radix.equals("2") || radix.equals("TWO")) { 
     1171            return 2; 
     1172        } else if (radix.equals("3") || radix.equals("THREE")) { 
     1173            return 3; 
     1174        } else if (radix.equals("4") || radix.equals("FOUR")) { 
     1175            return 4; 
     1176        } else if (radix.equals("5") || radix.equals("FIVE")) { 
     1177            return 5; 
     1178        } else if (radix.equals("6") || radix.equals("SIX")) { 
     1179            return 6; 
     1180        } else if (radix.equals("7") || radix.equals("SEVEN")) { 
     1181            return 7; 
     1182        } else if (radix.equals("8") || radix.equals("EIGHT")) { 
     1183            return 8; 
     1184        } else if (radix.equals("9") || radix.equals("NINE")) { 
     1185            return 9; 
     1186        } else if (radix.equals("10") || radix.equals("TEN")) { 
     1187            return 10; 
     1188        } else if (radix.equals("11") || radix.equals("ELEVEN")) { 
     1189            return 11; 
     1190        } else if (radix.equals("12") || radix.equals("TWELVE")) { 
     1191            return 12; 
     1192        } else if (radix.equals("13") || radix.equals("THIRTEEN")) { 
     1193            return 13; 
     1194        } else if (radix.equals("14") || radix.equals("FOURTEEN")) { 
     1195            return 14; 
     1196        } else if (radix.equals("15") || radix.equals("FIFTEEN")) { 
     1197            return 15; 
     1198        } else if (radix.equals("16") || radix.equals("SIXTEEN")) { 
     1199            return 16; 
     1200        } else { 
     1201            /* radix is not valid. */ 
     1202            return -1; 
     1203        } 
    12041204    } 
    12051205 
    12061206    private static boolean validDigitOrLetterIn12(char c) { 
    1207         if (Character.isLetter(c)) { 
    1208             switch (c) { 
    1209                 case 'A': 
    1210                 case 'a': 
    1211                 case 'B': 
    1212                 case 'b': 
    1213                 case 'X': 
    1214                 case 'x': 
    1215                 case 'E': 
    1216                 case 'e': { break; } 
    1217                 default: { 
    1218                     /* c is not valid in radix 12. */ 
    1219                     return false; 
    1220                 } 
    1221             } 
    1222         } 
    1223         return true; 
     1207        if (Character.isLetter(c)) { 
     1208            switch (c) { 
     1209                case 'A': 
     1210                case 'a': 
     1211                case 'B': 
     1212                case 'b': 
     1213                case 'X': 
     1214                case 'x': 
     1215                case 'E': 
     1216                case 'e': { break; } 
     1217                default: { 
     1218                    /* c is not valid in radix 12. */ 
     1219                    return false; 
     1220                } 
     1221            } 
     1222        } 
     1223        return true; 
    12241224    } 
    12251225 
    12261226    // radix is not 12. 
    12271227    private static boolean validDigitOrLetter(char c, int radix) { 
    1228         if ((radix < 10 && Character.digit(c, radix) > -1) || 
    1229             (radix >= 10 && Character.isDigit(c))) 
    1230             return true; 
    1231         switch (c) { 
    1232             case 'A': 
    1233             case 'a': { 
    1234                 if (radix <= 10) return false; 
    1235                 break; 
    1236             } 
    1237             case 'B': 
    1238             case 'b': { 
    1239                 if (radix <= 11) return false; 
    1240                 break; 
    1241             } 
    1242             case 'C': 
    1243             case 'c': { 
    1244                 if (radix <= 12) return false; 
    1245                 break; 
    1246             } 
    1247             case 'D': 
    1248             case 'd': { 
    1249                 if (radix <= 13) return false; 
    1250                 break; 
    1251             } 
    1252             case 'E': 
    1253             case 'e': { 
    1254                 if (radix <= 14) 
    1255                     return false; 
    1256                 break; 
    1257             } 
    1258             case 'F': 
    1259             case 'f': { 
    1260                 if (radix <= 15) return false; 
    1261                 break; 
    1262             } 
    1263             default: { 
    1264                 /* c is not valid in a numeral of the radix. */ 
    1265                 return false; 
    1266             } 
    1267         } 
    1268         return true; 
     1228        if ((radix < 10 && Character.digit(c, radix) > -1) || 
     1229            (radix >= 10 && Character.isDigit(c))) 
     1230            return true; 
     1231        switch (c) { 
     1232            case 'A': 
     1233            case 'a': { 
     1234                if (radix <= 10) return false; 
     1235                break; 
     1236            } 
     1237            case 'B': 
     1238            case 'b': { 
     1239                if (radix <= 11) return false; 
     1240                break; 
     1241            } 
     1242            case 'C': 
     1243            case 'c': { 
     1244                if (radix <= 12) return false; 
     1245                break; 
     1246            } 
     1247            case 'D': 
     1248            case 'd': { 
     1249                if (radix <= 13) return false; 
     1250                break; 
     1251            } 
     1252            case 'E': 
     1253            case 'e': { 
     1254                if (radix <= 14) 
     1255                    return false; 
     1256                break; 
     1257            } 
     1258            case 'F': 
     1259            case 'f': { 
     1260                if (radix <= 15) return false; 
     1261                break; 
     1262            } 
     1263            default: { 
     1264                /* c is not valid in a numeral of the radix. */ 
     1265                return false; 
     1266            } 
     1267        } 
     1268        return true; 
    12691269    } 
    12701270 
    12711271    public static void checkSubscriptedAssignment(BufferedWriter writer, Span span, 
    1272                                                   FnHeaderFront fhf, FnHeaderClause fhc) { 
    1273         if ( fhf.isSubscriptedAssignment && fhc.getReturnType().isSome() && 
    1274              ! isVoidType(fhc.getReturnType().unwrap()) ) 
    1275             log(writer, span, 
    1276                 "If a return type is given in a subscripted assignment operator declaration,\n    it must be ()."); 
     1272                                                  FnHeaderFront fhf, FnHeaderClause fhc) { 
     1273        if ( fhf.isSubscriptedAssignment && fhc.getReturnType().isSome() && 
     1274             ! isVoidType(fhc.getReturnType().unwrap()) ) 
     1275            log(writer, span, 
     1276                "If a return type is given in a subscripted assignment operator declaration,\n    it must be ()."); 
    12771277    } 
    12781278 
     
    12821282     */ 
    12831283    public static Modifiers checkModifiers(BufferedWriter writer, final Span span, 
    1284                                            List<Modifiers> mods) { 
    1285         Modifiers res = Modifiers.None; 
    1286         int index = 0; 
    1287         for (Modifiers mod : mods) { 
    1288             if ( mod.isAbstract() && index > 0 ) 
    1289                 log(writer, span, 
    1290                     "Modifier " + mod + " should come first."); 
    1291             if ( (mod.isGetter() || mod.isSetter()) && 
    1292                 index != mods.size()-1 ) 
    1293                 log(writer, span, 
    1294                     "Modifier " + mod + " should come last."); 
    1295             if (res.containsAny(mod)) { 
    1296                 log(writer, span, 
    1297                     "Modifier " + mod + " must not occur multiple times."); 
    1298             } 
    1299             res = res.combine(mod); 
    1300             index++; 
    1301         } 
    1302         return res; 
     1284                                           List<Modifiers> mods) { 
     1285        Modifiers res = Modifiers.None; 
     1286        int index = 0; 
     1287        for (Modifiers mod : mods) { 
     1288            if ( mod.isAbstract() && index > 0 ) 
     1289                log(writer, span, 
     1290                    "Modifier " + mod + " should come first."); 
     1291            if ( (mod.isGetter() || mod.isSetter()) && 
     1292                index != mods.size()-1 ) 
     1293                log(writer, span, 
     1294                    "Modifier " + mod + " should come last."); 
     1295            if (res.containsAny(mod)) { 
     1296                log(writer, span, 
     1297                    "Modifier " + mod + " must not occur multiple times."); 
     1298            } 
     1299            res = res.combine(mod); 
     1300            index++; 
     1301        } 
     1302        return res; 
    13031303    } 
    13041304 
    13051305    public static void checkNoWrapped(BufferedWriter writer, 
    1306                                       Option<List<Param>> optParams) { 
    1307         if ( optParams.isSome() ) { 
    1308             List<Param> params = optParams.unwrap(); 
    1309             for ( Param param : params ) { 
    1310                 if (param.getMods().isWrapped()) { 
    1311                     log(writer, getSpan(param), 
    1312                         "The modifier \"wrapped\" cannot " + 
    1313                         "appear in an API."); 
    1314                 } 
    1315             } 
    1316         } 
     1306                                      Option<List<Param>> optParams) { 
     1307        if ( optParams.isSome() ) { 
     1308            List<Param> params = optParams.unwrap(); 
     1309            for ( Param param : params ) { 
     1310                if (param.getMods().isWrapped()) { 
     1311                    log(writer, getSpan(param), 
     1312                        "The modifier \"wrapped\" cannot " + 
     1313                        "appear in an API."); 
     1314                } 
     1315            } 
     1316        } 
    13171317    } 
    13181318 
    13191319    /* true if there exists a self parameter in the parameter list of a given FnDecl */ 
    13201320    public static boolean isFunctionalMethod(FnDecl f) { 
    1321         for (Param p : getParams(f)) { 
    1322             if (p.getName().getText().equals("self")) return true; 
    1323         } 
    1324         return false; 
     1321        for (Param p : getParams(f)) { 
     1322            if (p.getName().getText().equals("self")) return true; 
     1323        } 
     1324        return false; 
    13251325    } 
    13261326 
    13271327    /* true if there exists a self parameter in a given parameter list */ 
    13281328    public static boolean isFunctionalMethod(List<Param> params) { 
    1329         for (Param p : params) { 
    1330             if (p.getName().getText().equals("self")) return true; 
    1331         } 
    1332         return false; 
     1329        for (Param p : params) { 
     1330            if (p.getName().getText().equals("self")) return true; 
     1331        } 
     1332        return false; 
    13331333    } 
    13341334 
    13351335    public static void validId(final BufferedWriter writer, Id name) { 
    1336         name.accept(new NodeDepthFirstVisitor_void(){ 
    1337             public void forIdOnly(Id id){ 
    1338                 if (id.getText().equals("outcome")) 
    1339                     log(writer, getSpan(id), 
    1340                         "Invalid variable name: 'outcome' is a reserved word."); 
    1341             } 
    1342  
    1343             public void defaultTemplateGap(TemplateGap g){ 
    1344                 /* nothing */ 
    1345             } 
    1346  
    1347             public void for_EllipsesIdOnly(_EllipsesId e){ 
    1348                 /* nothing */ 
    1349             } 
    1350         }); 
     1336        name.accept(new NodeDepthFirstVisitor_void(){ 
     1337            public void forIdOnly(Id id){ 
     1338                if (id.getText().equals("outcome")) 
     1339                    log(writer, getSpan(id), 
     1340                        "Invalid variable name: 'outcome' is a reserved word."); 
     1341            } 
     1342 
     1343            public void defaultTemplateGap(TemplateGap g){ 
     1344                /* nothing */ 
     1345            } 
     1346 
     1347            public void for_EllipsesIdOnly(_EllipsesId e){ 
     1348                /* nothing */ 
     1349            } 
     1350        }); 
    13511351    } 
    13521352 
    13531353    public static void validId(BufferedWriter writer, List<? extends LValue> lvs) { 
    1354         for (LValue lv : lvs) { 
    1355             validId(writer, lv.getName());