Changeset 4309 for trunk

Show
Ignore:
Timestamp:
11/03/09 15:19:06 (3 weeks ago)
Author:
jmaessen
Message:

[static checks] Fixed massive bugs in the AbstractMethodChecker
(tested for in Compiled12.inherit). Modified
STypesUtil.inheritedMethods to avoid using a Frankensteinian
combination of plt and Scala tuple types, and to account for getter
and setter methods as well as ordinary and functional methods.

Location:
trunk/ProjectFortress
Files:
9 modified

Legend:

Unmodified
Added
Removed
  • trunk/ProjectFortress/compiler_tests/Compiled12.inherit.fss

    r4305 r4309  
    2020trait T comprises { U, V } 
    2121  abstract getter asString(): String 
     22  abstract getter foo(): String 
    2223  abstract m(t:T): T 
    2324  abstract mv(v:V): T 
     25  abstract leaf(): T 
    2426end 
    2527 
    2628object U extends T 
    2729  getter asString(): String = "U" 
     30  getter foo(): String = "U" 
    2831  m(t:T): T = t 
    2932  mv(v:V): T = v 
     33  leaf(): T = self 
    3034end 
    3135 
    3236trait V extends T comprises { W, X } 
     37  getter foo(): String = "V" 
     38  getter k(): String 
    3339  m(t:T): T = t.mv(self) 
    3440  mv(v:V): T = self 
     
    3743object W extends V 
    3844  getter asString(): String = "W" 
     45  getter k(): String = "WW" 
     46  leaf(): T = self 
    3947end 
    4048 
    4149object X extends V 
    4250  getter asString(): String = "X" 
     51  getter k(): String = "XX" 
     52  leaf(): T = self 
    4353end 
    4454 
     
    5363    println("W" X.m(W).asString) 
    5464    println("X" X.m(X).asString) 
     65    println("U" U.foo) 
     66    println("V" W.foo) 
     67    println("V" X.foo) 
     68    println("U" U.leaf().asString) 
     69    println("W" W.leaf().asString) 
     70    println("X" X.leaf().asString) 
    5571  end 
  • trunk/ProjectFortress/compiler_tests/Compiled12.inherit.test

    r4305 r4309  
    2626XX\n\ 
    2727WW\n\ 
     28XX\n\ 
     29UU\n\ 
     30VV\n\ 
     31VV\n\ 
     32UU\n\ 
     33WW\n\ 
    2834XX\n 
  • trunk/ProjectFortress/src/com/sun/fortress/compiler/index/TraitIndex.java

    r4259 r4309  
    4545 
    4646    public TraitIndex(TraitObjectDecl ast, Map<Id, Method> getters, Map<Id, Method> setters, Set<Coercion> coercions, Relation<IdOrOpOrAnonymousName, DeclaredMethod> dottedMethods, Relation<IdOrOpOrAnonymousName, FunctionalMethod> functionalMethods) { 
    47         _ast = ast; 
    48         _getters = getters; 
    49         _setters = setters; 
    50         _coercions = coercions; 
    51         _dottedMethods = dottedMethods; 
    52         _functionalMethods = functionalMethods; 
     47        _ast = ast; 
     48        _getters = getters; 
     49        _setters = setters; 
     50        _coercions = coercions; 
     51        _dottedMethods = dottedMethods; 
     52        _functionalMethods = functionalMethods; 
    5353    } 
    5454 
    5555    public TraitObjectDecl ast() { 
    56         return _ast; 
     56        return _ast; 
    5757    } 
    5858 
    5959    public Option<Type> typeOfSelf() { 
    60         if (this.ast() instanceof TraitObjectDecl) { 
    61             return ((TraitObjectDecl) this.ast()).getSelfType(); 
    62         } 
    63         return Option.<Type>none(); 
     60        if (this.ast() instanceof TraitObjectDecl) { 
     61            return ((TraitObjectDecl) this.ast()).getSelfType(); 
     62        } 
     63        return Option.<Type>none(); 
    6464    } 
    6565 
    6666    public List<StaticParam> staticParameters() { 
    67         return NodeUtil.getStaticParams(_ast); 
     67        return NodeUtil.getStaticParams(_ast); 
    6868    } 
    6969 
    7070    public List<Id> hiddenParameters() { 
    71         return Collections.emptyList(); 
     71        return Collections.emptyList(); 
    7272    } 
    7373 
     
    7878     */ 
    7979    public Iterable<Pair<Type, Type>> typeConstraints() { 
    80         return IterUtil.empty(); 
     80        return IterUtil.empty(); 
    8181    } 
    8282 
    8383    public List<TraitTypeWhere> extendsTypes() { 
    84         return NodeUtil.getExtendsClause(_ast); 
     84        return NodeUtil.getExtendsClause(_ast); 
    8585    } 
    8686 
    8787    public Map<Id, Method> getters() { 
    88         return _getters; 
     88        return _getters; 
    8989    } 
    9090 
    9191    public Map<Id, Method> setters() { 
    92         return _setters; 
     92        return _setters; 
    9393    } 
    9494 
    9595    public Set<Coercion> coercions() { 
    96         return _coercions; 
     96        return _coercions; 
    9797    } 
    9898 
    9999    public Relation<IdOrOpOrAnonymousName, DeclaredMethod> dottedMethods() { 
    100         return _dottedMethods; 
     100        return _dottedMethods; 
    101101    } 
    102102 
    103103    public Relation<IdOrOpOrAnonymousName, FunctionalMethod> functionalMethods() { 
    104         return _functionalMethods; 
     104        return _functionalMethods; 
    105105    } 
    106106 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/disambiguator/ExprDisambiguator.scala

    r4296 r4309  
    911911      {(res, t) => (res, t) match { 
    912912         case ((accessors, methods), STraitTypeWhere(_, base, where)) 
    913               if ! hist.hasExplored(base) => 
    914            hist.explore(base) 
     913              if hist.explore(base) => 
    915914           // Trait types or VarTypes can represent traits at this phase of compilation. 
    916915           base match { 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/AbstractMethodChecker.scala

    r4304 r4309  
    2525import com.sun.fortress.compiler.GlobalEnvironment 
    2626import com.sun.fortress.compiler.index.ComponentIndex 
     27import com.sun.fortress.compiler.index.{DeclaredMethod => JavaDeclaredMethod} 
     28import com.sun.fortress.compiler.index.FieldGetterOrSetterMethod 
    2729import com.sun.fortress.compiler.index.{Functional => JavaFunctional} 
     30import com.sun.fortress.compiler.index.{FunctionalMethod => JavaFunctionalMethod} 
    2831import com.sun.fortress.compiler.index.HasSelfType 
    2932import com.sun.fortress.compiler.index.TraitIndex 
     
    7073                    walk(decls).asInstanceOf[List[Decl]]) 
    7174        val inherited = inheritedMethods(traits, extendsC, Set(), typeAnalyzer) 
    72                         .map(t => t.first.asInstanceOf[IdOrOp].getText) 
     75                        .map(t => t._1.asInstanceOf[IdOrOp].getText) 
    7376        for ( d <- decls ; if d.isInstanceOf[FnDecl] ) { 
    7477          if ( NU.isFunctionalMethod(NU.getParams(d.asInstanceOf[FnDecl])) && 
     
    9295    typeAnalyzer = typeAnalyzer.extend(sparams, None) 
    9396    val toCheck = inheritedAbstractMethods(extendsC) 
    94     for ( t <- toCheck.keySet ) { 
    95       for ( (owner, ds) <- toCheck.get(t) ) { 
    96         for ( d <- ds ) { 
    97           if ( ! implement(d, decls, owner) ) 
    98             error(span, 
    99                   "The inherited abstract method " + d + " from the trait " + t + 
    100                   "\n    in the object " + name + 
    101                   " is not defined in the component " + componentName + ".") 
    102          } 
    103        } 
     97    for ( (owner, d) <- toCheck ) { 
     98      if ( ! implement(d, decls, owner) ) { 
     99        error(span, 
     100              "The inherited abstract method " + d + " from the trait " + owner + 
     101              "\n    in the object " + name + 
     102              " is not defined in the component " + componentName + ".") 
     103      } 
    104104    } 
    105105    typeAnalyzer = oldTypeAnalyzer 
    106106  } 
    107107 
    108   private def inheritedAbstractMethods(extended_traits: List[TraitTypeWhere]) = { 
     108  private def inheritedAbstractMethods(extended_traits: List[TraitTypeWhere]): 
     109      List[(TraitType, FnDecl)] = { 
    109110    val inherited = inheritedMethods(typeAnalyzer.traits, extended_traits, 
    110111                                     Set(), typeAnalyzer) 
    111     val map = new HashMap[IdOrOp, (TraitType, Set[FnDecl])]() 
    112     for (pair <- inherited) { 
    113       val (_, ftn) = (pair.first, pair.second) 
    114       val name = ftn._1.asInstanceOf[HasSelfType].declaringTrait 
    115       val tci = typeAnalyzer.traits.typeCons(name) 
    116       if ( tci.isSome && tci.unwrap.isInstanceOf[TraitIndex] ) { 
    117         val ti = tci.unwrap.asInstanceOf[TraitIndex] 
    118         map.put(name, (ftn._3, 
    119                        collectAbstractMethods(name, toList(NU.getDecls(ti.ast))))) 
     112    var res = List[(TraitType, FnDecl)]() 
     113    for { 
     114      (_,(meth : HasSelfType, _, tt)) <- inherited 
     115      decl <- meth match { 
     116        case f : JavaFunctionalMethod => Some(f.ast()) 
     117        case m : JavaDeclaredMethod => Some(m.ast()) 
     118        case gs : FieldGetterOrSetterMethod if gs.fnDecl.isSome => 
     119            Some(gs.fnDecl.unwrap) 
     120        case o => System.err.println("inheritedAbstractMethods: skipped "+o) 
     121            None 
    120122      } 
    121     } 
    122     map 
     123      SFnDecl(_,SFnHeader(_,mods,_,_,_,_,_,_),_,body,_) <- Some(decl) 
     124      if (mods.isAbstract || ! body.isDefined) 
     125    } res = ((tt,decl)) :: res 
     126    res 
    123127  } 
    124128 
     
    127131    decls.foreach( (d: Decl) => d match { 
    128132                   case fd@SFnDecl(_,SFnHeader(_,mods,_,_,_,_,_,_),_,body,_) => 
    129                      if ( component.typeConses.keySet.contains(name) ) { 
     133                     if ( component.typeConses.containsKey(name) ) { 
    130134                       if ( ! body.isDefined ) set += fd 
    131135                     } else if ( mods.isAbstract ) set += fd 
     
    147151   */ 
    148152  private def implement(d: FnDecl, decl: FnDecl, t: TraitType): Boolean = { 
     153    // Quickly reject unmatched decls.  Note that we're still doing an O(n^2) search here. 
     154    if (!NU.getName(d).asInstanceOf[IdOrOp].getText.equals( 
     155         NU.getName(decl).asInstanceOf[IdOrOp].getText)) 
     156      return false; 
     157    // Quickly reject unmatched modifiers. 
     158    if (!NU.getMods(d).containsAll(NU.getMods(decl))) 
     159      return false; 
     160 
    149161    val tci = typeAnalyzer.traits.typeCons(t.getName) 
    150162    var sparams = List[StaticParam]() 
     
    157169      staticInstantiation(sparams zip sargs, ty).getOrElse(ty) 
    158170    val result = 
    159       NU.getName(d).asInstanceOf[IdOrOp].getText.equals(NU.getName(decl).asInstanceOf[IdOrOp].getText) && 
    160       NU.getMods(d).containsAll(NU.getMods(decl)) && 
    161171      ( typeAnalyzer.equivalent(subst(NU.getParamType(d).asInstanceOf[Type]), 
    162172                                subst(NU.getParamType(decl))).isTrue || 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala

    r4304 r4309  
    193193            var methods = toSet(traitOrObject.dottedMethods) 
    194194                          .asInstanceOf[Set[JavaPair[IdOrOpOrAnonymousName, JavaFunctional]]] 
    195                           .map(p => new JavaPair(p.first, (p.second, identity))) 
     195                          .map(p => (p.first, (p.second, identity))) 
    196196            methods ++= 
    197197              STypesUtil.inheritedMethods(typeAnalyzer.traits, 
    198198                                          toList(traitOrObject.extendsTypes), 
    199199                                          methods, typeAnalyzer) 
    200               .asInstanceOf[Set[JavaPair[IdOrOpOrAnonymousName, (JavaFunctional, StaticTypeReplacer, TraitType)]]] 
    201               .map(p => { val t = p.second 
    202                           new JavaPair(p.first, (t._1, t._2)) }) 
    203  
    204             for ( f <- methods.map(x => x.first) ; if isDeclaredName(f) ) { 
     200              .asInstanceOf[Set[(IdOrOpOrAnonymousName, (JavaFunctional, StaticTypeReplacer, TraitType))]] 
     201              .map(p => (p._1,(p._2._1, p._2._2))) 
     202 
     203            for ( f <- methods.map(_._1) ; if isDeclaredName(f) ) { 
    205204              var ss = Set[(JavaMethod, StaticTypeReplacer)]() 
    206               methods.filter(p => (p.first == f && p.second._1.isInstanceOf[JavaMethod]) && 
    207                              p.second._1.asInstanceOf[JavaMethod].selfType.isSome) 
    208                      .foreach(ss += _.second.asInstanceOf[(JavaMethod, StaticTypeReplacer)]) 
     205              methods.filter(p => (p._1 == f && p._2._1.isInstanceOf[JavaMethod]) && 
     206                             p._2._1.asInstanceOf[JavaMethod].selfType.isSome) 
     207                     .foreach(ss += _._2.asInstanceOf[(JavaMethod, StaticTypeReplacer)]) 
    209208              checkMethodOverloading(f, toMethodSig(ss)) 
    210209            } 
    211             for ( f <- methods.map(x => x.first) ; if isDeclaredName(f) ) { 
     210            for ( f <- methods.map(_._1) ; if isDeclaredName(f) ) { 
    212211              var ss = Set[(JavaFunction, StaticTypeReplacer)]() 
    213               methods.filter(p => p.first == f && p.second._1.isInstanceOf[JavaFunction]) 
    214                      .foreach(ss += _.second.asInstanceOf[(JavaFunction, StaticTypeReplacer)]) 
     212              methods.filter(p => p._1 == f && p._2._1.isInstanceOf[JavaFunction]) 
     213                     .foreach(ss += _._2.asInstanceOf[(JavaFunction, StaticTypeReplacer)]) 
    215214              checkFunctionOverloading(f, toFunctionalMethodSig(ss)) 
    216215            } 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/impls/Common.scala

    r4251 r4309  
    6262      for ( trait_ <- extended_traits if (! done) ) { 
    6363        val type_ = trait_.getBaseType 
    64         if ( ! h.hasExplored(type_) ) { 
    65           h.explore(type_) 
     64        if ( h.explore(type_) ) { 
    6665          type_ match { 
    6766            case ty@STraitType(_, name, _, _) => 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/useful/STypesUtil.scala

    r4304 r4309  
    1919 
    2020import _root_.java.util.ArrayList 
     21import _root_.java.util.{Map => JMap} 
    2122import scala.collection.{Set => CSet} 
    2223import edu.rice.cs.plt.tuple.Pair 
     
    5455  class HierarchyHistory { 
    5556    var explored = Set[Type]() 
    56     def explore(t: Type) = explored += t 
    57     def hasExplored(t: Type) = explored.exists(_ == t) 
     57    def explore(t: Type): Boolean = 
     58      if (explored(t)) 
     59        false 
     60      else { 
     61        explored += t 
     62        true 
     63      } 
     64    def hasExplored(t: Type): Boolean = explored(t) 
    5865    def copy = { 
    5966      val h = new HierarchyHistory 
     
    864871  def inheritedMethods(traits: TraitTable, 
    865872                       extendedTraits: List[TraitTypeWhere], 
    866                        initial: Set[Pair[IdOrOpOrAnonymousName, 
    867                                          (Functional, StaticTypeReplacer)]], 
     873                       initial: Set[(IdOrOpOrAnonymousName, 
     874                                         (Functional, StaticTypeReplacer))], 
    868875                       analyzer: TypeAnalyzer) = { 
    869876    // Return all of the methods from super-traits 
     
    871878                               extended_traits: List[TraitTypeWhere], 
    872879                               given: Set[(String, Type)]) 
    873                               : Set[Pair[IdOrOpOrAnonymousName, 
    874                                          (Functional, StaticTypeReplacer, TraitType)]] = { 
     880                              : Set[(IdOrOpOrAnonymousName, 
     881                                         (Functional, StaticTypeReplacer, TraitType))] = { 
    875882      var allMethods = given 
    876883      // a set of inherited methods: 
    877884      // a set of pairs of method names and 
    878885      //                   triples of Functionals, static parameters substitutions, and declaring trait 
    879       var methods = Set[Pair[IdOrOpOrAnonymousName, (Functional, StaticTypeReplacer, TraitType)]]() 
     886      var methods = Set[(IdOrOpOrAnonymousName, (Functional, StaticTypeReplacer, TraitType))]() 
    880887      var h = history 
    881888      for (trait_ <- extended_traits) { 
    882889        val type_ = trait_.getBaseType 
    883         if ( ! h.hasExplored(type_) ) { 
    884           h.explore(type_) 
     890        if ( h.explore(type_) ) { 
    885891          type_ match { 
    886892            case ty@STraitType(_, name, trait_args, params) => 
    887893              toOption(traits.typeCons(name)) match { 
    888                 case Some(ti) => 
    889                   if ( ti.isInstanceOf[TraitIndex] ) { 
     894                case Some(ti : TraitIndex) => 
    890895                    val tindex = ti.asInstanceOf[TraitIndex] 
    891896                    // Instantiate methods with static args 
    892897                    val paramsToArgs = new StaticTypeReplacer(ti.staticParameters, 
    893898                                                              toJavaList(trait_args)) 
    894                     var collected = toSet(tindex.dottedMethods) 
    895                       .asInstanceOf[Collection[Pair[IdOrOpOrAnonymousName, Functional]]] 
    896                     collected ++= toSet(tindex.functionalMethods) 
    897                       .asInstanceOf[Collection[Pair[IdOrOpOrAnonymousName, Functional]]] 
    898                     for ( pair <- collected ; if pair.first.isInstanceOf[IdOrOp] ) { 
    899                       val (method_name, method_func) = (pair.first, pair.second) 
     899                    var collected = toSet(tindex.dottedMethods).map(p => (p.first, p.second)) 
     900                      .asInstanceOf[Collection[(IdOrOpOrAnonymousName, Functional)]] 
     901                    collected ++= toSet(tindex.functionalMethods).map(p => (p.first, p.second)) 
     902                      .asInstanceOf[Collection[(IdOrOpOrAnonymousName, Functional)]] 
     903                    collected ++= toSet(tindex.getters.entrySet).map(e => (e.getKey, e.getValue)) 
     904                      .asInstanceOf[Collection[(IdOrOpOrAnonymousName, Functional)]] 
     905                    collected ++= toSet(tindex.setters.entrySet).map(e => (e.getKey, e.getValue)) 
     906                      .asInstanceOf[Collection[(IdOrOpOrAnonymousName, Functional)]] 
     907                    for ( (method_name : IdOrOp, method_func) <- collected ) { 
    900908                      val new_pair = toNameParamTy(method_name, method_func) 
    901909                      val fname = new_pair._1 
    902910                      val paramTy = paramsToArgs.replaceIn(new_pair._2) 
    903911                      if (!isOverride(fname, paramTy, allMethods, analyzer)) { 
    904                         methods += new Pair(method_name, (method_func, paramsToArgs, ty)) 
     912                        methods += ((method_name, (method_func, paramsToArgs, ty))) 
    905913                        allMethods += ((fname, paramTy)) 
    906914                      } 
     
    912920                                                           allMethods) 
    913921                    methods ++= inherited 
    914                     allMethods ++= inherited.map(p => toNameParamTy(p.first, p.second._1)) 
     922                    allMethods ++= inherited.map(p => toNameParamTy(p._1, p._2._1)) 
    915923                    h = old_hist 
    916                   } else return methods 
    917924                case _ => return methods 
    918925              } 
     
    924931    } 
    925932    inheritedMethodsHelper(new HierarchyHistory(), extendedTraits, 
    926                            initial.map(p => toNameParamTy(p.first, p.second._1))) 
     933                           initial.map(p => toNameParamTy(p._1, p._2._1))) 
    927934  } 
    928935 
     
    933940      case _ => NF.makeVoidType(span) 
    934941    } 
    935    (name.asInstanceOf[IdOrOp].getText, ty) 
     942    (name.asInstanceOf[IdOrOp].getText, ty) 
    936943  } 
    937944 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/useful/Sets.scala

    r4211 r4309  
    2323 
    2424object Sets { 
    25    
     25 
    2626  /** Takes in any kind of collection. */ 
    2727  def toJavaSet[T](elts: Collection[T]): JavaSet[T] = { 
     
    3030    temp 
    3131  } 
    32    
     32 
    3333  /** Creates an immutable set. */ 
    3434  def toSet[T](jset: JavaSet[T]): Set[T] =