| 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 |
|---|
| 19 | |
|---|
| 20 | import com.sun.fortress.exceptions.InterpreterBug.bug |
|---|
| 21 | import com.sun.fortress.nodes._ |
|---|
| 22 | import com.sun.fortress.nodes_util.Modifiers |
|---|
| 23 | import com.sun.fortress.scala_src.useful.SExprUtil |
|---|
| 24 | import scala.collection.immutable.EmptyMap |
|---|
| 25 | |
|---|
| 26 | /** |
|---|
| 27 | * Represents a list of variable name to type bindings for some context. All |
|---|
| 28 | * instances of this class should be created with `STypeEnv.make` or with the |
|---|
| 29 | * `extendWith` method. |
|---|
| 30 | */ |
|---|
| 31 | abstract sealed class STypeEnv extends StaticEnv[Type] { |
|---|
| 32 | |
|---|
| 33 | /** My type. */ |
|---|
| 34 | type Env = STypeEnv |
|---|
| 35 | |
|---|
| 36 | /** My binding type. */ |
|---|
| 37 | type EnvBinding = TypeBinding |
|---|
| 38 | |
|---|
| 39 | /** Extend me with the immediate bindings of the given node. */ |
|---|
| 40 | def extendWith(node: Any): STypeEnv = |
|---|
| 41 | new NestedSTypeEnv(this, STypeEnv.extractEnvBindings(node)) |
|---|
| 42 | |
|---|
| 43 | /** Same as `lookup`. */ |
|---|
| 44 | def getType(x: Name): Option[Type] = lookup(x).map(_.value) |
|---|
| 45 | } |
|---|
| 46 | |
|---|
| 47 | /** The single empty type environment. */ |
|---|
| 48 | object EmptySTypeEnv extends STypeEnv with EmptyStaticEnv[Type] |
|---|
| 49 | |
|---|
| 50 | /** |
|---|
| 51 | * A type environment with a parent and some explicit bindings. |
|---|
| 52 | * |
|---|
| 53 | * @param parent A type environment that this one extends. |
|---|
| 54 | * @param _bindings A collection of all the bindings in this environment. |
|---|
| 55 | */ |
|---|
| 56 | class NestedSTypeEnv protected (protected val parent: STypeEnv, |
|---|
| 57 | _bindings: Collection[TypeBinding]) |
|---|
| 58 | extends STypeEnv with NestedStaticEnv[Type] { |
|---|
| 59 | |
|---|
| 60 | /** Internal representation of `bindings` is a map. */ |
|---|
| 61 | protected val bindings: Map[Name, TypeBinding] = |
|---|
| 62 | new EmptyMap ++ _bindings.map(b => b.name -> b) |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | /** Companion module for STypeEnv. */ |
|---|
| 66 | object STypeEnv extends StaticEnvCompanion[Type] { |
|---|
| 67 | |
|---|
| 68 | /** My type. */ |
|---|
| 69 | type Env = STypeEnv |
|---|
| 70 | |
|---|
| 71 | /** My binding type. */ |
|---|
| 72 | type EnvBinding = TypeBinding |
|---|
| 73 | |
|---|
| 74 | /** New type environment with empty parent and the node's bindings. */ |
|---|
| 75 | def make(node: Any): STypeEnv = |
|---|
| 76 | new NestedSTypeEnv(EmptySTypeEnv, extractEnvBindings(node)) |
|---|
| 77 | |
|---|
| 78 | /** Extract out the bindings in node. */ |
|---|
| 79 | protected def extractEnvBindings(node: Any): Collection[TypeBinding] = null |
|---|
| 80 | // node match { |
|---|
| 81 | // case SParam => |
|---|
| 82 | // } |
|---|
| 83 | |
|---|
| 84 | // protected def extractFnDecls(node: Any): List[FnDecl] = null |
|---|
| 85 | // |
|---|
| 86 | // /** |
|---|
| 87 | // * A type environment that stores types of named functionals. Return types |
|---|
| 88 | // * might not always be given on functional declarations, so this type |
|---|
| 89 | // * environment will lazily evaluate those types as needed. |
|---|
| 90 | // * |
|---|
| 91 | // * This class should only ever be instantiated by `STypeEnv`. |
|---|
| 92 | // * |
|---|
| 93 | // * @param parent A static environment that this one extends. |
|---|
| 94 | // * @param fnDecls An immutable list of all the functional declarations in |
|---|
| 95 | // * scope for this type environment. |
|---|
| 96 | // */ |
|---|
| 97 | // protected class LazyFnTypeEnv(protected val parent: STypeEnv, |
|---|
| 98 | // protected val fnDecls: List[FnDecl], |
|---|
| 99 | // protected val initialChecker: STypeChecker) |
|---|
| 100 | // extends STypeEnv(parent, Nil) { |
|---|
| 101 | // |
|---|
| 102 | // import scala.collection.mutable.Map |
|---|
| 103 | // import scala.collection.mutable.Stack |
|---|
| 104 | // |
|---|
| 105 | // type TypeThunk = Function0[Option[Type]] |
|---|
| 106 | // type UnambiguousName = Name |
|---|
| 107 | // |
|---|
| 108 | // /** |
|---|
| 109 | // * Contains the function names that have been called thus far during the |
|---|
| 110 | // * type checking of function bodies in this environment. |
|---|
| 111 | // */ |
|---|
| 112 | // protected var callStack: Stack[Name] = new Stack |
|---|
| 113 | // |
|---|
| 114 | // /** Maps unsolved overloadings to their thunks. */ |
|---|
| 115 | // protected var unsolvedOverloadings: Map[UnambiguousName, TypeThunk] = Map.empty |
|---|
| 116 | // |
|---|
| 117 | // /** Maps solved overloadings to their thunks. */ |
|---|
| 118 | // protected var solvedOverloadings: Map[UnambiguousName, Type] = Map.empty |
|---|
| 119 | // |
|---|
| 120 | // /** */ |
|---|
| 121 | // protected var solved: Map[Name, Type] = Map.empty |
|---|
| 122 | // |
|---|
| 123 | // protected def makeThunk(fnDecl: FnDecl): TypeThunk = { |
|---|
| 124 | // |
|---|
| 125 | // // If return type given, just thunk it. |
|---|
| 126 | // fnDecl.getHeader.getReturnType match { |
|---|
| 127 | // case Some(t) => return () => t |
|---|
| 128 | // case _ => |
|---|
| 129 | // } |
|---|
| 130 | // |
|---|
| 131 | // // Get relevant parts out of the decl. |
|---|
| 132 | // val name = fnDecl.getHeader.getName |
|---|
| 133 | // val unambiguousName = fnDecl.getUnambiguousName |
|---|
| 134 | // val body = fnDecl.getBody.getOrElse(bug("No body on function.")) |
|---|
| 135 | // |
|---|
| 136 | // // Capture the type checker at this point. |
|---|
| 137 | // val checker = this.initialChecker |
|---|
| 138 | // def thunk: Option[Type] = { |
|---|
| 139 | // |
|---|
| 140 | // // If we have already seen this name, then there is a cycle! |
|---|
| 141 | // if (callStack.contains(name)) { |
|---|
| 142 | // checker.signal(body, "Cyclical reference to function %s while checking body of function %s" |
|---|
| 143 | // .format(name, this.callStack.top)) |
|---|
| 144 | // } |
|---|
| 145 | // |
|---|
| 146 | // // Add this name to the call stack. |
|---|
| 147 | // this.callStack += name |
|---|
| 148 | // |
|---|
| 149 | // // Extend the type checker with the params of this decl and check. |
|---|
| 150 | // val newChecker = checker.extend(fnDecl) |
|---|
| 151 | // SExprUtil.getType(newChecker.checkExpr(body)) |
|---|
| 152 | // } |
|---|
| 153 | // thunk _ |
|---|
| 154 | // } |
|---|
| 155 | // } |
|---|
| 156 | } |
|---|
| 157 | |
|---|
| 158 | |
|---|
| 159 | /** |
|---|
| 160 | * A binding for a type environment contains name to type pairs, along with some |
|---|
| 161 | * modifiers for the binding and whether or not the binding is mutable. |
|---|
| 162 | * |
|---|
| 163 | * @param name The variable name for the binding. |
|---|
| 164 | * @param value The bound type for this variable name. |
|---|
| 165 | * @param mods Any modifiers for the binding. |
|---|
| 166 | * @param mutable Whether or not the binding is mutable. |
|---|
| 167 | */ |
|---|
| 168 | case class TypeBinding(override val name: Name, |
|---|
| 169 | typ: Type, |
|---|
| 170 | mods: Modifiers, |
|---|
| 171 | mutable: Boolean) extends StaticBinding[Type](name, typ) |
|---|