Changeset 4291

Show
Ignore:
Timestamp:
10/26/09 20:28:38 (4 weeks ago)
Author:
dr2chase
Message:

Unambiguous names enabled -- stack traces may look vile.

Location:
trunk/ProjectFortress
Files:
25 modified

Legend:

Unmodified
Added
Removed
  • trunk/ProjectFortress/astgen/Fortress.ast

    r4280 r4291  
    16731673             */ 
    16741674            Overloading(IdOrOp unambiguousName, 
    1675                         Option<Type> type); 
     1675                        Option<ArrowType> type); 
    16761676 
    16771677            /** syntactic abstraction nodes ************************************/ 
  • trunk/ProjectFortress/other_compiler_tests/Funmet1.fsi

    r4105 r4291  
    1919 
    2020trait T 
    21   me(self, x:ZZ32):ZZ32 
     21   me(self, x:ZZ32):ZZ32 
    2222end 
    2323 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/OverloadRewriteVisitor.java

    r4192 r4291  
    6969            if (rc != 0) 
    7070                return rc; 
    71             Option<Type> ot1 = o1.getType(); 
    72             Option<Type> ot2 = o2.getType(); 
     71            Option<ArrowType> ot1 = o1.getType(); 
     72            Option<ArrowType> ot2 = o2.getType(); 
    7373            if (ot1.isNone()) { 
    7474                if (ot2.isNone()) { 
     
    8080                return 1; 
    8181            } else { 
    82                 Type t1 = ot1.unwrap(); 
    83                 Type t2 = ot2.unwrap(); 
     82                ArrowType t1 = ot1.unwrap(); 
     83                ArrowType t2 = ot2.unwrap(); 
    8484                return NodeComparator.typeComparer.compare(t1, t2); 
    8585            } 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/codegen/CodeGen.java

    r4283 r4291  
    6262import com.sun.fortress.useful.Useful; 
    6363 
     64import edu.rice.cs.plt.collect.CollectUtil; 
     65import edu.rice.cs.plt.collect.Relation; 
     66 
    6467// Note we have a name clash with org.objectweb.asm.Type 
    6568// and com.sun.fortress.nodes.Type.  If anyone has a better 
     
    8083    private final FreeVariables fv; 
    8184    private final Map<IdOrOpOrAnonymousName, MultiMap<Integer, Function>> topLevelOverloads; 
     85    private final MultiMap<String, Function> exportedToUnambiguous; 
    8286    private Set<String> overloadedNamesAndSigs; 
    8387 
     
    116120        this.fv = c.fv; 
    117121        this.topLevelOverloads = c.topLevelOverloads; 
     122        this.exportedToUnambiguous = c.exportedToUnambiguous; 
    118123        this.overloadedNamesAndSigs = c.overloadedNamesAndSigs; 
    119124 
     
    142147        this.fv = fv; 
    143148        this.ci = ci; 
     149        this.exportedToUnambiguous = new MultiMap<String, Function> (); 
     150 
     151        /* 
     152         * Find every exported name, and make an entry mapping name to 
     153         * API declarations, so that unambiguous names from APIs can 
     154         * also be emitted. 
     155         */ 
     156        List<APIName> exports = c.getExports(); 
     157        for (APIName apiname:exports) { 
     158            ApiIndex api_index = env.api(apiname); 
     159            Relation<IdOrOpOrAnonymousName, Function> fns = api_index.functions(); 
     160            for (IdOrOpOrAnonymousName name : fns.firstSet()) { 
     161                if (name instanceof IdOrOp) { 
     162                    Set<Function> defs = fns.matchFirst(name); 
     163                    for (Function def : defs) { 
     164                        IdOrOpOrAnonymousName ua_name = def.unambiguousName(); 
     165                        if (ua_name instanceof IdOrOp) { 
     166                            IdOrOp ioo_name = (IdOrOp) name; 
     167                            IdOrOp ioo_ua_name = (IdOrOp) ua_name; 
     168                            if (! ioo_name.equals(ioo_ua_name)) { 
     169                                // Add mapping ioo_name -> def to MultiMap 
     170                                exportedToUnambiguous.putItem( 
     171                                        ioo_name.getText(), 
     172                                        def); 
     173                            } 
     174                        } 
     175                    } 
     176                } 
     177            } 
     178        } 
     179         
    144180        this.topLevelOverloads = 
    145181            sizePartitionedOverloads(ci.functions()); 
     182 
    146183        this.overloadedNamesAndSigs = new HashSet<String>(); 
    147184        this.lexEnv = new BATree<String,VarCodeGen>(StringHashComparer.V); 
    148185        this.env = env; 
     186         
     187         
    149188        debug( "Compile: Compiling ", packageAndClassName ); 
    150189    } 
     
    394433            // answer depends upon how intersection types are normalized. 
    395434            // conservative answer is "no". 
    396             methodName = Naming.mangleIdentifier(methodName); 
     435            // methodName = Naming.mangleIdentifier(methodName); 
    397436            signature = NamingCzar.jvmMethodDesc(arrow, component.getName()); 
    398437 
     
    400439            IntersectionType it = (IntersectionType) arrow; 
    401440            methodName = OverloadSet.actuallyOverloaded(it, paramCount) ? 
    402                     OverloadSet.oMangle(methodName) : Naming.mangleIdentifier(methodName); 
     441                    OverloadSet.oMangle(methodName) : methodName; 
    403442 
    404443            signature = OverloadSet.getSignature(it, paramCount, ta); 
     
    566605 
    567606        // Must do this first, to get local decls right. 
    568         overloadedNamesAndSigs = generateTopLevelOverloads(thisApi(), topLevelOverloads, ta, cw); 
    569  
     607        overloadedNamesAndSigs = generateTopLevelOverloads(thisApi(), topLevelOverloads, ta, cw, this); 
     608 
     609        /* Need wrappers for the API, too. */ 
     610        generateUnambiguousWrappersForApi(); 
     611         
    570612        // Must process top-level values next to make sure fields end up in scope. 
    571613        for (Decl d : x.getDecls()) { 
     
    755797         */ 
    756798 
     799 
    757800        // Dotted method; downcast self and 
    758801        // forward to static method in springboard class 
     
    808851        cg.generateActualMethodCode(modifiers, mname, sig, params, selfIndex, 
    809852                                    inAMethod, body); 
     853         
     854        generateAllWrappersForFn(x, params, sig, modifiers, mname); 
     855    } 
     856 
     857 
     858    /** 
     859     * @param x 
     860     * @param params 
     861     * @param selfIndex 
     862     * @param sig 
     863     * @param modifiers 
     864     * @param mname 
     865     */ 
     866    private void generateAllWrappersForFn(FnDecl x, List<Param> params, 
     867            String sig, int modifiers, 
     868            String mname) { 
     869        CodeGen cg = new CodeGen(this); 
     870        /* This code generates forwarding wrappers for  
     871         * the (local) unambiguous name of the function. 
     872         */ 
     873                 
     874        // unambiguous within component 
     875        String wname = idOrOpToString(x.getUnambiguousName()); 
     876        cg.generateWrapperMethodCode(modifiers, mname, wname, sig, params); 
     877    } 
     878 
     879 
     880    /** 
     881     * @param params 
     882     * @param sig 
     883     * @param modifiers 
     884     * @param mname 
     885     * @param cg 
     886     * @param sf 
     887     */ 
     888    private void generateUnambiguousWrappersForApi() { 
     889 
     890        for (Map.Entry<String, Set<Function>> entry : exportedToUnambiguous 
     891                .entrySet()) { 
     892            Set<Function> sf = entry.getValue(); 
     893            for (Function function : sf) { 
     894                List<Param> params = function.parameters(); 
     895 
     896                String sig = NamingCzar.jvmSignatureFor( 
     897                        NodeUtil.getParamType(params, function.getSpan()), 
     898                        function.getReturnType().unwrap(), 
     899                        component.getName()); 
     900                 
     901                String mname = idOrOpToString(function.name()); // entry.getKey(); 
     902 
     903                String function_ua_name = idOrOpToString(function.unambiguousName()); 
     904                generateWrapperMethodCode( 
     905                        Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, mname, 
     906                        function_ua_name, sig, params); 
     907            } 
     908        } 
     909    } 
     910 
     911    /** Generate an actual Java method and body code from an Expr. 
     912     *  Should be done within a nested codegen as follows: 
     913     *  new CodeGen(this).generateActualMethodCode(...); 
     914     */ 
     915    private void generateWrapperMethodCode(int modifiers, String mname, String wname, String sig, 
     916                                          List<Param> params) { 
     917 
     918        // ignore virtual, now. 
     919        if (0 == (Opcodes.ACC_STATIC & modifiers)) 
     920            return; 
     921         
     922        mv = cw.visitCGMethod(modifiers, wname, sig, null, null); 
     923        mv.visitCode(); 
     924 
     925        // Need to copy the parameter across for the wrapper call. 
     926        // Modifiers should tell us how to do the call, maybe? 
     927        // Invokestatic, for now. 
     928 
     929        int i = 0; 
     930         
     931        for (Param p : params) { 
     932            // Type ty = p.getIdType().unwrap(); 
     933            mv.visitVarInsn(Opcodes.ALOAD, i); 
     934            i++; 
     935        } 
     936 
     937        mv.visitMethodInsn(Opcodes.INVOKESTATIC, packageAndClassName, mname, sig); 
     938         
     939        methodReturnAndFinish(); 
    810940    } 
    811941 
     
    11971327                         sig, params.size(), true); 
    11981328 
     1329         
     1330        generateAllWrappersForFn(x, params, sig, modifiers, mname); 
     1331         
    11991332    } 
    12001333 
     
    12021335     * @param cg 
    12031336     */ 
     1337 
    12041338    private void methodReturnAndFinish() { 
    12051339        mv.visitInsn(Opcodes.ARETURN); 
     
    13021436    private String singleName(IdOrOpOrAnonymousName name) { 
    13031437        String nameString = idOrOpToString((IdOrOp)name); 
    1304         String mname = Naming.mangleIdentifier(nameString); 
     1438        String mname = nameString; // Naming.mangleIdentifier(nameString); 
    13051439        return mname; 
    13061440    } 
     
    14711605                int lastDot = n.lastIndexOf("."); 
    14721606                calleePackageAndClass = n.substring(0, lastDot).replace(".", "/"); 
    1473                 method = n.substring(lastDot+1); 
     1607                method = n.substring(lastDot+2); 
     1608                int foreign_tag = method.indexOf(Naming.FOREIGN_TAG); 
     1609                calleePackageAndClass = calleePackageAndClass + "/" + method.substring(0, foreign_tag); 
     1610                method = method.substring(foreign_tag+1); 
     1611                int paren_tag = method.indexOf("("); 
     1612                if (paren_tag != -1) 
     1613                    method = method.substring(0, paren_tag); 
    14741614            } 
    14751615        } 
     
    19362076 
    19372077            mv.visitInsn(Opcodes.DUP); 
    1938             int taskVar = mv.createCompilerLocal(Naming.mangleIdentifier(task), 
     2078            int taskVar = mv.createCompilerLocal(task, // Naming.mangleIdentifier(task), 
    19392079                    NamingCzar.internalToDesc(task)); 
    19402080            taskVars[i] = taskVar; 
     
    20452185        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, 
    20462186                           NamingCzar.makeInnerClassName(id), 
    2047                            Naming.mangleIdentifier(opToString(op)), 
     2187                           // Naming.mangleIdentifier(opToString(op)), 
     2188                           opToString(op), 
    20482189                           "(Lcom/sun/fortress/compiler/runtimeValues/FZZ32;)Lcom/sun/fortress/compiler/runtimeValues/FString;"); 
    20492190    } 
     
    23882529            Map<IdOrOpOrAnonymousName,MultiMap<Integer, Function>> size_partitioned_overloads, 
    23892530            TypeAnalyzer ta, 
    2390             ClassWriter cw 
     2531            CodeGenClassWriter cw, CodeGen cg 
    23912532            ) { 
    23922533 
     
    24132554 
    24142555               os.generateAnOverloadDefinition(s2, cw); 
     2556               if (cg != null) { 
     2557                   /* 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  
     2560                    */ 
     2561               } 
    24152562 
    24162563               for (Map.Entry<String, OverloadSet> o_entry : os.getOverloadSubsets().entrySet()) { 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/disambiguator/NameEnv.java

    r3998 r4291  
    4848 
    4949    /** 
    50      * Produce the set of unqualified, unambiguous names corresponding to the 
    51      * given function name.  Imported names are included. An undefined reference 
    52      * produces an empty set. 
     50     * Produce the set of qualified, unambiguous names corresponding to the 
     51     * given, possibly qualified function name.   
    5352     */ 
    5453    public abstract Set<IdOrOp> unambiguousFunctionNames(IdOrOp name); 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/disambiguator/TopLevelEnv.java

    r4211 r4291  
    446446    public Set<IdOrOp> unambiguousFunctionNames(final IdOrOp name) { 
    447447 
    448         // Function that gets an unambiguous name out of a Function. If it is 
    449         // not a DeclaredFunction or FunctionalMethod, the original name will 
    450         // be returned. 
     448        // Function that gets an unambiguous name out of a Function. 
    451449        Lambda<Function, IdOrOp> unambiguousNameFromFunction = new Lambda<Function, IdOrOp>() { 
     450            @Override public IdOrOp value(Function fn) { 
     451                return fn.unambiguousName(); 
     452            } 
     453        }; 
     454 
     455        // Qualifies the given name with the given API. Create normal Lambdas 
     456        // by binding an API. 
     457        Lambda2<APIName, IdOrOp, IdOrOp> addApi = new Lambda2<APIName, IdOrOp, IdOrOp>() { 
    452458            @Override 
    453             public IdOrOp value(Function fn) { 
    454                 if (fn instanceof DeclaredFunction) { 
    455                     return ((DeclaredFunction) fn).ast().getUnambiguousName(); 
    456                 } else if (fn instanceof FunctionalMethod) { 
    457                     return ((FunctionalMethod) fn).ast().getUnambiguousName(); 
     459            public IdOrOp value(APIName api, IdOrOp name) { 
     460                if (name instanceof Id) { 
     461                    return NodeFactory.makeId(Option.some(api), (Id) name); 
    458462                } else { 
    459                     return name; 
     463                    return NodeFactory.makeOp(Option.some(api), (Op) name); 
    460464                } 
    461465            } 
    462466        }; 
     467         
     468        // If this name is qualified, then lookup names only in that API. 
     469        if (name.getApiName().isSome()) { 
     470            APIName api = name.getApiName().unwrap(); 
     471             
     472            // Get the functions from this api with this name. 
     473            Set<? extends Function> functions = 
     474                _onDemandImportedApis.get(api).functions().matchFirst(name); 
     475             
     476            // Return their unambiguous names, qualified. 
     477            Lambda<IdOrOp, IdOrOp> addThisApi = LambdaUtil.bindFirst(addApi, api); 
     478            return CollectUtil.asSet(IterUtil.map(functions, 
     479                                                  LambdaUtil.compose(unambiguousNameFromFunction, 
     480                                                                     addThisApi))); 
     481        } 
    463482 
    464483        // First get all the declarations from this compilation unit. 
     
    468487        // Loop over all the imported APIs. 
    469488        for (final ApiIndex api : _onDemandImportedApis.values()) { 
    470  
    471             // Qualifies the names with this API. 
    472             Lambda<IdOrOp, IdOrOp> addApi = new Lambda<IdOrOp, IdOrOp>() { 
    473                 @Override 
    474                 public IdOrOp value(IdOrOp name) { 
    475                     if (name instanceof Id) { 
    476                         return NodeFactory.makeId(api.ast().getName(), (Id) name, NodeUtil.getSpan(name)); 
    477                     } else { 
    478                         return NodeFactory.makeOp(api.ast().getName(), (Op) name); 
    479                     } 
    480                 } 
    481             }; 
     489            Lambda<IdOrOp, IdOrOp> addThisApi = LambdaUtil.bindFirst(addApi, api.ast().getName()); 
    482490 
    483491            // Get all the declarations from this API and qualify the names. 
    484492            functions = api.functions().matchFirst(name); 
    485             results = IterUtil.compose(results, IterUtil.map(functions, LambdaUtil.compose(unambiguousNameFromFunction, 
    486                                                                                            addApi))); 
    487         } 
     493            results = IterUtil.compose(results, 
     494                                       IterUtil.map(functions, 
     495                                                    LambdaUtil.compose(unambiguousNameFromFunction, 
     496                                                                       addThisApi))); 
     497        } 
     498 
     499        // Add in the unambiguous names from the alias. 
     500        // TODO: Correct behavior? 
     501        if (_aliases.containsKey(name)) { 
     502            results = IterUtil.compose(results, 
     503                                       unambiguousFunctionNames((IdOrOp) _aliases.get(name))); 
     504        } 
     505 
    488506        return CollectUtil.asSet(results); 
    489507    } 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Coercion.java

    r4280 r4291  
    118118        return (IdOrOp) ast().getHeader().getName(); 
    119119    } 
     120     
     121    public IdOrOp unambiguousName() { 
     122        return (IdOrOp) ast().getUnambiguousName(); 
     123    } 
    120124 
    121125    public Id declaringTrait() { 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Constructor.java

    r4280 r4291  
    9191        return _declaringTrait; 
    9292    } 
     93     
     94    public IdOrOp unambiguousName() { 
     95        return name(); 
     96    } 
    9397 
    9498    //    public List<StaticParam> staticParams() { return _staticParams; } 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/index/DeclaredFunction.java

    r4280 r4291  
    6666        return (IdOrOp) NodeUtil.getName(_ast); 
    6767    } 
     68     
     69    public IdOrOp unambiguousName() { 
     70        return (IdOrOp) _ast.getUnambiguousName(); 
     71    } 
    6872 
    6973    @Override 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/index/DeclaredMethod.java

    r4280 r4291  
    123123        return (IdOrOp) NodeUtil.getName(_ast); 
    124124    } 
     125     
     126    public IdOrOp unambiguousName() { 
     127        return (IdOrOp) _ast.getUnambiguousName(); 
     128    } 
    125129 
    126130    @Override 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FieldGetterOrSetterMethod.java

    r4280 r4291  
    114114        return _ast.getName(); 
    115115    } 
     116     
     117    public IdOrOp unambiguousName() { 
     118        return name(); 
     119    } 
    116120} 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Functional.java

    r4280 r4291  
    4545 
    4646    public abstract IdOrOp name(); 
     47     
     48    public abstract IdOrOp unambiguousName(); 
    4749 
    4850    public String toString() { 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FunctionalMethod.java

    r4280 r4291  
    9898        return (IdOrOp) NodeUtil.getName(_ast); 
    9999    } 
     100     
     101    public IdOrOp unambiguousName() { 
     102        return (IdOrOp) _ast.getUnambiguousName(); 
     103    } 
    100104 
    101105    public Id declaringTrait() { 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/nativeInterface/FortressMethodAdapter.java

    r4283 r4291  
    2424 
    2525import com.sun.fortress.compiler.codegen.CodeGen; 
     26import com.sun.fortress.compiler.codegen.CodeGenClassWriter; 
    2627import com.sun.fortress.compiler.index.Function; 
    2728import com.sun.fortress.compiler.OverloadSet; 
     
    7071    private Map<IdOrOpOrAnonymousName,MultiMap<Integer, Function>> sizePartitionedOverloads; 
    7172    private TypeAnalyzer ta; 
    72     private ClassWriter cw; 
     73    private CodeGenClassWriter cw; 
    7374    private Set<String> overloadedNamesAndSigs; 
    7475 
     
    112113    } 
    113114 
    114     public FortressMethodAdapter(ClassWriter cv, 
     115    public FortressMethodAdapter(CodeGenClassWriter cv, 
    115116            String inputClassName, 
    116117            String outputClassName, 
     
    129130 
    130131    public void visit(int version, int access, String name, String signature, 
    131                       String superName, String[] interfaces) { 
    132         Debug.debug( Debug.Type.COMPILER, 1, 
    133                      "visit:" + name + " generate " + inputClassName); 
    134         cv.visit(version, access, outputClassName, signature, superName, interfaces); 
    135  
    136         overloadedNamesAndSigs = CodeGen.generateTopLevelOverloads(apiName, sizePartitionedOverloads, ta, cw); 
     132            String superName, String[] interfaces) { 
     133        Debug.debug(Debug.Type.COMPILER, 1, "visit:" + name + " generate " 
     134                + inputClassName); 
     135        cv.visit(version, access, outputClassName, signature, superName, 
     136                interfaces); 
     137 
     138        /* 
     139         * TODO there may be more work be done in the method called below. 
     140         * cg=null allows a bunch of code reuse, but does not deal with the 
     141         * possibility of unambiguous reference to one of these 
     142         * adapter-generated overloaded (?) native methods. 
     143         */ 
     144 
     145        overloadedNamesAndSigs = CodeGen.generateTopLevelOverloads(apiName, 
     146                sizePartitionedOverloads, ta, cw, /* cg= */null); 
    137147    } 
    138148 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/nativeInterface/FortressTransformer.java

    r4153 r4291  
    2424 
    2525import com.sun.fortress.compiler.ByteCodeWriter; 
     26import com.sun.fortress.compiler.codegen.CodeGenClassWriter; 
    2627import com.sun.fortress.compiler.index.Function; 
    2728import com.sun.fortress.compiler.OverloadSet; 
     
    4546        try { 
    4647            ClassReader cr = new ClassReader(inputClassName); 
    47             ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 
     48            CodeGenClassWriter cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES); 
    4849            String outputClassName = Naming.NATIVE_PREFIX_DOT + inputClassName; 
    4950             
  • trunk/ProjectFortress/src/com/sun/fortress/exceptions/InterpreterBug.java

    r1895 r4291  
    7171 
    7272    public static <T> T bug(String msg) { 
    73         throw new InterpreterBug(msg); 
     73        throw new InterpreterBug("** bug! " + msg); 
    7474    } 
    7575 
  • trunk/ProjectFortress/src/com/sun/fortress/nodes_util/NodeFactory.java

    r4280 r4291  
    486486                                    Option<Type> returnType, 
    487487                                    Option<Expr> body) { 
    488         return makeFnDecl(span, mods, name, 
     488        return makeFnDecl(span, 
     489                          mods, 
     490                          name, 
    489491                          Collections.<StaticParam>emptyList(), 
    490492                          params, returnType, 
     
    494496                          body); 
    495497    } 
    496  
     498     
     499    private static String uaName(String tag, Span span ) { 
     500        String s = span.toString(); 
     501        s = s.replaceAll("/", "|"); 
     502        return s; 
     503    } 
     504     
    497505    public static FnDecl makeFnDecl(Span span, Modifiers mods, 
    498506                                    IdOrOpOrAnonymousName name, 
     
    505513        IdOrOp unambiguousName; 
    506514        if (name instanceof Op) { 
    507                 unambiguousName = makeOp((Op)name, "OP$"+span.toString()); 
     515                unambiguousName = makeOp((Op)name, uaName("OP", span)); 
    508516        } else { 
    509                 unambiguousName = makeId(span, "FN$"+span.toString()); 
     517                unambiguousName = makeId(span, uaName("FN", span)); 
    510518        } 
    511519        return makeFnDecl(span, mods, name, staticParams, params, returnType, 
     
    525533        IdOrOp unambiguousName; 
    526534        if (name instanceof Op) { 
    527                 unambiguousName = makeOp((Op)name, "OP$"+span.toString()); 
     535                unambiguousName = makeOp((Op)name, uaName("OP", span)); 
    528536        } else { 
    529                 unambiguousName = makeId(span, "FN$"+span.toString()); 
     537                unambiguousName = makeId(span, uaName("FN", span)); 
    530538        } 
    531539        return makeFnDecl(span, mods, name, staticParams, params, returnType, 
     
    546554    } 
    547555 
    548     public static FnDecl makeFnDecl(Span span, Modifiers mods, 
     556    public static FnDecl makeFnDecl(Span span, 
     557                                    Modifiers mods, 
    549558                                    IdOrOpOrAnonymousName name, 
    550559                                    List<StaticParam> staticParams, 
     
    17671776    public static Op makeOp(final APIName api, Op op) { 
    17681777        return makeOp(NodeUtil.getSpan(op), Option.some(api), 
     1778                      op.getText(), op.getFixity(), op.isEnclosing() ); 
     1779    } 
     1780 
     1781    public static Op makeOp(Option<APIName> api, Op op) { 
     1782        return makeOp(NodeUtil.getSpan(op), api, 
    17691783                      op.getText(), op.getFixity(), op.isEnclosing() ); 
    17701784    } 
  • trunk/ProjectFortress/src/com/sun/fortress/repository/ForeignJava.java

    r4275 r4291  
    3232import com.sun.fortress.repository.graph.ApiGraphNode; 
    3333import com.sun.fortress.repository.graph.GraphNode; 
     34import com.sun.fortress.runtimeSystem.Naming; 
    3435import com.sun.fortress.scala_src.typechecker.IndexBuilder; 
    3536import com.sun.fortress.useful.*; 
     
    172173    private static Span span() { 
    173174        return NodeFactory.internalSpan; 
    174     } 
    175  
    176     private static Span span(MethodNode m) { 
    177         return NodeFactory.makeSpan(methodName(m)); 
    178175    } 
    179176 
     
    413410 
    414411        public int compare(MethodNode o1, MethodNode o2) { 
    415             return methodName(o1).compareTo(methodName(o2)); 
     412            return justMethodName(o1).compareTo(justMethodName(o2)); 
    416413        } 
    417414 
     
    489486 
    490487    private FnDecl recurOnMethod(APIName importing_package, ClassNode cl, MethodNode m, boolean is_static) { 
    491         String methodKey = methodName(m); 
     488        String methodKey = methodName(cl, m); 
    492489        if (methodToDecl.containsKey(methodKey)) return methodToDecl.get(methodKey); 
    493490 
     
    501498        for (Type pt : pts) { 
    502499            com.sun.fortress.nodes.Type type = recurOnOpaqueClass(importing_package, pt); 
    503             Span param_span = NodeFactory.makeSpan(span(m) + " p#" + i); 
     500            Span param_span = NodeFactory.makeSpan(span(methodKey) + " p#" + i); 
    504501            Id id = NodeFactory.makeId(param_span, "p" + (i++)); 
    505502            Param p = NodeFactory.makeParam(id, type); 
     
    507504        } 
    508505 
    509         Span fn_span = span(m); 
     506        Span fn_span = span(methodKey); 
    510507        Id id = is_static ? NodeFactory.makeId(fn_span, getSimpleName(cl) + "." + getName(m)) : NodeFactory.makeId( 
    511508                fn_span, 
    512509                getName(m)); 
     510         
     511        String uan = Naming.FOREIGN_TAG + methodKey ; 
     512         
    513513        FnDecl fndecl = NodeFactory.makeFnDecl(fn_span, 
    514514                                               Modifiers.None, 
    515                                                id, 
     515                                               (IdOrOpOrAnonymousName) id, 
     516                                               Collections.<StaticParam>emptyList(), 
    516517                                               params, 
    517518                                               Option.some(return_type), 
    518                                                Option.<Expr>none()); 
     519                                               Option.<List<com.sun.fortress.nodes.Type>>none(), 
     520                                               Option.<WhereClause>none(), 
     521                                               Option.<Contract>none(), 
     522                                               (IdOrOp) NodeFactory.makeId(fn_span, uan), 
     523                                               Option.<Expr>none(), 
     524                                               Option.<IdOrOp>none() 
     525                                               ); 
     526         
    519527        methodToDecl.put(methodKey, fndecl); 
    520528        return fndecl; 
     
    525533     * @return 
    526534     */ 
    527     private static String methodName(MethodNode m) { 
     535    private static String methodName(ClassNode cl, MethodNode m) { 
     536        String s = cl.name; 
     537        int i = s.lastIndexOf("/"); 
     538        s = s.substring(i+1); 
     539        return s + Naming.FOREIGN_TAG + m.name + m.desc; 
     540    } 
     541     
     542    private static String justMethodName(MethodNode m) { 
    528543        return m.name + m.desc; 
    529544    } 
  • trunk/ProjectFortress/src/com/sun/fortress/runtimeSystem/Naming.java

    r4252 r4291  
    634634                mangledString = "\\=" + mangledString; 
    635635 
     636            // debugging check for double-mangling 
     637            if (mangledString.startsWith("\\-")) 
     638                mangledString = mangledString; 
     639             
    636640            return mangledString; 
    637641        } 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/disambiguator/ExprDisambiguator.scala

    r4185 r4291  
    397397                  } else result = Some(SVarRef(info, newName, sargs, depth)) 
    398398                case (0, f, _) if f > 0 => 
    399                   var new_fns = setToList[IdOrOp](toSet(fns)) 
     399                  val new_fns = setToList[IdOrOp](toSet(fns)) 
     400                  val unambiguous_fns = setToList[IdOrOp](toSet(env.unambiguousFunctionNames(name))) 
    400401                  // Create a list of overloadings for this FnRef from the 
    401402                  // matching function names. 
    402403                  // TODO: insert correct number of to-infer arguments? 
    403404                  result = Some(SFnRef(info, sargs, depth, name, new_fns, None, 
    404                                        new_fns.map(new Overloading(info, _, None)), 
     405                                       unambiguous_fns.map(new Overloading(info, _, None)), 
    405406                                       None)) 
    406407                case (1, 0, 1) => 
     
    443444          } 
    444445        else { 
    445           var new_fns = setToList[IdOrOp](toSet(fns)) 
     446          val new_fns = setToList[IdOrOp](toSet(fns)) 
     447          val unambiguous_fns = setToList[IdOrOp](toSet(env.unambiguousFunctionNames(fn_name))) 
    446448          SFnRef(info, sargs, depth, fn_name.asInstanceOf[Id], new_fns, ovl, 
    447449                 // Create a list of overloadings for this FnRef from the matching 
    448450                 // function names. 
    449                  new_fns.map(new Overloading(info, _, None)), ovlType) 
     451                 unambiguous_fns.map(new Overloading(info, _, None)), ovlType) 
    450452        } 
    451453 
     
    801803      if (ops.isEmpty) None 
    802804      else { 
    803         var new_ops = setToList[IdOrOp](toSet(ops)) 
     805        val new_ops = setToList[IdOrOp](toSet(ops)) 
     806        val unambiguous_ops = setToList[IdOrOp](toSet(env.unambiguousFunctionNames(op_name))) 
    804807        // Create a list of overloadings for this OpRef from the matching 
    805808        // operator names. 
    806809        Some(SOpRef(info, sargs, depth, op_name, new_ops, oldOvl, 
    807                     new_ops.map(new Overloading(info, _, None)), ovlType)) 
     810                    unambiguous_ops.map(new Overloading(info, _, None)), ovlType)) 
    808811      } 
    809812    case _ => None 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/linker/HygienicRenamer.scala

    r4275 r4291  
    154154             SOptionalSymbol(walk(getInfo).asInstanceOf[com.sun.fortress.nodes.ASTNodeInfo], walk(getSymbol).asInstanceOf[com.sun.fortress.nodes.SyntaxSymbol]) 
    155155         case SOverloading(getInfo, getUnambiguousName, getType) => 
    156              SOverloading(walk(getInfo).asInstanceOf[com.sun.fortress.nodes.ASTNodeInfo], walk(getUnambiguousName).asInstanceOf[com.sun.fortress.nodes.IdOrOp], walk(getType).asInstanceOf[Option[com.sun.fortress.nodes.Type]]) 
     156             SOverloading(walk(getInfo).asInstanceOf[com.sun.fortress.nodes.ASTNodeInfo], walk(getUnambiguousName).asInstanceOf[com.sun.fortress.nodes.IdOrOp], walk(getType).asInstanceOf[Option[com.sun.fortress.nodes.ArrowType]]) 
    157157         case SParam(getInfo, getName, getMods, getIdType, getDefaultExpr, getVarargsType) => 
    158158             SParam(walk(getInfo).asInstanceOf[com.sun.fortress.nodes.ASTNodeInfo], walk(getName).asInstanceOf[com.sun.fortress.nodes.Id], walk(getMods).asInstanceOf[com.sun.fortress.nodes_util.Modifiers], walk(getIdType).asInstanceOf[Option[com.sun.fortress.nodes.Type]], walk(getDefaultExpr).asInstanceOf[Option[com.sun.fortress.nodes.Expr]], walk(getVarargsType).asInstanceOf[Option[com.sun.fortress.nodes.Type]]) 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/STypeChecker.scala

    r4285 r4291  
    337337    } 
    338338 
     339  /** 
     340   * Lookup the functional indices for the given name in the proper type 
     341   * environment. 
     342   */ 
     343  protected def getFnIndicesFromName(name: Name): Option[List[Functional]] = 
     344    getRealName(name, toList(current.ast.getImports)) match { 
     345      case id@SIdOrOp(_, Some(api), _) => getEnvFromApi(api).getFnIndices(id) 
     346      case id:IdOrOp => env.getFnIndices(id) 
     347      case _ => None 
     348    } 
     349 
    339350  def getErrors(): List[StaticError] = errors.errors 
    340351 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/impls/Functionals.scala

    r4251 r4291  
    2121import com.sun.fortress.compiler.index._ 
    2222import com.sun.fortress.exceptions._ 
     23import com.sun.fortress.exceptions.InterpreterBug.bug 
    2324import com.sun.fortress.exceptions.StaticError.errorMsg 
    2425import com.sun.fortress.nodes._ 
     
    466467  def checkFunctionals(node: Node): Node = node match { 
    467468 
    468     case SOverloading(info, name, _) => { 
    469       val checkedName = check(name).asInstanceOf[IdOrOp] 
     469    case SOverloading(info, unambigName, _) => { 
     470      val checkedName = check(unambigName).asInstanceOf[IdOrOp] 
     471 
     472      // Should have one arrow type for this unambiguous name. 
    470473      getTypeFromName(checkedName) match { 
    471         case Some(checkedType) => 
    472           SOverloading(info, checkedName, Some(normalize(checkedType))) 
     474        case Some(arrow: ArrowType) => 
     475          SOverloading(info, checkedName, Some(arrow)) 
     476        case Some(typ) => 
     477          bug("type env binds unambiguous name %s to non-arrow type %s".format(unambigName, typ)) 
    473478        case None => node 
    474479      } 
     
    557562        case SOverloading(info, name, Some(ty)) => 
    558563          instantiateStaticParams(sargs, ty). 
    559             map(t => SOverloading(info, name, Some(t))) 
     564            map(t => SOverloading(info, name, Some(t.asInstanceOf[ArrowType]))) 
    560565        case _ => hadNoType = true; None 
    561566      } 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/STypeEnv.scala

    r4166 r4291  
    3131import com.sun.fortress.scala_src.useful.Options._ 
    3232import com.sun.fortress.scala_src.useful.Sets._ 
    33 import com.sun.fortress.scala_src.useful.STypesUtil 
    34 import com.sun.fortress.scala_src.useful.STypesUtil.TypeThunk 
     33import com.sun.fortress.scala_src.useful.SNodeUtil._ 
     34import com.sun.fortress.scala_src.useful.STypesUtil._ 
    3535import edu.rice.cs.plt.collect.Relation 
    3636 
     
    101101  /** Get the modifiers for the given name, if it exists. */ 
    102102  def getMods(x: Name): Option[Modifiers] = lookup(x).map(_.mods) 
     103   
     104  /** Get the functional indices for this name, if any. */ 
     105  def getFnIndices(x: Name): Option[List[Functional]] = 
     106    lookup(x).map(_.fnIndices) 
    103107} 
    104108 
     
    151155                            typeThunk: TypeThunk, 
    152156                            mods: Modifiers, 
    153                             mutable: Boolean): TypeBinding = 
    154     TypeBinding(name, typeThunk, mods, mutable) 
     157                            mutable: Boolean, 
     158                            functions: Collection[Functional]): TypeBinding = 
     159    TypeBinding(name, typeThunk, mods, mutable, functions.toList) 
    155160 
    156161  /** 
     
    163168                            mutable: Boolean): TypeBinding = { 
    164169    val typeThunk = new TypeThunk { def apply: Option[Type] = Some(typ) } 
    165     TypeBinding(name, typeThunk, mods, mutable) 
     170    TypeBinding(name, typeThunk, mods, mutable, Nil) 
    166171  } 
    167172 
     
    211216              NF.makeArrowType(NU.getSpan(qualifiedName), 
    212217                               // Constructors must have all param types. 
    213                                STypesUtil.makeDomainType(toList(params)).get, 
     218                               makeDomainType(toList(params)).get, 
    214219                               NF.makeTraitType(qualifiedName)) 
    215220            case Some(params) => 
    216221              // Generic arrow type for constructor. 
    217               val sargs = toList(sparams).map(STypesUtil.staticParamToArg) 
     222              val sargs = toList(sparams).map(staticParamToArg) 
    218223              NF.makeArrowType(NU.getSpan(decl), 
    219224                               false, 
    220225                               // Constructors must have all param types. 
    221                                STypesUtil.makeDomainType(toList(params)).get, 
     226                               makeDomainType(toList(params)).get, 
    222227                               NF.makeTraitType(qualifiedName, 
    223228                                                toJavaList(sargs)), 
     
    242247          def apply: Option[Type] = v.getInferredType 
    243248        } 
    244         makeBinding(x, lazyTypeEvaluation, v.modifiers, v.mutable) 
     249        makeBinding(x, lazyTypeEvaluation, v.modifiers, v.mutable, Nil) 
    245250      }) 
    246251    } 
     
    259264                                       (functions: Iterable[(S,Set[T])], 
    260265                                        api: Option[APIName]): Iterable[TypeBinding] = { 
    261     functions.map{ tuple => 
    262       val (x,fns) = tuple 
    263       // Lazily compute the type for this function binding at the time of 
    264       // lookup. 
    265       val lazyTypeEvaluation: TypeThunk = new TypeThunk { 
     266                                          
     267    // Collect all bindings found among all these functions. 
     268    functions.flatMap { nameAndFunctions => 
     269      val (f, fnsSet) = nameAndFunctions 
     270      val fns = fnsSet.toList 
     271       
     272      // Create the binding for each overloading of the function named f. 
     273      val unambiguousBindings = fns.map { fn => 
     274         
     275        // Create a lazy computation for the type of this overloading. 
     276        val lazyType = new TypeThunk { 
     277          def apply: Option[Type] = makeArrowFromFunctional(fn) 
     278        } 
     279         
     280        // Bind the unambiguous name of this overloading to its type. 
     281        makeBinding(unqualifiedName(fn.unambiguousName), 
     282                    lazyType, 
     283                    fn.mods, 
     284                    false, 
     285                    List(fn)) 
     286      } 
     287       
     288      // Create a lazy computation for the type of the whole overloaded 
     289      // function named x. 
     290      val ambiguousThunk = new TypeThunk { 
    266291        def apply: Option[Type] = { 
    267           // TODO: Currently ignoring any errors from makeArrowFromFunctional 
    268           val oTypes = fns.flatMap[Type](STypesUtil.makeArrowFromFunctional) 
     292          val oTypes = fns.flatMap[Type](makeArrowFromFunctional) 
    269293          if (oTypes.isEmpty) 
    270294            None 
     
    273297        } 
    274298      } 
    275       val mods = if ( fns.isEmpty ) Modifiers.None 
    276                  else fns.find(_.mods != Modifiers.None) match { 
    277                    case Some(f) => f.mods 
    278                      case _ => Modifiers.None 
    279                    } 
    280       makeBinding(x, lazyTypeEvaluation, mods, false) 
     299       
     300      // Create the modifiers for the whole binding. 
     301      val ambiguousMods = 
     302        if (fns.isEmpty) 
     303          Modifiers.None 
     304        else fns.find(_.mods != Modifiers.None) match { 
     305          case Some(f) => f.mods 
     306          case _ => Modifiers.None 
     307        } 
     308       
     309      // Bind the ambiguous, plain name of this function to the intersection 
     310      // of all its overloadings' types. 
     311      val ambiguousBinding = makeBinding(unqualifiedName(f), 
     312                                         ambiguousThunk, 
     313                                         ambiguousMods, 
     314                                         false, 
     315                                         fns) 
     316       
     317      // Return all the bindings. 
     318      ambiguousBinding :: unambiguousBindings 
    281319    } 
    282320  }  
     
    293331 * @param mods Any modifiers for the binding. 
    294332 * @param mutable Whether or not the binding is mutable. 
     333 * @param fnIndices A list of Functional indices, if any, to which this name 
     334 *                  refers. 
    295335 */ 
    296336case class TypeBinding(name: Name, 
    297337                       typeThunk: TypeThunk, 
    298338                       mods: Modifiers, 
    299                        mutable: Boolean) 
     339                       mutable: Boolean, 
     340                       fnIndices: List[Functional]) 
    300341 
    301342/** 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/useful/STypesUtil.scala

    r4289 r4291  
    796796                             (implicit analyzer: TypeAnalyzer) 
    797797                              : Option[Overloading] = { 
    798     // Is this arrow type applicable. 
    799     def arrowTypeIsApplicable(ovType: ArrowType): Option[Type] = { 
    800      
    801       // If static args, then instantiate the unlifted static params. 
    802       val typ1 = 
    803         if (!sargs.isEmpty) 
    804           instantiateStaticParams(sargs, ovType).getOrElse(return None) 
    805         else 
    806           ovType 
    807        
    808       // If there were lifted, inferred static args, then instantiate those. 
    809       val typ2 = 
    810         if (!liftedInfSargs.isEmpty) 
    811           instantiateLiftedStaticParams(liftedInfSargs, typ1).getOrElse(return None) 
    812         else 
    813           typ1 
    814  
    815       // If there are still some static params in it, then we can't infer them 
    816       // so it's not applicable. 
    817       val typ = typ2.asInstanceOf[ArrowType] 
     798    val SOverloading(ovInfo, ovName, Some(ovType)) = overloading 
     799 
     800    // If static args, then instantiate the unlifted static params. 
     801    val typ1 = 
     802      if (!sargs.isEmpty) 
     803        instantiateStaticParams(sargs, ovType).getOrElse(return None) 
     804      else 
     805        ovType 
     806 
     807    // If there were lifted, inferred static args, then instantiate those. 
     808    val typ2 = 
     809      if (!liftedInfSargs.isEmpty) 
     810        instantiateLiftedStaticParams(liftedInfSargs, typ1).getOrElse(return None) 
     811      else 
     812        typ1 
     813 
     814    // If there are still some static params in it, then we can't infer them 
     815    // so it's not applicable. 
     816    val typ = typ2.asInstanceOf[ArrowType] 
     817    val newOvType = 
    818818      if (!hasStaticParams(typ) && isSubtype(typ.getDomain, smaArrow.getDomain)) 
    819         Some(typ) 
     819        typ 
    820820      else 
    821         None 
    822     } 
    823  
    824     // If overloading type is an intersection, check that any of its 
    825     // constituents is applicable. 
    826     val applicableArrows = conjuncts(toOption(overloading.getType).get). 
    827       map(_.asInstanceOf[ArrowType]). 
    828       flatMap(arrowTypeIsApplicable). 
    829       toList 
    830  
    831     val overloadingType = applicableArrows match { 
    832       case Nil => return None 
    833       case t::Nil => t 
    834       case _ => NF.makeIntersectionType(toJavaList(applicableArrows)) 
    835     } 
    836     Some(SOverloading(overloading.getInfo, 
    837                       overloading.getUnambiguousName, 
    838                       Some(overloadingType))) 
     821        return None 
     822 
     823    Some(SOverloading(ovInfo, ovName, Some(newOvType))) 
    839824  } 
    840825