Changeset 4289 for trunk/ProjectFortress

Show
Ignore:
Timestamp:
10/26/09 07:55:47 (4 weeks ago)
Author:
sukyoungryu
Message:

[types util] Fixed the inheritedMethods to handle method overriding.
Moved the paramsToType method to STypesUtil.

Location:
trunk/ProjectFortress/src/com/sun/fortress/scala_src
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/AbstractMethodChecker.scala

    r4286 r4289  
    2525import com.sun.fortress.compiler.GlobalEnvironment 
    2626import com.sun.fortress.compiler.index.ComponentIndex 
     27import com.sun.fortress.compiler.index.{Functional => JavaFunctional} 
    2728import com.sun.fortress.compiler.index.TraitIndex 
    2829import com.sun.fortress.compiler.typechecker.StaticTypeReplacer 
     
    6768        checkObject(span, List(), name, extendsC, 
    6869                    walk(decls).asInstanceOf[List[Decl]]) 
    69         val inherited = inheritedMethods(traits, extendsC).map(t => t.first.asInstanceOf[IdOrOp].getText) 
     70        val inherited = inheritedMethods(traits, extendsC, Set(), typeAnalyzer) 
     71                        .map(t => t.first.asInstanceOf[IdOrOp].getText) 
    7072        for ( d <- decls ; if d.isInstanceOf[FnDecl] ) { 
    7173          if ( NU.isFunctionalMethod(NU.getParams(d.asInstanceOf[FnDecl])) && 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala

    r4275 r4289  
    474474    /* Returns the type of the given list of parameters. */ 
    475475    private def paramsToType(params: JavaList[Param], span: Span): Type = 
    476         params.size match { 
    477             case 0 => NodeFactory.makeVoidType(span) 
    478             case 1 => paramToType(params.get(0)) 
    479             case _ => 
    480             NodeFactory.makeTupleType(NodeUtil.spanAll(params), 
    481                                       Lists.toJavaList(Lists.toList(params).map(p => paramToType(p)))) 
    482         } 
    483  
    484     /* Returns the type of the given parameter. */ 
    485     private def paramToType(param: Param): Type = 
    486         toOption(param.getIdType) match { 
    487             case Some(ty) => ty 
    488             case _ => 
    489                 toOption(param.getVarargsType) match { 
    490                     case Some(ty) => ty 
    491                     case _ => 
    492                         val span = NodeUtil.getSpan(param) 
    493                         error(span, 
    494                               "Type checking couldn't infer the type of " + param) 
    495                         NodeFactory.makeVoidType(span) 
    496                 } 
    497         } 
     476      STypesUtil.paramsToType(toList(params), span) match { 
     477        case Some(ty) => ty 
     478        case _ => 
     479          val span = NodeUtil.spanAll(params) 
     480          error(span, 
     481                "Type checking couldn't infer the type of " + params) 
     482          NodeFactory.makeVoidType(span) 
     483      } 
    498484 
    499485    private def error(loc: Span, msg: String) = 
  • trunk/ProjectFortress/src/com/sun/fortress/scala_src/useful/STypesUtil.scala

    r4286 r4289  
    3535import com.sun.fortress.nodes_util.{NodeFactory => NF} 
    3636import com.sun.fortress.nodes_util.{NodeUtil => NU} 
     37import com.sun.fortress.nodes_util.Span 
    3738import com.sun.fortress.scala_src.nodes._ 
    3839import com.sun.fortress.scala_src.typechecker.ConstraintFormula 
     
    874875  } 
    875876 
     877  // Invariant: Parameter types of all the methods should exist. 
    876878  def inheritedMethods(traits: TraitTable, 
    877                        extendedTraits: List[TraitTypeWhere]) = { 
     879                       extendedTraits: List[TraitTypeWhere], 
     880                       initial: Set[Pair[IdOrOpOrAnonymousName, Functional]], 
     881                       analyzer: TypeAnalyzer) = { 
    878882    // Return all of the methods from super-traits 
    879883    def inheritedMethodsHelper(history: HierarchyHistory, 
    880                                extended_traits: List[TraitTypeWhere]) 
    881                               : Set[Pair[IdOrOpOrAnonymousName, Function]] = { 
    882       var methods = Set[Pair[IdOrOpOrAnonymousName, Function]]() 
    883       var done = false 
     884                               extended_traits: List[TraitTypeWhere], 
     885                               given: Set[Pair[IdOrOpOrAnonymousName, Functional]]) 
     886                              : Set[Pair[IdOrOpOrAnonymousName, Functional]] = { 
     887      var allMethods = given 
     888      var methods = Set[Pair[IdOrOpOrAnonymousName, Functional]]() 
    884889      var h = history 
    885       for ( trait_ <- extended_traits ; if (! done) ) { 
     890      for (trait_ <- extended_traits) { 
    886891        val type_ = trait_.getBaseType 
    887892        if ( ! h.hasExplored(type_) ) { 
    888893          h.explore(type_) 
    889894          type_ match { 
    890             case ty@STraitType(_, name, _, params) => 
     895            case ty@STraitType(_, name, trait_args, params) => 
    891896              toOption(traits.typeCons(name)) match { 
    892897                case Some(ti) => 
    893898                  if ( ti.isInstanceOf[TraitIndex] ) { 
    894                     val trait_params = ti.staticParameters 
    895                     val trait_args = ty.getArgs 
    896899                    // Instantiate methods with static args 
    897                     var collected: Collection[Pair[IdOrOpOrAnonymousName, Function]] = 
    898                       toSet(ti.asInstanceOf[TraitIndex].dottedMethods).asInstanceOf[CSet[Pair[IdOrOpOrAnonymousName, Function]]] 
     900                    val paramsToArgs = new StaticTypeReplacer(ti.staticParameters, 
     901                                                              toJavaList(trait_args)) 
     902                    var collected: Collection[Pair[IdOrOpOrAnonymousName, Functional]] = 
     903                      toSet(ti.asInstanceOf[TraitIndex].dottedMethods) 
     904                      .asInstanceOf[CSet[Pair[IdOrOpOrAnonymousName, Functional]]] 
    899905                    collected ++= 
    900                       toSet(ti.asInstanceOf[TraitIndex].functionalMethods).asInstanceOf[CSet[Pair[IdOrOpOrAnonymousName, Function]]] 
     906                      toSet(ti.asInstanceOf[TraitIndex].functionalMethods) 
     907                      .asInstanceOf[CSet[Pair[IdOrOpOrAnonymousName, Functional]]] 
    901908                    for ( pair <- collected ; if pair.first.isInstanceOf[IdOrOp] ) { 
    902                       methods += pair 
     909                      val fname = pair.first.asInstanceOf[IdOrOp].getText 
     910                      val span = NU.getSpan(pair.first) 
     911                      val paramTy = paramsToType(toList(pair.second.parameters), 
     912                                                 span) match { 
     913                        case Some(t) => paramsToArgs.replaceIn(t) 
     914                        case _ => NF.makeVoidType(span) 
     915                      } 
     916                      if (!isOverride(fname, paramTy, allMethods, analyzer)) { 
     917                        methods += pair 
     918                        allMethods += pair 
     919                      } 
    903920                    } 
    904                     val paramsToArgs = new StaticTypeReplacer(trait_params, trait_args) 
    905921                    val instantiated_extends_types = 
    906922                      toList(ti.asInstanceOf[TraitIndex].extendsTypes).map( (t:TraitTypeWhere) => 
    907923                            t.accept(paramsToArgs).asInstanceOf[TraitTypeWhere] ) 
    908924                    val old_hist = h 
    909                     methods ++= inheritedMethodsHelper(h, instantiated_extends_types) 
     925                    val inherited = inheritedMethodsHelper(h, instantiated_extends_types, 
     926                                                           allMethods) 
     927                    methods ++= inherited 
     928                    allMethods ++= inherited 
    910929                    h = old_hist 
    911                   } else done = true 
    912                 case _ => done = true 
     930                  } else return methods 
     931                case _ => return methods 
    913932              } 
    914             case _ => done = true 
     933            case _ => return methods 
    915934          } 
    916935        } 
     
    918937      methods 
    919938    } 
    920     inheritedMethodsHelper(new HierarchyHistory(), extendedTraits) 
    921   } 
    922  
     939    inheritedMethodsHelper(new HierarchyHistory(), extendedTraits, initial) 
     940  } 
     941 
     942  private def isOverride(fname: String, paramTy: Type, 
     943                         allMethods: Set[Pair[IdOrOpOrAnonymousName, Functional]], 
     944                         analyzer: TypeAnalyzer): Boolean = { 
     945    for (f <- allMethods; 
     946         if fname.equals(f.first.asInstanceOf[IdOrOp].getText)) { 
     947      val span = NU.getSpan(f.first) 
     948      val otherParamTy = paramsToType(toList(f.second.parameters), span) match { 
     949        case Some(t) => t 
     950        case _ => NF.makeVoidType(span) 
     951      } 
     952      if (analyzer.equivalent(paramTy, otherParamTy).isTrue) return true 
     953    } 
     954    false 
     955  } 
     956 
     957  /* Returns the type of the given list of parameters. */ 
     958  def paramsToType(params: List[Param], span: Span): Option[Type] = 
     959    params.size match { 
     960      case 0 => Some(NF.makeVoidType(span)) 
     961      case 1 => paramToType(params.head) 
     962      case _ => 
     963        val elems = params.map(paramToType) 
     964        if (elems.forall(_.isDefined)) 
     965          Some(NF.makeTupleType(NU.spanAll(toJavaList(params)), 
     966                                Lists.toJavaList(elems.map(_.get)))) 
     967        else None 
     968    } 
     969 
     970  /* Returns the type of the given parameter. */ 
     971  def paramToType(param: Param): Option[Type] = 
     972    toOption(param.getIdType) match { 
     973      case Some(ty) => Some(ty) 
     974      case _ => toOption(param.getVarargsType) match { 
     975        case Some(ty) => Some(ty) 
     976        case _ => None 
     977      } 
     978  } 
    923979}