| 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 | |
|---|
| 18 | package com.sun.fortress.scala_src.typechecker.staticenv |
|---|
| 19 | |
|---|
| 20 | import _root_.java.util.{Map => JMap} |
|---|
| 21 | import _root_.java.util.{Set => JSet} |
|---|
| 22 | import com.sun.fortress.compiler.index._ |
|---|
| 23 | import com.sun.fortress.nodes._ |
|---|
| 24 | import com.sun.fortress.nodes_util.Modifiers |
|---|
| 25 | import com.sun.fortress.nodes_util.{NodeFactory => NF} |
|---|
| 26 | import com.sun.fortress.nodes_util.{NodeUtil => NU} |
|---|
| 27 | import com.sun.fortress.scala_src.nodes._ |
|---|
| 28 | import com.sun.fortress.scala_src.useful.Lists._ |
|---|
| 29 | import com.sun.fortress.scala_src.useful.Options._ |
|---|
| 30 | import com.sun.fortress.scala_src.useful.Maps._ |
|---|
| 31 | import com.sun.fortress.scala_src.useful.Sets._ |
|---|
| 32 | import com.sun.fortress.scala_src.useful.STypesUtil |
|---|
| 33 | import edu.rice.cs.plt.collect.Relation |
|---|
| 34 | |
|---|
| 35 | trait STypeEnvExtraction { self: STypeEnv.type => |
|---|
| 36 | |
|---|
| 37 | /** Extract out the bindings in node. */ |
|---|
| 38 | def extractEnvBindings(node: Any): Collection[TypeBinding] = { |
|---|
| 39 | def recur(node: Any) = extractEnvBindings(node) |
|---|
| 40 | (node match { |
|---|
| 41 | |
|---|
| 42 | case SBinding(_, name, mods, Some(typ)) => |
|---|
| 43 | TypeBinding(name, typ, mods, false) |
|---|
| 44 | |
|---|
| 45 | case SParam(_, name, mods, _, _, Some(vaTyp)) => |
|---|
| 46 | TypeBinding(name, vaTyp, mods, false) |
|---|
| 47 | case SParam(_, name, mods, Some(typ), _, _) => |
|---|
| 48 | TypeBinding(name, typ, mods, false) |
|---|
| 49 | |
|---|
| 50 | case SLValue(_, name, mods, Some(typ), mutable) => |
|---|
| 51 | TypeBinding(name, typ, mods, mutable) |
|---|
| 52 | |
|---|
| 53 | case SLocalVarDecl(_, _, lValues, _) => lValues.map(recur) |
|---|
| 54 | |
|---|
| 55 | case v:DeclaredVariable => recur(v.ast) |
|---|
| 56 | |
|---|
| 57 | // Type erasure makes us put all JMap cases in one. |
|---|
| 58 | case m:JMap[_, _] => toMap(m).flatMap(xv => |
|---|
| 59 | xv match { |
|---|
| 60 | |
|---|
| 61 | // Match Map[Id, Variable] |
|---|
| 62 | case (x:Id, v:DeclaredVariable) => recur(v) |
|---|
| 63 | case (x:Id, v:SingletonVariable) => |
|---|
| 64 | recur(NF.makeLValue(x, v.declaringTrait)) |
|---|
| 65 | case (x:Id, v:ParamVariable) => recur(v.ast) |
|---|
| 66 | |
|---|
| 67 | // Bind object names to their types. |
|---|
| 68 | case (x:Id, v:ObjectTraitIndex) => |
|---|
| 69 | val decl = v.ast |
|---|
| 70 | val params = toOption(NU.getParams(decl)) |
|---|
| 71 | val sparams = NU.getStaticParams(decl) |
|---|
| 72 | val objType = params match { |
|---|
| 73 | case None if sparams.isEmpty => |
|---|
| 74 | // Just a single trait type. |
|---|
| 75 | NF.makeTraitType(x) |
|---|
| 76 | case None => |
|---|
| 77 | // A generic trait type. |
|---|
| 78 | NF.makeGenericSingletonType(x, sparams) |
|---|
| 79 | case Some(params) if sparams.isEmpty => |
|---|
| 80 | // Arrow type for basic constructor. |
|---|
| 81 | NF.makeArrowType(NU.getSpan(x), |
|---|
| 82 | STypesUtil.makeDomainType(toList(params)), |
|---|
| 83 | NF.makeTraitType(x)) |
|---|
| 84 | case Some(params) => |
|---|
| 85 | // Generic arrow type for constructor. |
|---|
| 86 | val sargs = toList(sparams).map(STypesUtil.staticParamToArg) |
|---|
| 87 | NF.makeArrowType(NU.getSpan(decl), |
|---|
| 88 | false, |
|---|
| 89 | STypesUtil.makeDomainType(toList(params)), |
|---|
| 90 | NF.makeTraitType(x, toJavaList(sargs)), |
|---|
| 91 | NF.emptyEffect, // TODO: Change this? |
|---|
| 92 | sparams, |
|---|
| 93 | NU.getWhereClause(decl)) |
|---|
| 94 | } |
|---|
| 95 | List(TypeBinding(x, objType, Modifiers.None, false)) |
|---|
| 96 | }) |
|---|
| 97 | |
|---|
| 98 | // Matches all, but must be [IdOrOpOrAnonymousName, ? <: Functional] |
|---|
| 99 | case r:Relation[IdOrOpOrAnonymousName, Functional] => |
|---|
| 100 | val fnNames = toSet(r.firstSet) |
|---|
| 101 | |
|---|
| 102 | // For each name, intersect together all of its overloading types. |
|---|
| 103 | fnNames.flatMap(x => x match { |
|---|
| 104 | |
|---|
| 105 | // Make sure this is actually a name. |
|---|
| 106 | case x: IdOrOpOrAnonymousName => |
|---|
| 107 | val fns: Set[Functional] = toSet(r.matchFirst(x).asInstanceOf[JSet[Functional]]) |
|---|
| 108 | val oTypes = |
|---|
| 109 | fns.map(STypesUtil.makeArrowFromFunctional(_).asInstanceOf[Type]) |
|---|
| 110 | val fnType = NF.makeIntersectionType(oTypes) |
|---|
| 111 | Some(TypeBinding(x, fnType, Modifiers.None, false)) |
|---|
| 112 | |
|---|
| 113 | // case _ => None |
|---|
| 114 | }) |
|---|
| 115 | |
|---|
| 116 | case xs:Iterable[_] => xs.flatMap(recur) |
|---|
| 117 | |
|---|
| 118 | case _ => Nil |
|---|
| 119 | |
|---|
| 120 | }) match { // Guarantee that a Collection is returned. |
|---|
| 121 | case bs:Collection[TypeBinding] => bs |
|---|
| 122 | case b:TypeBinding => List(b) |
|---|
| 123 | } |
|---|
| 124 | } |
|---|
| 125 | } |
|---|