Changeset 3875

Show
Ignore:
Timestamp:
06/18/09 19:15:43 (5 months ago)
Author:
sukyoungryu
Message:

[overloading checker] Fixed the implementation of identifying the intersection of types with comprises clauses with the union of their common subtypes.
[parser] Added io to arrow types. Added a test.
[shell] Eliminated the temporary shell commands to test the Scala type checker. Added a flag, -typecheck-java, to the fortress compile command.

Location:
trunk/ProjectFortress
Files:
3 added
15 modified

Legend:

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

    r3845 r3875  
    10651065                /** 
    10661066                 * arrow type 
    1067                  * Type ::= Type -> Type Throws? 
     1067                 * Type ::= io? Type -> Type Throws? 
    10681068                 * e.g.) (String, NN..., p = Printer) -> NN throws IOException 
    10691069                 * 
     
    10721072                 * type of a generic function, used during static checking 
    10731073                 */ 
    1074                 ArrowType(Type domain, Type range, Effect effect); 
     1074                ArrowType(Type domain, Type range, Effect effect, boolean io); 
    10751075                /** 
    10761076                 * inferred type 
  • trunk/ProjectFortress/compiler_tests/AfterTypeChecking.test

    r3871 r3875  
    1414#    trademarks of Sun Microsystems, Inc. in the U.S. and other countries. 
    1515 
    16 tests=Compiled1.ag Compiled1.ah Compiled1.ai Compiled1.aj Compiled1.ak Compiled1.as Compiled1.au Compiled1.av Compiled2.g Compiled2.t Compiled3.b Compiled3.c Compiled3.d Compiled3.e Compiled3.f Compiled3.h Compiled3.i Compiled3.j Compiled3.k Compiled3.m Compiled3.p Compiled3.q Compiled3.t Compiled3.v Compiled3.x Compiled5.e Compiled5.j Compiled5.o Compiled5.q Compiled6 Compiled7 Compiled8 
     16tests=Compiled1.ag Compiled1.ah Compiled1.ai Compiled1.aj Compiled1.ak Compiled1.as Compiled1.au Compiled1.av Compiled2.g Compiled2.t Compiled3.b Compiled3.c Compiled3.d Compiled3.e Compiled3.f Compiled3.h Compiled3.i Compiled3.j Compiled3.k Compiled3.m Compiled3.p Compiled3.q Compiled3.t Compiled3.v Compiled3.x Compiled5.e Compiled5.o Compiled5.q Compiled6 Compiled7 Compiled8 
    1717desugar 
  • trunk/ProjectFortress/compiler_tests/nyi.Compiled6.t.fss

    r3832 r3875  
    1919export Executable 
    2020 
    21 f(x:ZZ32) = x 
    22 g(x:ZZ32) = x 
     21f(x:ZZ32):ZZ32 = x 
     22g(x:ZZ32):ZZ32 = x 
    2323 
    2424run(): () = printlnZZ32(g(3)) 
  • trunk/ProjectFortress/src/com/sun/fortress/Shell.java

    r3873 r3875  
    312312                setPhase( PhaseOrder.CODEGEN ); 
    313313                return_code = compilerPhases(args, Option.<String>none(), what); 
    314             } else if (what.equals("compile-scala")) { 
    315                 WellKnownNames.useCompilerLibraries(); 
    316                 Types.useCompilerLibraries(); 
    317                 setTypeChecking(true); 
    318                 //setScala(true); 
    319                 setPhase( PhaseOrder.CODEGEN ); 
    320                 return_code = compilerPhases(args, Option.<String>none(), what); 
    321314            } else if (what.equals("link")) { 
    322315                WellKnownNames.useCompilerLibraries(); 
    323316                Types.useCompilerLibraries(); 
    324                 setTypeChecking(true); 
    325                 setPhase( PhaseOrder.CODEGEN ); 
    326                 return_code = link(args); 
    327             } else if (what.equals("link-scala")) { 
    328                 WellKnownNames.useCompilerLibraries(); 
    329                 Types.useCompilerLibraries(); 
    330                 setScala(true); 
    331317                setTypeChecking(true); 
    332318                setPhase( PhaseOrder.CODEGEN ); 
     
    353339                setPhase( PhaseOrder.DISAMBIGUATE ); 
    354340                return_code = compilerPhases(args, Option.<String>none(), what); 
    355             } else if ( what.equals( "disambiguate-scala" ) ){ 
    356                 setScala(true); 
    357                 setPhase( PhaseOrder.DISAMBIGUATE ); 
    358                 return_code = compilerPhases(args, Option.<String>none(), what); 
    359341            } else if ( what.equals( "desugar" ) ){ 
    360342                setTypeChecking(true); 
     
    371353                setPhase( PhaseOrder.TYPECHECK ); 
    372354                return_code = compilerPhases(args, Option.<String>none(), what); 
    373             } else if (what.equals("typecheck-scala")){ 
    374                 WellKnownNames.useCompilerLibraries(); 
    375                 Types.useCompilerLibraries(); 
    376                 setTypeChecking(true); 
    377                 setScala(true); 
    378                 setPhase( PhaseOrder.TYPECHECK ); 
    379                 return_code = compilerPhases(args, Option.<String>none(), what); 
    380355            } else if (what.equals("test-coercion")) { 
    381356                setTypeChecking(true); 
    382                 setScala(true); 
    383357                setPhase(PhaseOrder.TYPECHECK); 
    384358                return_code = compilerPhases(args, Option.<String>none(), what); 
     
    749723                Types.useCompilerLibraries(); 
    750724            } 
    751             else if (s.equals("-typecheck-scala")) { 
    752                 setScala(true); 
     725            else if (s.equals("-typecheck-java")) { 
     726                setScala(false); 
    753727            } 
    754728            else if (s.equals("-coercion")) { 
     
    940914            if (s.equals("-debug")){ 
    941915                rest = Debug.parseOptions(rest); 
    942             } 
    943             else if (s.equals("-typecheck-scala")) { 
    944                 setScala(true); 
    945916            } 
    946917            else 
  • trunk/ProjectFortress/src/com/sun/fortress/nodes_util/NodeFactory.java

    r3855 r3875  
    743743                                          Option<WhereClause> where) { 
    744744        TypeInfo info = makeTypeInfo(span, parenthesized, sparams, where); 
    745         return new ArrowType(info, domain, range, effect); 
     745        return new ArrowType(info, domain, range, effect, false); 
    746746    } 
    747747 
  • trunk/ProjectFortress/src/com/sun/fortress/parser/Compilation.rats

    r3845 r3875  
    100100 
    101101/* Component ::= 
    102      (native w)? component w APIName w comprises w APINames 
    103      w end ((s component)? s APIName)? 
    104    | (native w)? component w APIName w ImportOrExports (w ;)? 
     102     (native w)? component w APIName w ImportOrExports (w ;)? 
    105103     (w Decls (w ;)?)? w end ((s component)? s APIName)? 
    106104 */ 
  • trunk/ProjectFortress/src/com/sun/fortress/parser/NoNewlineType.rats

    r3456 r3875  
    3636/* NoNewlineType ::= NoNewlineTypePrimary (w in w NoNewlineExpr)? */ 
    3737Type NoNewlineType = 
    38      !(one) a1:TypePrimary a2:(w void:in w NoNewlineExpr)? 
     38     !(one) (io w)? a1:TypePrimary a2:(w void:in w NoNewlineExpr)? 
    3939     { Type ty = TypeResolver.resolveOps(a1); 
    4040       if (a2 == null) 
  • trunk/ProjectFortress/src/com/sun/fortress/parser/Type.rats

    r3822 r3875  
    3434/* Type ::= TypePrimary (w in w Expr)? */ 
    3535Type Type = 
    36      !(one) a1:TypePrimary a2:(w void:in w Expr)? 
     36     !(one) (io w)? a1:TypePrimary a2:(w void:in w Expr)? 
    3737     { Type ty = TypeResolver.resolveOps(a1); 
    3838       Span span = NodeUtil.getSpan(ty); 
  • trunk/ProjectFortress/src/com/sun/fortress/parser/import_collector/Compilation.rats

    r3845 r3875  
    6565 
    6666/* Component ::= 
    67      (native w)? component w APIName w comprises w APINames 
    68      w end ((s component)? s APIName)? 
    69    | (native w)? component w APIName (w Imports w ;?)? w Exports w ;? 
     67     (native w)? component w APIName (w Imports w ;?)? w Exports w ;? 
    7068     (w Decls w ;?)? w end ((s component)? s APIName)? 
    7169 */ 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/ExclusionOracle.scala

    r3783 r3875  
    5656   * The following types are not yet supported: 
    5757   *     Types tagged with dimensions or units 
    58    *     Effects on arrow types 
     58   *     Effects and io on arrow types 
    5959   *     Keyword parameters and varargs parameters 
    6060   *     Intersection types 
     
    134134            false 
    135135        } 
    136       case (SArrowType(_,_,_,_), SArrowType(_,_,_,_)) => false 
    137       case (SArrowType(_,_,_,_), _) => true 
    138       case (_, SArrowType(_,_,_,_)) => true 
     136      case (SArrowType(_,_,_,_,_), SArrowType(_,_,_,_,_)) => false 
     137      case (SArrowType(_,_,_,_,_), _) => true 
     138      case (_, SArrowType(_,_,_,_,_)) => true 
    139139      case (f@STupleType(_,_,_,_), s@STupleType(_,_,_,_)) => 
    140140        NodeUtil.differentArity(f, s) || { 
     
    215215      case STraitType(i,n,a,p) => STraitType(i, n, a.map(saSubst), p.map(spSubst)) 
    216216      case STupleType(i,e,v,k) => STupleType(i, e.map(tySubst), v, k) 
    217       case SArrowType(i,d,r,e) => SArrowType(i, tySubst(d), tySubst(r), e) 
     217      case SArrowType(i,d,r,e,b) => SArrowType(i, tySubst(d), tySubst(r), e, b) 
    218218      case _ => tau 
    219219    } 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/ExportChecker.scala

    r3842 r3875  
    403403                equalOptTypes(varargsL, varargsR) && 
    404404                equalListKeywordTypes(kwdL, kwdR) 
    405             case (SArrowType(_, domL, ranL, effL), 
    406                   SArrowType(_, domR, ranR, effR)) => 
     405            case (SArrowType(_, domL, ranL, effL, ioL), 
     406                  SArrowType(_, domR, ranR, effR, ioR)) => 
    407407                  equalTypes(domL, domR) && 
    408408                  equalTypes(ranL, ranR) && 
    409                   equalEffects(effL, effR) 
     409                  equalEffects(effL, effR) && 
     410                  ioL == ioR 
    410411            case _ => false 
    411412        } 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala

    r3871 r3875  
    242242        typeAnalyzer = typeAnalyzer.extend(staticParameters, none[WhereClause]) 
    243243        var result = false 
    244         val meet = (reduce(typeAnalyzer.meet(first._1._2, second._1._2)), 
    245                     reduce(typeAnalyzer.meet(first._1._3, second._1._3))) 
     244        val exclusionOracle = new ExclusionOracle(typeAnalyzer, new ErrorLog()) 
     245        val meet = (reduce(typeAnalyzer.meet(first._1._2, second._1._2), exclusionOracle), 
     246                    reduce(typeAnalyzer.meet(first._1._3, second._1._3), exclusionOracle)) 
    246247        for ( f <- set ; if ! result ) 
    247248            if ( subtype(f._1._2, meet._1) && 
     
    262263     *    simplif "t" 
    263264     */ 
    264     private def reduce(t: Type): Type = t match { 
     265    private def reduce(t: Type, exclusionOracle: ExclusionOracle): Type = t match { 
    265266        case SIntersectionType(info, elements) => 
    266267            val (tuples, nots) = elements.partition(NodeUtil.isTupleType) 
     
    269270                // If all the "elements" have comprises clauses 
    270271                // and they all include type "M", then "M" is the meet. 
    271                 existComprisedMeet(elements) match { 
     272                existComprisedMeet(elements, exclusionOracle) match { 
    272273                    case Some(m) => m 
    273274                    case _ => t 
     
    292293 
    293294    /* If all the "types" have comprises clauses 
    294      * and they all include type "M", then "M" is the meet. 
    295      */ 
    296     private def existComprisedMeet(types: List[Type]): Option[TraitType] = { 
    297       var meet: List[TraitType] = null 
     295     * and they all include types "comprised", 
     296     * then if "comprised" = {"M"} and all the others are exclusive 
     297     *      then "M" is the meet 
     298     */ 
     299    private def existComprisedMeet(types: List[Type], 
     300                                   exclusionOracle: ExclusionOracle): Option[TraitType] = { 
     301      var allComprises = List[(Id, List[TraitType])]() 
     302      var meets: List[TraitType] = null 
    298303      for ( t <- types ) { 
    299304        if ( t.isInstanceOf[TraitType] ) { 
    300           STypesUtil.getTypes(t.asInstanceOf[TraitType].getName, 
    301                               globalEnv, compilation_unit) match { 
     305          val name = t.asInstanceOf[TraitType].getName 
     306          STypesUtil.getTypes(name, globalEnv, compilation_unit) match { 
    302307            case ti:ProperTraitIndex => 
    303308              var comprises = List[TraitType]() 
    304             for ( s <- toSet(ti.comprisesTypes) ) comprises = s::comprises 
     309              for ( s <- toSet(ti.comprisesTypes) ) comprises = s::comprises 
     310              allComprises = (name, comprises)::allComprises 
    305311              if ( ! comprises.isEmpty ) { 
    306                 if ( meet == null ) meet = comprises 
    307                 else meet = meet.intersect(comprises) 
     312                if ( meets == null ) meets = comprises 
     313                else meets = meets.intersect(comprises) 
    308314              } else return None // no comprises clause 
    309315            case _ => return None // not a trait 
     
    311317        } else return None 
    312318      } 
    313       if ( meet.length == 1 ) Some(meet.head) 
    314       else  None 
     319      if ( meets.length == 1 ) { 
     320        val meet = meets.head 
     321        def nonExclusive(pair: (List[TraitType], List[TraitType])): Boolean = { 
     322          for ( first <- pair._1 - meet ) { 
     323            for ( second <- pair._2 - meet ) { 
     324              if ( typeAnalyzer.equivalent(first, second).isFalse && 
     325                   ! exclusionOracle.excludes(first, second) ) 
     326                return true 
     327            } 
     328          } 
     329          false 
     330        } 
     331        for ( first <- allComprises ) { 
     332          for ( second <- allComprises ; 
     333                if ! first._1.getText.equals(second._1.getText) ) { 
     334            if ( nonExclusive(first._2, second._2) ) return None 
     335          } 
     336        } 
     337        Some(meet) 
     338      } else  None 
    315339    } 
    316340 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/STypeChecker.scala

    r3870 r3875  
    484484                 overloading2: (ArrowType, List[StaticArg])): Boolean = { 
    485485 
    486       val SArrowType(_, domain1, range1, _) = overloading1._1 
    487       val SArrowType(_, domain2, range2, _) = overloading2._1 
     486      val SArrowType(_, domain1, range1, _, _) = overloading1._1 
     487      val SArrowType(_, domain2, range2, _, _) = overloading2._1 
    488488 
    489489      if (equivalentTypes(domain1, domain2)) false 
     
    699699      signal(application, message) 
    700700    } 
    701    
     701 
    702702  /** 
    703703   * Create an error message that will have type and expected type inserted. 
     
    706706  private def errorString(message: String): String = 
    707707    message + " has type %s, but it must have %s type." 
    708    
     708 
    709709  /** 
    710710   * Create an error message that will have type and expected type inserted. 
     
    856856                                   analyzer.extend(statics, wheres)) 
    857857      val newContract = contract.map(c => newChecker.check(c)) 
    858        
     858 
    859859      // If setter decl and no return type given, make it void. 
    860860      val returnType = 
     
    863863        else 
    864864          rType 
    865        
     865 
    866866      // Get the new return type and body. 
    867867      val (newReturnType, newBody) = returnType match { 
    868          
     868 
    869869        // If there is a declared return type, check the body, expecting this 
    870870        // type. If this is a setter, check that the return type is a void too. 
     
    874874          (Some(rt), newChecker.checkExpr(body, rt, errorString("Function body", 
    875875                                                                "declared return"))) 
    876            
     876 
    877877        case None => 
    878878          val newBody = newChecker.checkExpr(body) 
     
    983983  } 
    984984 
    985    
     985 
    986986  /** 
    987987   * Check an expression and guarantee that its type is substitutable for the 
     
    991991   * operators in it; the first is replaced with the actual type and the second 
    992992   * with the expected type. 
    993    *  
     993   * 
    994994   * @param expr The expression node to type check. 
    995995   * @param expected The expected type of this expression. 
     
    10051005    val checkedExpr = checkExpr(expr, Some(expected)) 
    10061006    getType(checkedExpr) match { 
    1007       case Some(typ) =>  
     1007      case Some(typ) => 
    10081008        isSubtype(typ, expected, expr, message.format(normalize(typ), normalize(expected))) 
    10091009        addType(checkedExpr, typ) 
     
    10271027   * Check an expression, returning the rewritten node. This overloading should 
    10281028   * be called whenever there is no expected type. 
    1029    *  
     1029   * 
    10301030   * @param expr The expression node to type check. 
    10311031   * @return The rewritten expression node. 
     
    10381038   * should only ever be called by the other two overloadings. That is, no cases 
    10391039   * in the implementation should call this method itself. 
    1040    *  
     1040   * 
    10411041   * @param expr The expression node to type check. 
    10421042   * @param expected The expected type of this expression, if there is one. 
     
    10471047  def checkExpr(expr: Expr, 
    10481048                expected: Option[Type]): Expr = expr match { 
    1049      
     1049 
    10501050    case o@SObjectExpr(SExprInfo(span,parenthesized,_), 
    10511051                     STraitTypeHeader(sparams, mods, name, where, 
     
    17191719                   bindIds, bindExpr, clauses, elseClause) => { 
    17201720      val (checkedExpr, checkedType) = bindExpr.map(checkExpr) match { 
    1721          
     1721 
    17221722        // If expr exists and was checked properly, make sure the bindIds are 
    17231723        // not shadowing. 
     
    17291729            }) 
    17301730          (Some(checkedE), getType(checkedE).getOrElse(return expr)) 
    1731          
     1731 
    17321732        // If expr does not exist, make sure thr bindIds are not mutable. 
    17331733        case _ => 
     
    17371737                         "binding expression cannot be a mutable variable: %s"). 
    17381738                           format(id))) 
    1739            
     1739 
    17401740          val idTypes = bindIds.map(getTypeFromName(_).getOrElse(return expr)) 
    17411741          (None, NodeFactory.makeMaybeTupleType(NodeUtil.getSpan(expr), 
    17421742                                                toJavaList(idTypes))) 
    17431743      } 
    1744        
     1744 
    17451745      // Check that the number of bindIds matches the size of the bindExpr. 
    17461746      val isMultipleIds = bindIds.size > 1 
     
    17701770          return c 
    17711771        } 
    1772          
     1772 
    17731773        // Construct the types that correspond to each id. 
    17741774        val newType = 
     
    17801780            List[Type](normalize(NodeFactory.makeIntersectionType(checkedType, matchType.first))) 
    17811781          } 
    1782          
     1782 
    17831783        val checkedBody = 
    17841784          this.extend(bindIds, newType). 
    17851785          checkExpr(body).asInstanceOf[Block] 
    1786          
     1786 
    17871787        STypecaseClause(info, matchType, checkedBody) 
    17881788      } 
     
    17901790      val clauseTypes = 
    17911791        checkedClauses.map(c => getType(c.getBody).getOrElse(return expr)) 
    1792        
     1792 
    17931793      // Check the else clause with the new binding. 
    17941794      val newType = 
     
    18021802            checkExpr(e).asInstanceOf[Block]) 
    18031803      val elseType = checkedElse.map(getType(_).getOrElse(return expr)) 
    1804        
     1804 
    18051805      // Build union type of all clauses and else. 
    18061806      val allTypes = elseType match { 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/TypeWellFormedChecker.scala

    r3805 r3875  
    129129        } 
    130130      // Effects are not yet supported... 
    131       case SArrowType(_, domain, range, effect) => walk(domain); walk(range) 
     131      case SArrowType(_, domain, range, effect, io) => walk(domain); walk(range) 
    132132      case SIntersectionType(_, elements) => elements.foreach((t:Type) => walk(t)) 
    133133      case SUnionType(_, elements) => elements.foreach((t:Type) => walk(t)) 
  • trunk/ProjectFortress/src/com/sun/fortress/tests/unit_tests/FileTests.java

    r3854 r3875  
    5555 
    5656public class FileTests { 
    57  
    58     private static String option = ""; 
    5957 
    6058    public static class BaseTest extends TestCase { 
     
    624622        protected int justTheTest() 
    625623                throws FileNotFoundException, IOException, Throwable { 
    626             String[] tokens; 
    627             if ( option.equals("") ) 
    628                 tokens = new String [] {"compile", dir+"/"+makeTestFileName(name)}; 
    629             else 
    630                 tokens = new String [] {"compile", option, dir+"/"+makeTestFileName(name)}; 
     624            String[] tokens = new String [] {"compile", dir+"/"+makeTestFileName(name)}; 
    631625            int rc = com.sun.fortress.Shell.subMain(tokens); 
    632626            return rc; 
     
    660654            throws FileNotFoundException, IOException, Throwable { 
    661655            // might need to strip the .fss off f "f". 
    662             String[] tokens; 
    663             if ( option.equals("") ) 
    664                 tokens = new String [] {"desugar", dir+"/"+makeTestFileName(name)}; 
    665             else 
    666                 tokens = new String [] {"desugar", option, dir+"/"+makeTestFileName(name)}; 
     656            String[] tokens = new String [] {"desugar", dir+"/"+makeTestFileName(name)}; 
    667657            int rc = com.sun.fortress.Shell.subMain(tokens); 
    668658            return rc; 
     
    695685                throws FileNotFoundException, IOException, Throwable { 
    696686            // might need to strip the .fss off f "f". 
    697             String[] tokens; 
    698             if ( option.equals("") ) 
    699                 tokens = new String [] {"link", dir+"/"+makeTestFileName(name)}; 
    700             else 
    701                 tokens = new String [] {"link", option, dir+"/"+makeTestFileName(name)}; 
     687            String[] tokens = new String [] {"link", dir+"/"+makeTestFileName(name)}; 
    702688            int rc = com.sun.fortress.Shell.subMain(tokens); 
    703689            return rc; 
    704  
    705  
    706690        } 
    707691 
     
    860844                                          boolean failsOnly, 
    861845                                          boolean expect_failure, 
    862                                           boolean scala_test) throws IOException { 
    863  
    864         if (scala_test) option = "-typecheck-scala"; 
     846                                          boolean typechecker_test) throws IOException { 
    865847 
    866848        TestSuite suite = new TestSuite("Runs all tests in " + dir_name) { 
     
    921903                          while  (st.hasMoreTokens()) { 
    922904                              String token = st.nextToken(); 
    923                               if (addTest(scala_test, token)) 
     905                              if (addTest(typechecker_test, token)) 
    924906                                  standardCompilerTests(props, dir, dirname, token, 
    925907                                                        expect_failure, shouldFail, failsOnly, 
     
    929911                      } 
    930912                      else { 
    931                           if (addTest(scala_test, testname)) 
     913                          if (addTest(typechecker_test, testname)) 
    932914                              standardCompilerTests(props, dir, dirname, testname, 
    933915                                                    expect_failure, shouldFail, failsOnly, 
     
    963945    } 
    964946 
    965     private static boolean addTest(boolean scala_test, 
     947    private static boolean addTest(boolean typechecker_test, 
    966948                                   String test_name) { 
    967         return ( ! scala_test 
     949        return ( ! typechecker_test 
    968950                 || test_name.startsWith("Compiled0") 
    969951                 || test_name.startsWith("Compiled1")