Changeset 4292
- Timestamp:
- 10/26/09 21:56:40 (4 weeks ago)
- Location:
- trunk/ProjectFortress
- Files:
-
- 2 added
- 3 modified
-
compiler_tests/Compiled10.s.fss (added)
-
compiler_tests/XXX10s.test (added)
-
src/com/sun/fortress/scala_src/typechecker/ExclusionOracle.scala (modified) (8 diffs)
-
src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala (modified) (20 diffs)
-
src/com/sun/fortress/scala_src/useful/STypesUtil.scala (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/ExclusionOracle.scala
r4275 r4292 30 30 import com.sun.fortress.compiler.index.TypeConsIndex 31 31 import com.sun.fortress.compiler.index.{Function => JavaFunction} 32 import com.sun.fortress.compiler.typechecker.TypeAnalyzer33 32 import com.sun.fortress.exceptions.StaticError 34 33 import com.sun.fortress.exceptions.TypeError … … 39 38 import com.sun.fortress.parser_util.IdentifierUtil 40 39 import com.sun.fortress.repository.FortressRepository 40 import com.sun.fortress.scala_src.types.TypeAnalyzer 41 41 import com.sun.fortress.scala_src.useful._ 42 42 import com.sun.fortress.scala_src.useful.ErrorLog … … 74 74 case (_, SAnyType(_)) => false 75 75 case (f@SVarType(_,_,_), s@SVarType(_,_,_)) => 76 ( toOption(typeAnalyzer. kindEnv.staticParam(f.getName)),77 toOption(typeAnalyzer. kindEnv.staticParam(s.getName)) ) match {76 ( toOption(typeAnalyzer.env.staticParam(f.getName)), 77 toOption(typeAnalyzer.env.staticParam(s.getName)) ) match { 78 78 case (Some(fp), Some(sp)) => 79 79 var result = false … … 105 105 } 106 106 case (f@SVarType(_,_,_), _) => 107 toOption(typeAnalyzer. kindEnv.staticParam(f.getName)) match {107 toOption(typeAnalyzer.env.staticParam(f.getName)) match { 108 108 case Some(fp) => 109 109 var result = false … … 120 120 } 121 121 case (_, s@SVarType(_,_,_)) => 122 toOption(typeAnalyzer. kindEnv.staticParam(s.getName)) match {122 toOption(typeAnalyzer.env.staticParam(s.getName)) match { 123 123 case Some(sp) => 124 124 var result = false … … 148 148 case (_, _:TupleType) => true 149 149 case (f:TraitType, s:TraitType) => 150 ( toOption(typeAnalyzer.trait Table.typeCons(f.getName)),151 toOption(typeAnalyzer.trait Table.typeCons(s.getName)) ) match {150 ( toOption(typeAnalyzer.traits.typeCons(f.getName)), 151 toOption(typeAnalyzer.traits.typeCons(s.getName)) ) match { 152 152 case (Some(fi), Some(si)) => 153 153 ( NodeUtil.isTraitOrObject(fi), NodeUtil.isTraitOrObject(si) ) match { … … 182 182 for ( t <- toList(tIndex.extendsTypes) ) { 183 183 if ( t.getBaseType.isInstanceOf[NamedType] ) { 184 result ++= transitivelyExcludes(typeAnalyzer.trait Table.typeCons(t.getBaseType.asInstanceOf[NamedType].getName).unwrap.asInstanceOf[ProperTraitIndex])184 result ++= transitivelyExcludes(typeAnalyzer.traits.typeCons(t.getBaseType.asInstanceOf[NamedType].getName).unwrap.asInstanceOf[ProperTraitIndex]) 185 185 } 186 186 } … … 254 254 if (t.isInstanceOf[VarType]) result = false 255 255 else { 256 toOption(typeAnalyzer.trait Table.typeCons(t.getName)) match {256 toOption(typeAnalyzer.traits.typeCons(t.getName)) match { 257 257 case None => 258 258 errors.signal("Unrecognized name: " + t.getName, NodeUtil.getSpan(t)) -
trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala
r4289 r4292 23 23 import edu.rice.cs.plt.collect.Relation 24 24 import edu.rice.cs.plt.tuple.{Option => JavaOption} 25 import edu.rice.cs.plt.tuple.{Pair => JavaPair} 25 26 import com.sun.fortress.compiler.GlobalEnvironment 26 27 import com.sun.fortress.compiler.index.CompilationUnitIndex … … 33 34 import com.sun.fortress.compiler.index.{Method => JavaMethod} 34 35 import com.sun.fortress.compiler.index.{Variable => JavaVariable} 35 import com.sun.fortress.compiler.typechecker. TypeAnalyzer36 import com.sun.fortress.compiler.typechecker.StaticTypeReplacer 36 37 import com.sun.fortress.exceptions.InterpreterBug 37 38 import com.sun.fortress.exceptions.StaticError … … 43 44 import com.sun.fortress.nodes_util.Span 44 45 import com.sun.fortress.parser_util.IdentifierUtil 46 import com.sun.fortress.scala_src.types.TypeAnalyzer 45 47 import com.sun.fortress.scala_src.useful._ 46 48 import com.sun.fortress.scala_src.useful.Lists._ … … 71 73 f: IdOrOpOrAnonymousName) 72 74 : Set[((JavaList[StaticParam],Type,Type), Span)] = { 73 val fns = to Sig(toSet(index.functions.matchFirst(f)).asInstanceOf[Set[JavaFunctional]])75 val fns = toFunctionSig(toSet(index.functions.matchFirst(f)).asInstanceOf[Set[JavaFunctional]]) 74 76 if ( index.variables.keySet.contains(f) ) 75 77 index.variables.get(f) match { … … 84 86 } 85 87 86 private def toSig(set: Set[JavaFunctional]) 87 : Set[((JavaList[StaticParam],Type,Type), Span)] = 88 set.filter(isDeclaredFunctional(_)) 89 .map((f: JavaFunctional) => 88 // for functions 89 private def toFunctionSig(set: Set[JavaFunctional]) 90 : Set[((JavaList[StaticParam],Type,Type), Span)] = 91 set.filter(isDeclaredFunction(_)) 92 .map(f => ((f.staticParameters, 93 paramsToType(f.parameters, f.getSpan), 94 f.getReturnType.unwrap), 95 f.getSpan)) 96 97 // for functional methods 98 private def toFunctionalMethodSig(set: Set[(JavaFunction, StaticTypeReplacer)]) 99 : Set[((JavaList[StaticParam],Type,Type), Span)] = 100 set.filter(p => isFunctionalMethod(p._1)) 101 .map(p => { 102 val (f, replacer) = p 90 103 ((f.staticParameters, 91 paramsToType(f.parameters, f.getSpan), 92 f.getReturnType.unwrap), 93 f.getSpan)) 104 replacer.replaceIn(paramsToType(f.parameters, f.getSpan)), 105 replacer.replaceIn(f.getReturnType.unwrap)), 106 f.getSpan)}) 107 108 // for dotted methods 109 private def toMethodSig(set: Set[(JavaMethod, StaticTypeReplacer)]) 110 : Set[((JavaList[StaticParam],Type,Type), Span)] = 111 set.filter(p => isDeclaredMethod(p._1)) 112 .map(p => { 113 val (f, replacer) = p 114 ((f.staticParameters, 115 replacer.replaceIn(paramsToType(f.selfType.unwrap, f.parameters, f.getSpan)), 116 replacer.replaceIn(f.getReturnType.unwrap)), 117 f.getSpan)}) 94 118 95 119 /* Called by com.sun.fortress.compiler.StaticChecker.checkComponent … … 129 153 } 130 154 } 131 check Overloading(f, set)155 checkFunctionOverloading(f, set) 132 156 } 133 157 /* All inherited abstract methods in object expressions should be defined, … … 144 168 // Extend the type analyzer with the collected static parameters 145 169 val oldTypeAnalyzer = typeAnalyzer 146 val staticParameters = new ArrayList[StaticParam]()147 170 // Add static parameters of the enclosing trait or object 148 staticParameters.addAll( traitOrObject.staticParameters )149 typeAnalyzer = typeAnalyzer.extend(staticParameters, none[WhereClause])171 typeAnalyzer = typeAnalyzer.extend(toList(traitOrObject.staticParameters), 172 None) 150 173 /* The parameter type of a setter must be the same as the return type 151 174 * of a getter with the same name, if any. … … 166 189 } 167 190 } 168 val methods = traitOrObject.dottedMethods 169 for ( f <- toSet(methods.firstSet) ; if isDeclaredName(f) ) { 170 checkOverloading(f, toSig(toSet(methods.matchFirst(f)).asInstanceOf[Set[JavaFunctional]])) 191 val identity = new StaticTypeReplacer(new ArrayList[StaticParam](), 192 new ArrayList[StaticArg]()) 193 var methods = toSet(traitOrObject.dottedMethods) 194 .asInstanceOf[Set[JavaPair[IdOrOpOrAnonymousName, JavaFunctional]]] 195 .map(p => new JavaPair(p.first, (p.second, identity))) 196 methods ++= 197 STypesUtil.inheritedMethods(typeAnalyzer.traits, 198 toList(traitOrObject.extendsTypes), 199 methods, typeAnalyzer) 200 .asInstanceOf[Set[JavaPair[IdOrOpOrAnonymousName, (JavaFunctional, StaticTypeReplacer)]]] 201 202 for ( f <- methods.map(x => x.first) ; if isDeclaredName(f) ) { 203 var ss = Set[(JavaMethod, StaticTypeReplacer)]() 204 methods.filter(p => (p.first == f && p.second._1.isInstanceOf[JavaMethod]) && 205 p.second._1.asInstanceOf[JavaMethod].selfType.isSome) 206 .foreach(ss += _.second.asInstanceOf[(JavaMethod, StaticTypeReplacer)]) 207 checkMethodOverloading(f, toMethodSig(ss)) 208 } 209 for ( f <- methods.map(x => x.first) ; if isDeclaredName(f) ) { 210 var ss = Set[(JavaFunction, StaticTypeReplacer)]() 211 methods.filter(p => p.first == f && p.second._1.isInstanceOf[JavaFunction]) 212 .foreach(ss += _.second.asInstanceOf[(JavaFunction, StaticTypeReplacer)]) 213 checkFunctionOverloading(f, toFunctionalMethodSig(ss)) 171 214 } 172 215 typeAnalyzer = oldTypeAnalyzer … … 174 217 toJavaList(errors) 175 218 } 219 220 /* Checks the validity of the overloaded method declarations. */ 221 private def checkMethodOverloading(name: IdOrOpOrAnonymousName, 222 set: Set[((JavaList[StaticParam],Type,Type), Span)]) 223 : Unit = 224 checkOverloading(name, set, true) 225 226 /* Checks the validity of the overloaded function declarations. */ 227 private def checkFunctionOverloading(name: IdOrOpOrAnonymousName, 228 set: Set[((JavaList[StaticParam],Type,Type), Span)]) 229 : Unit = 230 checkOverloading(name, set, false) 176 231 177 232 /* Checks the validity of the overloaded function declarations. */ 178 233 private def checkOverloading(name: IdOrOpOrAnonymousName, 179 set: Set[((JavaList[StaticParam],Type,Type), Span)]) 234 set: Set[((JavaList[StaticParam],Type,Type), Span)], 235 isMethod: Boolean) 180 236 : Unit = set.size match { 181 237 case 0 => … … 189 245 "There are multiple declarations of " + 190 246 name + " with the same type: " + 191 param + " -> " + result) 247 (if (isMethod) dropReceiver(param) else param) + 248 " -> " + result) 192 249 case _ => 193 250 // A functional which takes a single parameter of a parametric type … … 249 306 staticParameters.addAll(sub_type._1._1) 250 307 staticParameters.addAll(super_type._1._1) 251 typeAnalyzer = typeAnalyzer.extend( staticParameters, none[WhereClause])308 typeAnalyzer = typeAnalyzer.extend(toList(staticParameters), None) 252 309 val result = subtype(super_type._1._2, sub_type._1._2) && 253 310 subtype(sub_type._1._3, super_type._1._3) … … 273 330 staticParameters.addAll(first._1._1) 274 331 staticParameters.addAll(second._1._1) 275 typeAnalyzer = typeAnalyzer.extend( staticParameters, none[WhereClause])332 typeAnalyzer = typeAnalyzer.extend(toList(staticParameters), None) 276 333 val result = new ExclusionOracle(typeAnalyzer, 277 334 new ErrorLog()).excludes(first._1._2, … … 291 348 staticParameters.addAll(first._1._1) 292 349 staticParameters.addAll(second._1._1) 293 typeAnalyzer = typeAnalyzer.extend( staticParameters, none[WhereClause])350 typeAnalyzer = typeAnalyzer.extend(toList(staticParameters), None) 294 351 var result = false 295 352 val exclusionOracle = new ExclusionOracle(typeAnalyzer, new ErrorLog()) … … 333 390 var i = 0 334 391 while ( i < size ) { 335 elems = elems ::: List(typeAnalyzer.meet(t oJavaList(tuples.map(ty => NodeUtil.getTupleTypeElem(ty, i)))))392 elems = elems ::: List(typeAnalyzer.meet(tuples.map(ty => NodeUtil.getTupleTypeElem(ty, i)))) 336 393 i += 1 337 394 } … … 419 476 // add static parameters of "f"'s enclosing trait or object 420 477 if ( NodeUtil.isFunctionalMethod(f) ) { 421 val ind = typeAnalyzer.trait Table.typeCons(NodeUtil.getDeclaringTrait(f))478 val ind = typeAnalyzer.traits.typeCons(NodeUtil.getDeclaringTrait(f)) 422 479 if ( ind.isSome && NodeUtil.isTraitOrObject(ind.unwrap) ) { 423 480 staticParameters.addAll( NodeUtil.getStaticParameters(ind.unwrap) ) … … 427 484 // add static parameters of "g"'s enclosing trait or object 428 485 if ( NodeUtil.isFunctionalMethod(g) ) { 429 val ind = typeAnalyzer.trait Table.typeCons(NodeUtil.getDeclaringTrait(g))486 val ind = typeAnalyzer.traits.typeCons(NodeUtil.getDeclaringTrait(g)) 430 487 if ( ind.isSome && NodeUtil.isTraitOrObject(ind.unwrap) ) { 431 488 staticParameters.addAll( NodeUtil.getStaticParameters(ind.unwrap) ) … … 438 495 // Whether "g"'s parameter type is a subtype of "f"'s parameter type 439 496 // and "f"'s return type is a subtype of "g"'s return type 440 typeAnalyzer = typeAnalyzer.extend( staticParameters, none[WhereClause])497 typeAnalyzer = typeAnalyzer.extend(toList(staticParameters), None) 441 498 val result = subtype(paramsToType(g.parameters, g.getSpan), 442 499 paramsToType(f.parameters, f.getSpan)) && … … 446 503 } 447 504 505 /* Drop the first element denoting the receiver type of the given type. */ 506 private def dropReceiver(param: Type) = param match { 507 case STupleType(info, _::ty::Nil, None, Nil) => ty 508 case STupleType(info, elements, varargs, keywords) => 509 STupleType(info, elements.takeRight(elements.size-1), varargs, keywords) 510 case _ => NodeFactory.makeVoidType(NodeUtil.getSpan(param)) 511 } 512 448 513 def isDeclaredName(f: IdOrOpOrAnonymousName) = f match { 449 514 case SId(_,_,str) => IdentifierUtil.validId(str) … … 452 517 } 453 518 454 def isDeclaredFunctional(f: JavaFunctional) = f match { 519 def isDeclaredMethod(f: JavaFunctional) = f match { 520 case DeclaredMethod(_,_) => true 521 case _ => false 522 } 523 524 def isDeclaredFunction(f: JavaFunctional) = f match { 455 525 case DeclaredFunction(_) => true 456 case DeclaredMethod(_,_) => true 526 case _ => false 527 } 528 529 def isFunctionalMethod(f: JavaFunctional) = f match { 530 case FunctionalMethod(_,_) => true 457 531 case _ => false 458 532 } … … 483 557 } 484 558 559 /* Returns the type of the given self type and a list of parameters. */ 560 private def paramsToType(self: Type, params: JavaList[Param], span: Span): Type = { 561 val span = params.size match { 562 case 0 => NodeUtil.getSpan(self) 563 case _ => NodeUtil.spanAll(params) 564 } 565 val elems = toList(params).map(paramToType) 566 if (elems.forall(_.isDefined)) 567 NodeFactory.makeTupleType(span, toJavaList(List(self) ++ elems.map(_.get))) 568 else { 569 error(span, 570 "Type checking couldn't infer the type of " + params) 571 NodeFactory.makeVoidType(span) 572 } 573 } 574 485 575 private def error(loc: Span, msg: String) = 486 576 errors = errors ::: List(TypeError.make(msg, loc)) -
trunk/ProjectFortress/src/com/sun/fortress/scala_src/useful/STypesUtil.scala
r4291 r4292 860 860 } 861 861 862 // Invariant: Parameter types of all the methods should exist. 862 // Invariant: Parameter types of all the methods should exist, 863 // either given or inferred. 863 864 def inheritedMethods(traits: TraitTable, 864 865 extendedTraits: List[TraitTypeWhere], 865 initial: Set[Pair[IdOrOpOrAnonymousName, Functional]], 866 initial: Set[Pair[IdOrOpOrAnonymousName, 867 (Functional, StaticTypeReplacer)]], 866 868 analyzer: TypeAnalyzer) = { 867 869 // Return all of the methods from super-traits 868 870 def inheritedMethodsHelper(history: HierarchyHistory, 869 871 extended_traits: List[TraitTypeWhere], 870 given: Set[Pair[IdOrOpOrAnonymousName, Functional]]) 871 : Set[Pair[IdOrOpOrAnonymousName, Functional]] = { 872 given: Set[(String, Type)]) 873 : Set[Pair[IdOrOpOrAnonymousName, 874 (Functional, StaticTypeReplacer)]] = { 872 875 var allMethods = given 873 var methods = Set[Pair[IdOrOpOrAnonymousName, Functional]]() 876 // a set of inherited methods: 877 // a set of pairs of method names and 878 // pairs of Functionals and static parameters substitutions 879 var methods = Set[Pair[IdOrOpOrAnonymousName, (Functional, StaticTypeReplacer)]]() 874 880 var h = history 875 881 for (trait_ <- extended_traits) { … … 882 888 case Some(ti) => 883 889 if ( ti.isInstanceOf[TraitIndex] ) { 890 val tindex = ti.asInstanceOf[TraitIndex] 884 891 // Instantiate methods with static args 885 892 val paramsToArgs = new StaticTypeReplacer(ti.staticParameters, 886 893 toJavaList(trait_args)) 887 var collected: Collection[Pair[IdOrOpOrAnonymousName, Functional]] = 888 toSet(ti.asInstanceOf[TraitIndex].dottedMethods) 889 .asInstanceOf[CSet[Pair[IdOrOpOrAnonymousName, Functional]]] 890 collected ++= 891 toSet(ti.asInstanceOf[TraitIndex].functionalMethods) 892 .asInstanceOf[CSet[Pair[IdOrOpOrAnonymousName, Functional]]] 894 var collected = toSet(tindex.dottedMethods) 895 .asInstanceOf[Collection[Pair[IdOrOpOrAnonymousName, Functional]]] 896 collected ++= toSet(tindex.functionalMethods) 897 .asInstanceOf[Collection[Pair[IdOrOpOrAnonymousName, Functional]]] 893 898 for ( pair <- collected ; if pair.first.isInstanceOf[IdOrOp] ) { 894 val fname = pair.first.asInstanceOf[IdOrOp].getText 895 val span = NU.getSpan(pair.first) 896 val paramTy = paramsToType(toList(pair.second.parameters), 897 span) match { 898 case Some(t) => paramsToArgs.replaceIn(t) 899 case _ => NF.makeVoidType(span) 900 } 899 val (method_name, method_func) = (pair.first, pair.second) 900 val new_pair = toNameParamTy(method_name, method_func) 901 val fname = new_pair._1 902 val paramTy = paramsToArgs.replaceIn(new_pair._2) 901 903 if (!isOverride(fname, paramTy, allMethods, analyzer)) { 902 methods += pair903 allMethods += pair904 methods += new Pair(method_name, (method_func, paramsToArgs)) 905 allMethods += ((fname, paramTy)) 904 906 } 905 907 } 906 908 val instantiated_extends_types = 907 toList(ti.asInstanceOf[TraitIndex].extendsTypes).map( (t:TraitTypeWhere) => 908 t.accept(paramsToArgs).asInstanceOf[TraitTypeWhere] ) 909 toList(tindex.extendsTypes).map(_.accept(paramsToArgs).asInstanceOf[TraitTypeWhere]) 909 910 val old_hist = h 910 911 val inherited = inheritedMethodsHelper(h, instantiated_extends_types, 911 912 allMethods) 912 913 methods ++= inherited 913 allMethods ++= inherited 914 allMethods ++= inherited.map(p => toNameParamTy(p.first, p.second._1)) 914 915 h = old_hist 915 916 } else return methods … … 922 923 methods 923 924 } 924 inheritedMethodsHelper(new HierarchyHistory(), extendedTraits, initial) 925 inheritedMethodsHelper(new HierarchyHistory(), extendedTraits, 926 initial.map(p => toNameParamTy(p.first, p.second._1))) 927 } 928 929 private def toNameParamTy(name: IdOrOpOrAnonymousName, func: Functional) = { 930 val span = NU.getSpan(name) 931 val ty = paramsToType(toList(func.parameters), span) match { 932 case Some(t) => t 933 case _ => NF.makeVoidType(span) 934 } 935 (name.asInstanceOf[IdOrOp].getText, ty) 925 936 } 926 937 927 938 private def isOverride(fname: String, paramTy: Type, 928 allMethods: Set[ Pair[IdOrOpOrAnonymousName, Functional]],939 allMethods: Set[(String, Type)], 929 940 analyzer: TypeAnalyzer): Boolean = { 930 for (f <- allMethods; 931 if fname.equals(f.first.asInstanceOf[IdOrOp].getText)) { 932 val span = NU.getSpan(f.first) 933 val otherParamTy = paramsToType(toList(f.second.parameters), span) match { 934 case Some(t) => t 935 case _ => NF.makeVoidType(span) 936 } 937 if (analyzer.equivalent(paramTy, otherParamTy).isTrue) return true 941 for (f <- allMethods; if fname.equals(f._1)) { 942 if (analyzer.equivalent(paramTy, f._2).isTrue) return true 938 943 } 939 944 false … … 949 954 if (elems.forall(_.isDefined)) 950 955 Some(NF.makeTupleType(NU.spanAll(toJavaList(params)), 951 Lists.toJavaList(elems.map(_.get))))956 toJavaList(elems.map(_.get)))) 952 957 else None 953 958 }

