Changeset 3783

Show
Ignore:
Timestamp:
05/31/09 04:41:05 (6 months ago)
Author:
sukyoungryu
Message:

[static checker] Implemented static overloading checking of dotted method declarations with simple generics. Moved exclusion checking in Java code to the Scala checker. Eliminated calls of InterpreterBug?.bug in the static checker in Scala. Added a test.

Location:
trunk/ProjectFortress
Files:
2 added
10 modified

Legend:

Unmodified
Added
Removed
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/StaticChecker.java

    r3726 r3783  
    220220 
    221221                if (Shell.testCoercion()) { new CoercionTest(typeChecker).run(); } 
    222                      
     222 
    223223                component_ast = typeChecker.check(component_ast); 
    224224                result = new TypeCheckerResult(component_ast, 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/InferenceVarInserter.java

    r3782 r3783  
    11/******************************************************************************* 
    2     Copyright 2008 Sun Microsystems, Inc., 
     2    Copyright 2009 Sun Microsystems, Inc., 
    33    4150 Network Circle, Santa Clara, California 95054, U.S.A. 
    44    All rights reserved. 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/TypeAnalyzer.java

    r3717 r3783  
    141141    public TraitTable traitTable() { return _table; } 
    142142 
     143    public TypeEnv typeEnv() { return _typeEnv; } 
     144 
    143145    private TypeAnalyzer(TraitTable table, TypeEnv typeEnv, 
    144146            SubtypeCache parentCache) { 
     
    218220        public Type value(Type t) { return normalize(t); } 
    219221    }; 
    220  
    221     /* Checks whether two given types are exclusive. */ 
    222     /* Invariant: two types are not equal. */ 
    223     public boolean exclusion(Type s, Type t) { 
    224         return exc(normalize(s), normalize(t)); 
    225     } 
    226  
    227     /* The following TypeConsIndex's are not checked: 
    228      *     TypeAliasIndex 
    229      *     Dimension 
    230      *     Unit 
    231      * TupleType's with varargs parameters or keyword parameters are not supprted. 
    232      */ 
    233     private boolean exc(Type s, Type t) { 
    234         if ( s instanceof TraitType && t instanceof TraitType ) { 
    235             TraitType ss = (TraitType)s; 
    236             TraitType tt = (TraitType)t; 
    237             Option<TypeConsIndex> firstInd  = _table.typeCons(ss.getName()); 
    238             Option<TypeConsIndex> secondInd = _table.typeCons(tt.getName()); 
    239             if ( firstInd.isNone() ) 
    240                 throw new IllegalArgumentException("Unrecognized name: " + 
    241                                                    ss.getName()); 
    242             else if ( secondInd.isNone() ) 
    243                 throw new IllegalArgumentException("Unrecognized name: " + 
    244                                                    tt.getName()); 
    245             TypeConsIndex first  = firstInd.unwrap(); 
    246             TypeConsIndex second = secondInd.unwrap(); 
    247             if ( first instanceof TraitIndex && second instanceof TraitIndex ) { 
    248                 if ( ! (subtype(ss, tt).isTrue() || subtype(tt, ss).isTrue() ) && 
    249                      ( isClosedType(first) || isClosedType(second) ) ) 
    250                     return true; 
    251                 else if ( first  instanceof ProperTraitIndex && 
    252                           second instanceof ProperTraitIndex ) 
    253                     return exc(ss, tt, (ProperTraitIndex)second) || 
    254                            exc(tt, ss, (ProperTraitIndex)first); 
    255                 else return false; 
    256             } else return false; 
    257         } else if ( s instanceof VarType && t instanceof VarType ) { 
    258             Option<StaticParam> sParam = _typeEnv.staticParam(((VarType)s).getName()); 
    259             Option<StaticParam> tParam = _typeEnv.staticParam(((VarType)t).getName()); 
    260             if ( sParam.isNone() ) 
    261                 bug("We are being asked about some type that is not in scope: " + 
    262                     s + " @ " + NodeUtil.getSpan(s)); 
    263             if ( tParam.isNone() ) 
    264                 bug("We are being asked about some type that is not in scope: " + 
    265                     t + " @ " + NodeUtil.getSpan(t)); 
    266             StaticParam that = sParam.unwrap(); 
    267             if ( NodeUtil.isTypeParam( that ) ) { 
    268                 for ( BaseType ty : that.getExtendsClause() ) { 
    269                     if ( exclusion(ty, t) ) return true; 
    270                 } 
    271             } 
    272             that = tParam.unwrap(); 
    273             if ( NodeUtil.isTypeParam( that ) ) { 
    274                 for ( BaseType ty : that.getExtendsClause() ) { 
    275                     if ( exclusion(s, ty) ) return true; 
    276                 } 
    277             } 
    278             return false; 
    279         } else if ( s instanceof VarType ) { 
    280             Option<StaticParam> param = _typeEnv.staticParam(((VarType)s).getName()); 
    281             if ( param.isNone() ) 
    282                 bug("We are being asked about some type that is not in scope: " + 
    283                     s + " @ " + NodeUtil.getSpan(s)); 
    284             StaticParam that = param.unwrap(); 
    285             if ( NodeUtil.isTypeParam( that ) ) { 
    286                 for ( BaseType ty : that.getExtendsClause() ) { 
    287                     if ( exclusion(ty, t) ) return true; 
    288                 } 
    289             } 
    290             return false; 
    291         } else if ( t instanceof VarType ) { 
    292             Option<StaticParam> param = _typeEnv.staticParam(((VarType)t).getName()); 
    293             if ( param.isNone() ) 
    294                 bug("We are being asked about some type that is not in scope: " + 
    295                     t + " @ " + NodeUtil.getSpan(t)); 
    296             StaticParam that = param.unwrap(); 
    297             if ( NodeUtil.isTypeParam( that ) ) { 
    298                 for ( BaseType ty : that.getExtendsClause() ) { 
    299                     if ( exclusion(s, ty) ) return true; 
    300                 } 
    301             } 
    302             return false; 
    303         } else if ( s instanceof TupleType && t instanceof TupleType ) { 
    304             TupleType ss = (TupleType)s; 
    305             TupleType tt = (TupleType)t; 
    306             return ( ss.getVarargs().isNone() && tt.getVarargs().isNone() && 
    307                      ss.getKeywords().isEmpty() && tt.getKeywords().isEmpty() && 
    308                      ss.getElements().size() == tt.getElements().size() && 
    309                      existExc(ss.getElements(), tt.getElements()) ); 
    310         } else return false; 
    311     } 
    312  
    313     /* A type is a closed type if and only if 
    314      * it is an object trait type or 
    315      * it is a trait type with a comprises clause containing only closed types. 
    316      */ 
    317     private boolean isClosedType(TypeConsIndex s) { 
    318         if ( s instanceof ObjectTraitIndex ) return true; 
    319         else if ( s instanceof ProperTraitIndex ) { 
    320             Set<TraitType> comprises = ((ProperTraitIndex)s).comprisesTypes(); 
    321             if ( comprises.isEmpty() ) return false; 
    322             for ( TraitType t : comprises ) { 
    323                 Option<TypeConsIndex> index  = _table.typeCons(t.getName()); 
    324                 if ( index.isNone() ) 
    325                     throw new IllegalArgumentException("Unrecognized name: " + 
    326                                                        t.getName()); 
    327                 if ( ! isClosedType(index.unwrap()) ) return false; 
    328             } 
    329             return true; 
    330         } else return false; 
    331     } 
    332  
    333     /* Invariant: two lists of types are the same length. */ 
    334     private boolean existExc(List<Type> ss, List<Type> tt) { 
    335         int i = 0; 
    336         for ( Type s : ss ) { 
    337             if ( exclusion(s, tt.get(i++)) ) return true; 
    338         } 
    339         return false; 
    340     } 
    341  
    342     /* Exists "tau" in "[X |-> ty...]S" such that "s" is a subtype of "tau" 
    343      * where "t" is "T[\ty...\]" and "trait T[\X...\] ... excludes S ... end" 
    344      */ 
    345     private boolean exc(TraitType s, TraitType t, ProperTraitIndex tIndex) { 
    346         // staticParams: X... 
    347         List<StaticParam> staticParams = tIndex.staticParameters(); 
    348         // staticArgs  : ty... 
    349         List<StaticArg>   staticArgs   = t.getArgs(); 
    350         if ( staticParams.size() != staticArgs.size() ) 
    351             bug("The numbers of static parameters and static arguments do not match: " + t); 
    352         // subst       : [X |-> ty ...] 
    353         final Map<IdOrOp,Type> subst = new HashMap<IdOrOp,Type>(); 
    354         int i = 0; 
    355         for ( StaticParam sp : staticParams ) { 
    356             StaticArg arg = staticArgs.get(i++); 
    357             if ( arg instanceof TypeArg ) 
    358                 subst.put(sp.getName(), ((TypeArg)arg).getTypeArg()); 
    359         } 
    360         // excludes    : S 
    361         Set<TraitType> excludes = tIndex.excludesTypes(); 
    362         // [X |-> ty ...]S 
    363         for ( TraitType tau : excludes ) { 
    364             excludes.remove(tau); 
    365             excludes.add((TraitType)tau.accept(new NodeUpdateVisitor() { 
    366                         @Override 
    367                         public Node forVarTypeOnly(VarType that, TypeInfo info, Id name) { 
    368                             if ( subst.containsKey(name) ) { 
    369                                 return subst.get(name); 
    370                             } else return bug("Type variable " + that + " is unbound."); 
    371                         } 
    372                 })); 
    373         } 
    374         // Exists "tau" in "[X |-> ty ...]S" such that "s" is a subtype of "tau" 
    375         for ( TraitType tau : excludes ) { 
    376             if ( subtype(s, tau).isTrue() ) return true; 
    377         } 
    378         return false; 
    379     } 
    380222 
    381223    /** 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/CoercionOracle.scala

    r3726 r3783  
    3636class CoercionOracleFactory(traits: TraitTable, analyzer: TypeAnalyzer, errors: ErrorLog) { 
    3737  val coercionTable = makeCoercionTable() 
    38   val exclusionOracle = new ExclusionOracle(analyzer) 
     38  val exclusionOracle = new ExclusionOracle(analyzer, errors) 
    3939 
    4040  private def makeCoercionTable() = { 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/ExclusionOracle.scala

    r3717 r3783  
    1919 
    2020import _root_.java.util.ArrayList 
     21import _root_.java.util.{HashMap => JavaHashMap} 
    2122import _root_.java.util.{List => JavaList} 
    2223import _root_.java.util.{Set => JavaSet} 
     
    2526import com.sun.fortress.compiler.GlobalEnvironment 
    2627import com.sun.fortress.compiler.index.ComponentIndex 
     28import com.sun.fortress.compiler.index.ObjectTraitIndex 
     29import com.sun.fortress.compiler.index.ProperTraitIndex 
     30import com.sun.fortress.compiler.index.TypeConsIndex 
    2731import com.sun.fortress.compiler.index.{Function => JavaFunction} 
    2832import com.sun.fortress.compiler.typechecker.TypeAnalyzer 
    29 import com.sun.fortress.exceptions.InterpreterBug 
    3033import com.sun.fortress.exceptions.StaticError 
    3134import com.sun.fortress.exceptions.TypeError 
     
    3740import com.sun.fortress.repository.FortressRepository 
    3841import com.sun.fortress.scala_src.useful._ 
     42import com.sun.fortress.scala_src.useful.ErrorLog 
    3943import com.sun.fortress.scala_src.useful.Lists._ 
    4044import com.sun.fortress.scala_src.useful.Options._ 
     
    4246import com.sun.fortress.scala_src.nodes._ 
    4347 
    44 class ExclusionOracle(typeAnalyzer: TypeAnalyzer) { 
    45     /* Checks the overloading rule: exclusion 
    46      * Invariant: firstParam is not equal to secondParam 
    47      * The following types are not yet supported: 
    48      *     Types tagged with dimensions or units 
    49      *     Effects on arrow types 
    50      *     Keyword parameters and varargs parameters 
    51      *     Intersection types 
    52      *     Union types 
    53      *     Fixed-point types 
    54      */ 
    55     def excludes(first: Type, second: Type): Boolean = 
    56         (first, second) match { 
    57             case (SBottomType(_), _) => true 
    58             case (_, SBottomType(_)) => true 
    59             case (SAnyType(_), _) => false 
    60             case (_, SAnyType(_)) => false 
    61             case (SVarType(_,_,_), _) => 
    62                 typeAnalyzer.exclusion(first, second) 
    63             case (_, SVarType(_,_,_)) => 
    64                 typeAnalyzer.exclusion(first, second) 
    65             case (SArrowType(_,_,_,_), SArrowType(_,_,_,_)) => false 
    66             case (SArrowType(_,_,_,_), _) => true 
    67             case (_, SArrowType(_,_,_,_)) => true 
    68             case (f@STupleType(_,_,_,_), s@STupleType(_,_,_,_)) => 
    69                 NodeUtil.differentArity(f, s) || typeAnalyzer.exclusion(f, s) 
    70             case (STupleType(_,_,_,_) ,_) => true 
    71             case (_, STupleType(_,_,_,_)) => true 
    72             case _ => typeAnalyzer.exclusion(first, second) 
    73     } 
    74  
     48/* 
     49 * ToDo: Unlike subtyping checking, all the other checking such as 
     50 * exclusion checking and meet and join operations are not cached. 
     51 * We'll cache the results of those questions later. 
     52 */ 
     53class ExclusionOracle(typeAnalyzer: TypeAnalyzer, errors: ErrorLog) { 
     54  /* Checks the overloading rule: exclusion 
     55   * Invariant: firstParam is not equal to secondParam 
     56   * The following types are not yet supported: 
     57   *     Types tagged with dimensions or units 
     58   *     Effects on arrow types 
     59   *     Keyword parameters and varargs parameters 
     60   *     Intersection types 
     61   *     Union types 
     62   *     Fixed-point types 
     63   * The following TypeConsIndex's are not checked: 
     64   *     TypeAliasIndex 
     65   *     Dimension 
     66   *     Unit 
     67   * TupleType's with varargs parameters or keyword parameters are not supprted. 
     68   */ 
     69  def excludes(first: Type, second: Type): Boolean = 
     70    ( typeAnalyzer.normalize(first), typeAnalyzer.normalize(second) ) match { 
     71      case (SBottomType(_), _) => true 
     72      case (_, SBottomType(_)) => true 
     73      case (SAnyType(_), _) => false 
     74      case (_, SAnyType(_)) => false 
     75      case (f@SVarType(_,_,_), s@SVarType(_,_,_)) => 
     76        ( toOption(typeAnalyzer.typeEnv.staticParam(f.getName)), 
     77          toOption(typeAnalyzer.typeEnv.staticParam(s.getName)) ) match { 
     78          case (Some(fp), Some(sp)) => 
     79            var result = false 
     80            if ( NodeUtil.isTypeParam( fp ) ) { 
     81              for ( ty <- toList(fp.getExtendsClause) ; if ! result ) { 
     82                if ( excludes(ty, s) ) result = true 
     83              } 
     84            } 
     85            if ( NodeUtil.isTypeParam( sp ) ) { 
     86              for ( ty <- toList(sp.getExtendsClause) ; if ! result ) { 
     87                if ( excludes(ty, f) ) result = true 
     88              } 
     89            } 
     90            result 
     91          case (None, Some(_)) => 
     92            errors.signal("We are being asked about some type that is not in scope:\n    " + 
     93                          f, NodeUtil.getSpan(f)) 
     94            false 
     95          case (_, None) => 
     96            errors.signal("We are being asked about some type that is not in scope:\n    " + 
     97                          s, NodeUtil.getSpan(s)) 
     98            false 
     99          case _ => 
     100            errors.signal("We are being asked about some type that is not in scope:\n    " + 
     101                          f, NodeUtil.getSpan(f)) 
     102            errors.signal("We are being asked about some type that is not in scope:\n    " + 
     103                          s, NodeUtil.getSpan(s)) 
     104            false 
     105        } 
     106      case (f@SVarType(_,_,_), _) => 
     107        toOption(typeAnalyzer.typeEnv.staticParam(f.getName)) match { 
     108          case Some(fp) => 
     109            var result = false 
     110            if ( NodeUtil.isTypeParam( fp ) ) { 
     111              for ( ty <- toList(fp.getExtendsClause) ; if ! result ) { 
     112                if ( excludes(ty, second) ) result = true 
     113              } 
     114            } 
     115            result 
     116          case _ => 
     117            errors.signal("We are being asked about some type that is not in scope:\n    " + 
     118                          f, NodeUtil.getSpan(f)) 
     119            false 
     120        } 
     121      case (_, s@SVarType(_,_,_)) => 
     122        toOption(typeAnalyzer.typeEnv.staticParam(s.getName)) match { 
     123          case Some(sp) => 
     124            var result = false 
     125            if ( NodeUtil.isTypeParam( sp ) ) { 
     126              for ( ty <- toList(sp.getExtendsClause) ; if ! result ) { 
     127                if ( excludes(ty, first) ) result = true 
     128              } 
     129            } 
     130            result 
     131          case _ => 
     132            errors.signal("We are being asked about some type that is not in scope:\n    " + 
     133                          s, NodeUtil.getSpan(s)) 
     134            false 
     135        } 
     136      case (SArrowType(_,_,_,_), SArrowType(_,_,_,_)) => false 
     137      case (SArrowType(_,_,_,_), _) => true 
     138      case (_, SArrowType(_,_,_,_)) => true 
     139      case (f@STupleType(_,_,_,_), s@STupleType(_,_,_,_)) => 
     140        NodeUtil.differentArity(f, s) || { 
     141          f.getVarargs.isNone && s.getVarargs.isNone && 
     142          f.getKeywords.isEmpty && s.getKeywords.isEmpty && 
     143          f.getElements.size == s.getElements.size && 
     144          toList(f.getElements).zip(toList(s.getElements)).exists((e:(Type,Type)) => 
     145                                                                  excludes(e._1,e._2)) 
     146        } 
     147      case (STupleType(_,_,_,_) ,_) => true 
     148      case (_, STupleType(_,_,_,_)) => true 
     149      case (f@STraitType(_,_,_,_), s@STraitType(_,_,_,_)) => 
     150        ( toOption(typeAnalyzer.traitTable.typeCons(f.getName)), 
     151          toOption(typeAnalyzer.traitTable.typeCons(s.getName)) ) match { 
     152          case (Some(fi), Some(si)) => 
     153            ( NodeUtil.isTraitOrObject(fi), NodeUtil.isTraitOrObject(si) ) match { 
     154              case (true, true) => 
     155                if ( ! (typeAnalyzer.subtype(f, s).isTrue || 
     156                        typeAnalyzer.subtype(s, f).isTrue ) && 
     157                     ( isClosedType(fi) || isClosedType(si) ) ) 
     158                  return true 
     159                else if ( fi.isInstanceOf[ProperTraitIndex] && 
     160                          si.isInstanceOf[ProperTraitIndex] ) 
     161                  excludes(f, s, si.asInstanceOf[ProperTraitIndex]) || 
     162                  excludes(s, f, fi.asInstanceOf[ProperTraitIndex]) 
     163                else false 
     164              case _ => false 
     165            } 
     166          case (None, Some(_)) => 
     167            errors.signal("Unrecognized name: " + f.getName, NodeUtil.getSpan(f)) 
     168            false 
     169          case (_, None) => 
     170            errors.signal("Unrecognized name: " + s.getName, NodeUtil.getSpan(s)) 
     171            false 
     172          case _ => 
     173            errors.signal("Unrecognized name: " + f.getName, NodeUtil.getSpan(f)) 
     174            errors.signal("Unrecognized name: " + s.getName, NodeUtil.getSpan(s)) 
     175            false 
     176        } 
     177      case _ => false 
     178    } 
     179 
     180  /* Exists "tau" in "[X |-> ty...]S" such that "s" is a subtype of "tau" 
     181   * where "t" is "T[\ty...\]" and "trait T[\X...\] ... excludes S ... end" 
     182   */ 
     183  private def excludes(s: TraitType, t: TraitType, tIndex: ProperTraitIndex) = { 
     184    // staticParams: X... 
     185    val staticParams = toList(tIndex.staticParameters) 
     186    // staticArgs  : ty... 
     187    val staticArgs   = toList(t.getArgs) 
     188    if ( staticParams.size != staticArgs.size ) 
     189      errors.signal("The numbers of static parameters and static arguments do not match: " + t, 
     190                    NodeUtil.getSpan(t)) 
     191    // subst       : [X |-> ty ...] 
     192    val subst = new JavaHashMap[IdOrOp,Type]() 
     193    staticParams.zip(staticArgs).foreach( (pair:(StaticParam,StaticArg)) => 
     194                                          if ( pair._2.isInstanceOf[TypeArg] ) 
     195                                            subst.put(pair._1.getName, 
     196                                                      pair._2.asInstanceOf[TypeArg].getTypeArg) ) 
     197    // excludes    : S 
     198    var excludes: Set[TraitType] = toSet(tIndex.excludesTypes) 
     199    // [X |-> ty ...]S 
     200    def saSubst(sa: StaticArg): StaticArg = sa match { 
     201      case STypeArg(i,t) => STypeArg(i, tySubst(t) ) 
     202      case _ => sa 
     203    } 
     204    def spSubst(sp: StaticParam): StaticParam = sp match { 
     205      case SStaticParam(i,n,e,d,a,k) => 
     206        SStaticParam(i, n, e.map(tySubst).asInstanceOf[List[BaseType]], d, a, k) 
     207    } 
     208    def tySubst(tau: Type): Type = tau match { 
     209      case SVarType(_,name,_) => 
     210        if ( subst.containsKey(name) ) subst.get(name) 
     211        else { 
     212          errors.signal("Type variable " + tau + " is unbound.", NodeUtil.getSpan(tau)) 
     213          tau 
     214        } 
     215      case STraitType(i,n,a,p) => STraitType(i, n, a.map(saSubst), p.map(spSubst)) 
     216      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) 
     218      case _ => tau 
     219    } 
     220    excludes = excludes.map( tySubst ).asInstanceOf[Set[TraitType]] 
     221    var result = false 
     222    // Exists "tau" in "[X |-> ty ...]S" such that "s" is a subtype of "tau" 
     223    for ( tau <- excludes ; if ! result ) { 
     224        if ( typeAnalyzer.subtype(s, tau).isTrue ) result = true 
     225    } 
     226    result 
     227  } 
     228 
     229  /* A type is a closed type if and only if 
     230   * it is an object trait type or 
     231   * it is a trait type with a comprises clause containing only closed types. 
     232   */ 
     233  private def isClosedType(s: TypeConsIndex): Boolean = 
     234    if ( s.isInstanceOf[ObjectTraitIndex] ) true 
     235    else if ( s.isInstanceOf[ProperTraitIndex] ) { 
     236      val comprises = toSet(s.asInstanceOf[ProperTraitIndex].comprisesTypes) 
     237      if ( comprises.isEmpty ) false 
     238      else { 
     239        var result = true 
     240        for ( t <- comprises ; if result ) { 
     241          toOption(typeAnalyzer.traitTable.typeCons(t.getName)) match { 
     242            case None => 
     243              errors.signal("Unrecognized name: " + t.getName, NodeUtil.getSpan(t)) 
     244            case Some(ind) => 
     245              if ( ! isClosedType(ind) ) result = false 
     246          } 
     247        } 
     248        result 
     249      } 
     250    } else false 
    75251} 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/ExportChecker.scala

    r3766 r3783  
    3131import com.sun.fortress.compiler.index.{Constructor => JavaConstructor} 
    3232import com.sun.fortress.compiler.index.{DeclaredFunction => JavaDeclaredFunction} 
     33import com.sun.fortress.compiler.index.{DeclaredMethod => JavaDeclaredMethod} 
     34import com.sun.fortress.compiler.index.{FieldGetterMethod => JavaFieldGetterMethod} 
     35import com.sun.fortress.compiler.index.{FieldSetterMethod => JavaFieldSetterMethod} 
    3336import com.sun.fortress.compiler.index.{DeclaredVariable => JavaDeclaredVariable} 
    3437import com.sun.fortress.compiler.index.{Dimension => JavaDimension} 
     
    713716object FunctionalMethod { 
    714717    def unapply(function:JavaFunctionalMethod) = 
    715         Some(function.ast, function.declaringTrait) 
     718        Some((function.ast, function.declaringTrait)) 
    716719    def apply(fndecl:FnDecl, id:Id) = 
    717720        new JavaFunctionalMethod(fndecl, id) 
    718721} 
     722 
     723object DeclaredMethod { 
     724    def unapply(method:JavaDeclaredMethod) = 
     725        Some((method.ast, method.getDeclaringTrait)) 
     726    def apply(fndecl:FnDecl, id:Id) = 
     727        new JavaDeclaredMethod(fndecl, id) 
     728} 
     729 
     730object FieldGetterMethod { 
     731    def unapply(method:JavaFieldGetterMethod) = 
     732        Some((method.ast, method.getDeclaringTrait)) 
     733    def apply(binding:Binding, id:Id) = 
     734        new JavaFieldGetterMethod(binding, id) 
     735} 
     736 
     737object FieldSetterMethod { 
     738    def unapply(method:JavaFieldSetterMethod) = 
     739        Some((method.ast, method.getDeclaringTrait)) 
     740    def apply(binding:Binding, id:Id) = 
     741        new JavaFieldSetterMethod(binding, id) 
     742} 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala

    r3766 r3783  
    2727import com.sun.fortress.compiler.index.TraitIndex 
    2828import com.sun.fortress.compiler.index.{Function => JavaFunction} 
     29import com.sun.fortress.compiler.index.{Functional => JavaFunctional} 
     30import com.sun.fortress.compiler.index.{Method => JavaMethod} 
    2931import com.sun.fortress.compiler.typechecker.TypeAnalyzer 
    3032import com.sun.fortress.exceptions.InterpreterBug 
     
    6062                         repository: FortressRepository) { 
    6163 
    62     val typeAnalyzer = TypeAnalyzer.make(new TraitTable(compilation_unit, globalEnv)) 
    63     val exclusionOracle = new ExclusionOracle(typeAnalyzer) 
     64    var typeAnalyzer = TypeAnalyzer.make(new TraitTable(compilation_unit, globalEnv)) 
    6465    var errors = List[StaticError]() 
    6566 
     
    7071        val fnsInComp = compilation_unit.functions 
    7172        for ( f <- toSet(fnsInComp.firstSet) ; if isDeclaredName(f) ) { 
    72             checkOverloading(f, fnsInComp.matchFirst(f)) 
     73            checkOverloading(f, toSet(fnsInComp.matchFirst(f)).asInstanceOf[Set[JavaFunctional]]) 
    7374        } 
    7475        val typesInComp = compilation_unit.typeConses 
     
    9495                } 
    9596            } 
    96             /* 
    97             val methods = typesInComp.get(t).asInstanceOf[TraitIndex].dottedMethods 
     97            val methods = traitOrObject.dottedMethods 
     98            val staticParameters = new ArrayList[StaticParam]() 
     99            // Add static parameters of the enclosing trait or object 
     100            staticParameters.addAll( traitOrObject.staticParameters ) 
     101            // Extend the type analyzer with the collected static parameters 
     102            val oldTypeAnalyzer = typeAnalyzer 
    98103            for ( f <- toSet(methods.firstSet) ; if isDeclaredName(f) ) { 
    99                 checkOverloading(f, methods.matchFirst(f).asInstanceOf[JavaSet[JavaFunctional]]) 
    100             } 
    101             */ 
     104                typeAnalyzer = typeAnalyzer.extend(staticParameters, none[WhereClause]) 
     105                checkOverloading(f, toSet(methods.matchFirst(f)).asInstanceOf[Set[JavaFunctional]]) 
     106            } 
     107            typeAnalyzer = oldTypeAnalyzer 
    102108        } 
    103109        toJavaList(errors) 
     
    106112    /* Checks the validity of the overloaded function declarations. */ 
    107113    private def checkOverloading(name: IdOrOpOrAnonymousName, 
    108                                  set: JavaSet[JavaFunction]) = { 
    109         var signatures = List[((Type,Type),Span)]() 
    110         for ( f <- toSet(set) ; if isDeclaredFunction(f) ) { 
     114                                 set: Set[JavaFunctional]) = { 
     115        var signatures = List[((JavaList[StaticParam],Type,Type),Span)]() 
     116        for ( f <- set ; if isDeclaredFunctional(f) ) { 
    111117            val result = f.getReturnType 
    112118            val param = paramsToType(f.parameters, f.getSpan) 
    113             signatures.find(p => p._1 == (param,result)) match { 
     119            val sparams = f.staticParameters 
     120            signatures.find(p => p._1 == (sparams,param,result)) match { 
    114121                case Some((_,span)) => 
    115122                    error(mergeSpan(span, f.getSpan), 
     
    118125                          param + " -> " + result) 
    119126                case _ => 
    120                     signatures = ((param, result), f.getSpan) :: signatures 
     127                    signatures = ((sparams, param, result), f.getSpan) :: signatures 
    121128            } 
    122129        } 
     
    140147 
    141148    /* Checks the overloading rules: subtype / exclusion / meet */ 
    142     private def validOverloading(first: ((Type,Type),Span), 
    143                                  second: ((Type,Type),Span), 
    144                                  set: List[((Type,Type),Span)]) = 
     149    private def validOverloading(first: ((JavaList[StaticParam],Type,Type),Span), 
     150                                 second: ((JavaList[StaticParam],Type,Type),Span), 
     151                                 set: List[((JavaList[StaticParam],Type,Type),Span)]) = 
    145152        subtype(first, second) || subtype(second, first) || 
    146153        exclusion(first, second) || meet(first, second, set) 
    147154 
    148155    /* Checks the overloading rule: subtype */ 
    149     private def subtype(newTypeAnalyzer: TypeAnalyzer, f: JavaFunction, 
    150                         g: JavaFunction): Boolean = 
    151         subtype(newTypeAnalyzer, paramsToType(g.parameters, g.getSpan), 
     156    private def subtype(f: JavaFunction, g: JavaFunction): Boolean = 
     157        subtype(paramsToType(g.parameters, g.getSpan), 
    152158                paramsToType(f.parameters, f.getSpan)) && 
    153         subtype(newTypeAnalyzer, f.getReturnType, g.getReturnType) 
    154  
    155     private def subtype(newTypeAnalyzer: TypeAnalyzer, sub_type: Type, 
    156                         super_type: Type): Boolean = 
    157         newTypeAnalyzer.subtype(sub_type, super_type).isTrue 
     159        subtype(f.getReturnType, g.getReturnType) 
    158160 
    159161    private def subtype(sub_type: Type, super_type: Type): Boolean = 
    160         subtype(typeAnalyzer, sub_type, super_type) 
    161  
    162     private def subtype(sub_type: ((Type,Type),Span), 
    163                         super_type: ((Type,Type),Span)): Boolean = 
    164         subtype(super_type._1._1, sub_type._1._1) && 
    165         subtype(sub_type._1._2, super_type._1._2) 
     162        typeAnalyzer.subtype(sub_type, super_type).isTrue 
     163 
     164    private def subtype(sub_type: ((JavaList[StaticParam],Type,Type),Span), 
     165                        super_type: ((JavaList[StaticParam],Type,Type),Span)): Boolean = { 
     166        val oldTypeAnalyzer = typeAnalyzer 
     167        // Add static parameters of the method 
     168        val staticParameters = new ArrayList[StaticParam]() 
     169        staticParameters.addAll(sub_type._1._1) 
     170        staticParameters.addAll(super_type._1._1) 
     171        typeAnalyzer = typeAnalyzer.extend(staticParameters, none[WhereClause]) 
     172        val result = subtype(super_type._1._2, sub_type._1._2) && 
     173                     subtype(sub_type._1._3, super_type._1._3) 
     174        typeAnalyzer = oldTypeAnalyzer 
     175        result 
     176    } 
    166177 
    167178    /* Checks the overloading rule: exclusion 
     
    175186     *     Fixed-point types 
    176187     */ 
    177     private def exclusion(first: ((Type,Type),Span), 
    178                           second: ((Type,Type),Span)): Boolean = 
    179         exclusionOracle.excludes(first._1._1, second._1._1) 
     188    private def exclusion(first: ((JavaList[StaticParam],Type,Type),Span), 
     189                          second: ((JavaList[StaticParam],Type,Type),Span)): Boolean = { 
     190        val oldTypeAnalyzer = typeAnalyzer 
     191        // Add static parameters of the method 
     192        val staticParameters = new ArrayList[StaticParam]() 
     193        staticParameters.addAll(first._1._1) 
     194        staticParameters.addAll(second._1._1) 
     195        typeAnalyzer = typeAnalyzer.extend(staticParameters, none[WhereClause]) 
     196        val result = new ExclusionOracle(typeAnalyzer, 
     197                                         new ErrorLog()).excludes(first._1._2, 
     198                                                                  second._1._2) 
     199        typeAnalyzer = oldTypeAnalyzer 
     200        result 
     201    } 
    180202 
    181203    /* Checks the overloading rule: meet */ 
    182204    /* Not yet fully implemented... */ 
    183     private def meet(first: ((Type,Type),Span), second: ((Type,Type),Span), 
    184                      set: List[((Type,Type),Span)]) = { 
     205    private def meet(first: ((JavaList[StaticParam],Type,Type),Span), 
     206                     second: ((JavaList[StaticParam],Type,Type),Span), 
     207                     set: List[((JavaList[StaticParam],Type,Type),Span)]) = { 
     208        val oldTypeAnalyzer = typeAnalyzer 
     209        // Add static parameters of the method 
     210        val staticParameters = new ArrayList[StaticParam]() 
     211        staticParameters.addAll(first._1._1) 
     212        staticParameters.addAll(second._1._1) 
     213        typeAnalyzer = typeAnalyzer.extend(staticParameters, none[WhereClause]) 
    185214        var result = false 
    186         val meet = (reduce(typeAnalyzer.meet(first._1._1, second._1._1)), 
    187                     reduce(typeAnalyzer.meet(first._1._2, second._1._2))) 
     215        val meet = (reduce(typeAnalyzer.meet(first._1._2, second._1._2)), 
     216                    reduce(typeAnalyzer.meet(first._1._3, second._1._3))) 
    188217        for ( f <- set ; if ! result ) 
    189             if ( subtype(f._1._1, meet._1) && 
    190                  subtype(meet._1, f._1._1) && 
    191                  subtype(meet._2, f._1._2) && 
    192                  subtype(f._1._2, meet._2)) 
     218            if ( subtype(f._1._2, meet._1) && 
     219                 subtype(meet._1, f._1._2) && 
     220                 subtype(meet._2, f._1._3) && 
     221                 subtype(f._1._3, meet._2)) 
    193222                result = true 
     223        typeAnalyzer = oldTypeAnalyzer 
    194224        result 
    195225    } 
     
    260290        for ( s <- toList(g.staticParameters) ) staticParameters.add(s) 
    261291        // Extend the type analyzer with the collected static parameters 
    262         val newTypeAnalyzer = typeAnalyzer.extend(staticParameters, 
    263                                                   none[WhereClause]) 
     292        val oldTypeAnalyzer = typeAnalyzer 
    264293        // Whether "g"'s parameter type is a subtype of "f"'s parameter type 
    265294        // and "f"'s return type is a subtype of "g"'s return type 
    266         subtype(newTypeAnalyzer, f, g) 
     295        typeAnalyzer = typeAnalyzer.extend(staticParameters, none[WhereClause]) 
     296        val result = subtype(f, g) 
     297        typeAnalyzer = oldTypeAnalyzer 
     298        result 
    267299    } 
    268300 
     
    273305    } 
    274306 
    275     def isDeclaredFunction(f: JavaFunction) = f match { 
     307    def isDeclaredFunctional(f: JavaFunctional) = f match { 
    276308        case DeclaredFunction(fd) => true 
     309        case DeclaredMethod(_,_) => true 
    277310        case _ => false 
    278311    } 
    279312 
    280     private def mergeSpan(sub_type: ((Type,Type),Span), 
    281                           super_type: ((Type,Type),Span)): String = 
     313    private def mergeSpan(sub_type: ((JavaList[StaticParam],Type,Type),Span), 
     314                          super_type: ((JavaList[StaticParam],Type,Type),Span)): String = 
    282315        mergeSpan(sub_type._2, super_type._2) 
    283316 
     
    288321            second.toString + ":\n" + first.toString 
    289322 
    290     private def toString(ty: ((Type,Type), Span)): String = 
    291         ty._1._1 + " -> " + ty._1._2 + " @ " + ty._2 
     323    private def toString(ty: ((JavaList[StaticParam],Type,Type), Span)): String = 
     324        ty._1._2 + " -> " + ty._1._3 + " @ " + ty._2 
    292325 
    293326    /* Returns the type of the given list of parameters. */ 
     
    305338        toOption(param.getIdType) match { 
    306339            case Some(ty) => ty 
    307             case _ => InterpreterBug.bug(param, 
    308                                          "Type checking couldn't infer the type of " + param) 
     340            case _ => 
     341                toOption(param.getVarargsType) match { 
     342                    case Some(ty) => ty 
     343                    case _ => 
     344                        val span = NodeUtil.getSpan(param) 
     345                        error(span.toString, 
     346                              "Type checking couldn't infer the type of " + param) 
     347                        NodeFactory.makeVoidType(span) 
     348                } 
    309349        } 
    310350 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/STypeChecker.scala

    r3763 r3783  
    5454import com.sun.fortress.scala_src.useful.Lists._ 
    5555import com.sun.fortress.scala_src.useful.Options._ 
    56 import com.sun.fortress.exceptions.InterpreterBug.bug 
    5756import com.sun.fortress.useful.HasAt 
    5857 
     
    830829            if ( isArrows(first) ) { 
    831830              val (arrows,temp) = (first::rest).span(isArrows) 
    832               val (nonArrows,remainingChunks) = temp.span((e:Expr) => ! isArrows(e))  
     831              val (nonArrows,remainingChunks) = temp.span((e:Expr) => ! isArrows(e)) 
    833832              chunker(remainingChunks, (arrows,nonArrows)::results) 
    834833            } else { 
     
    849848        def associateArrows(fs: List[Expr], oe: Option[Expr]) = oe match { 
    850849          case None => fs match { 
    851             case Nil => bug(expr, "Empty chunk") 
     850            case Nil => 
     851              errors.signal("Empty chunk", expr) 
     852              expr 
    852853            case _ => 
    853854              fs.take(fs.size-1).foldRight(fs.last){ (f: Expr, e: Expr) => 
     
    887888          // If not, left associate as InfixJuxts 
    888889          associatedChunks match { 
    889             case Nil => bug(expr, "Empty juxt") 
     890            case Nil => 
     891              errors.signal("Empty juxt", expr) 
     892              expr 
    890893            case head::tail => 
    891894              checkExpr(tail.foldLeft(head){ (e1: Expr, e2: Expr) => 
  • trunk/ProjectFortress/test

    r3780 r3783  
    22 
    33################################################################################ 
    4 #    Copyright 2008 Sun Microsystems, Inc., 
     4#    Copyright 2009 Sun Microsystems, Inc., 
    55#    4150 Network Circle, Santa Clara, California 95054, U.S.A. 
    66#    All rights reserved. 
     
    2121SCALAVER=2.7.4 
    2222 
    23 if (uname | egrep -q CYGWIN) ; then  
     23if (uname | egrep -q CYGWIN) ; then 
    2424  CP="build;$TP/junit/junit.jar;$TP/unsigned/unsigned.jar;$TP/asm/asm-all-3.1.jar;$TP/xtc/xtc.jar;$TP/jsr166y/jsr166y.jar;$TP/plt/plt.jar;$TP/astgen/astgen.jar;$TP/scala/scala-library-$SCALAVER.jar" 
    2525else 
  • trunk/ProjectFortress/tests/Reversals.fss

    r3779 r3783  
     1(******************************************************************************* 
     2    Copyright 2009 Sun Microsystems, Inc., 
     3    4150 Network Circle, Santa Clara, California 95054, U.S.A. 
     4    All rights reserved. 
     5 
     6    U.S. Government Rights - Commercial software. 
     7    Government users are subject to the Sun Microsystems, Inc. standard 
     8    license agreement and applicable provisions of the FAR and its supplements. 
     9 
     10    Use is subject to license terms. 
     11 
     12    This distribution may include materials developed by third parties. 
     13 
     14    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered 
     15    trademarks of Sun Microsystems, Inc. in the U.S. and other countries. 
     16 ******************************************************************************) 
     17 
    118component Reversals 
    219import List.{...} 
    320export Executable 
    4  
    5  
    621 
    722run() = do