summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala5
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala79
-rw-r--r--src/reflect/scala/reflect/api/Types.scala98
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala23
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala1
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala3
-rw-r--r--test/files/run/reflection-methodsymbol-allparams.check8
-rw-r--r--test/files/run/reflection-methodsymbol-allparams.scala24
-rw-r--r--test/files/run/reflection-methodsymbol-params.check8
-rw-r--r--test/files/run/reflection-methodsymbol-params.scala24
-rw-r--r--test/files/run/reflection-methodsymbol-resulttype.check8
-rw-r--r--test/files/run/reflection-methodsymbol-resulttype.scala24
-rw-r--r--test/files/run/reflection-methodsymbol-typeparams.check8
-rw-r--r--test/files/run/reflection-methodsymbol-typeparams.scala24
15 files changed, 239 insertions, 101 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
index 56b9c7011c..202d5d3f82 100644
--- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
@@ -212,8 +212,7 @@ trait TypeStrings {
}
private def tparamString[T: ru.TypeTag] : String = {
- // [Eugene++ to Paul] needs review!!
- def typeArguments: List[ru.Type] = ru.typeOf[T].typeArguments
+ def typeArguments: List[ru.Type] = ru.typeOf[T] match { case ru.TypeRef(_, _, args) => args; case _ => Nil }
// [Eugene++] todo. need to use not the `rootMirror`, but a mirror with the REPL's classloader
// how do I get to it? acquiring context classloader seems unreliable because of multithreading
def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => ru.rootMirror.runtimeClass(targ))
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 7bd5f4caeb..bd2808d049 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -70,11 +70,8 @@ trait MethodSynthesis {
// [Eugene++->Martin] now this compiles, will soon check it out
def newMethodType[F](owner: Symbol)(implicit t: TT[F]): Type = {
val fnSymbol = compilerSymbolFromTag(t)
- assert(fnSymbol isSubClass FunctionClass(t.tpe.typeArguments.size - 1), (owner, t))
- // [Eugene++ to Paul] needs review!!
- // val symbols = m.typeArguments map (m => manifestToSymbol(m))
- // val formals = symbols.init map (_.typeConstructor)
val formals = compilerTypeFromTag(t).typeArguments
+ assert(fnSymbol isSubClass FunctionClass(formals.size - 1), (owner, t))
val params = owner newSyntheticValueParams formals
MethodType(params, formals.last)
}
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index 7ca1d9c7c6..cd9044c934 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -43,23 +43,6 @@ trait Symbols extends base.Symbols { self: Universe =>
*/
def hasAnnotation(sym: Symbol): Boolean
- /** ...
- */
- def orElse(alt: => Symbol): Symbol
-
- /** ...
- */
- def filter(cond: Symbol => Boolean): Symbol
-
- /** If this is a NoSymbol, returns NoSymbol, otherwise
- * returns the result of applying `f` to this symbol.
- */
- def map(f: Symbol => Symbol): Symbol
-
- /** ...
- */
- def suchThat(cond: Symbol => Boolean): Symbol
-
/**
* Set when symbol has a modifier of the form private[X], NoSymbol otherwise.
*
@@ -93,15 +76,17 @@ trait Symbols extends base.Symbols { self: Universe =>
*/
def companionSymbol: Symbol
- /** If this symbol is a package class, this symbol; otherwise the next enclosing
- * package class, or `NoSymbol` if none exists.
+ /** The type signature of this symbol seen as a member of given type `site`.
*/
- def enclosingPackageClass: Symbol
+ def typeSignatureIn(site: Type): Type
- /** If this symbol is a top-level class, this symbol; otherwise the next enclosing
- * top-level class, or `NoSymbol` if none exists.
+ /** The type signature of this symbol.
+ * Note if the symbol is a member of a class, one almost always is interested
+ * in `typeSignatureIn` with a site type instead.
*/
- def enclosingTopLevelClass: Symbol
+ def typeSignature: Type
+
+ /******************* tests *******************/
/** Does this symbol represent the definition of a package?
* If yes, `isTerm` is also guaranteed to be true.
@@ -136,15 +121,24 @@ trait Symbols extends base.Symbols { self: Universe =>
*/
def isStatic: Boolean
- /** The type signature of this symbol seen as a member of given type `site`.
+ /******************* helpers *******************/
+
+ /** ...
*/
- def typeSignatureIn(site: Type): Type
+ def orElse(alt: => Symbol): Symbol
- /** The type signature of this symbol.
- * Note if the symbol is a member of a class, one almost always is interested
- * in `typeSignatureIn` with a site type instead.
+ /** ...
*/
- def typeSignature: Type
+ def filter(cond: Symbol => Boolean): Symbol
+
+ /** If this is a NoSymbol, returns NoSymbol, otherwise
+ * returns the result of applying `f` to this symbol.
+ */
+ def map(f: Symbol => Symbol): Symbol
+
+ /** ...
+ */
+ def suchThat(cond: Symbol => Boolean): Symbol
/** The string discriminator of this symbol; useful for debugging */
def kind: String
@@ -263,10 +257,33 @@ trait Symbols extends base.Symbols { self: Universe =>
}
/** The API of method symbols */
- type MethodSymbolApi = MethodSymbolBase
+ trait MethodSymbolApi extends TermSymbolApi with MethodSymbolBase { this: MethodSymbol =>
+ /** For a polymorphic method, its type parameters, the empty list for all other methods */
+ def typeParams: List[Symbol]
+
+ /** The first parameter list of the method.
+ *
+ * For a nullary method, returns the empty list.
+ * For a method with an empty parameter list, returns the empty list.
+ * To distinguish between those, use `allParams`.
+ */
+ def params: List[Symbol]
+
+ /** All parameter lists of the method.
+ *
+ * Can be used to distinguish nullary methods and methods with empty parameter lists.
+ * For a nullary method, returns the empty list (i.e. `List()`).
+ * For a method with an empty parameter list, returns a list that contains the empty list (i.e. `List(List())`).
+ */
+ def allParams: List[List[Symbol]]
+
+ /** The result type of the method */
+ def resultType: Type
+ }
/** The API of module symbols */
- type ModuleSymbolApi = ModuleSymbolBase
+ trait ModuleSymbolApi extends TermSymbolApi with ModuleSymbolBase { this: ModuleSymbol =>
+ }
/** The API of class symbols */
trait ClassSymbolApi extends TypeSymbolApi with ClassSymbolBase { this: ClassSymbol =>
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index 33248fcbee..199cf9b9e5 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -45,45 +45,14 @@ trait Types extends base.Types { self: Universe =>
*/
def members: MemberScope
- /** Substitute symbols in `to` for corresponding occurrences of references to
- * symbols `from` in this type.
- */
- def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type
-
- /** Substitute types in `to` for corresponding occurrences of references to
- * symbols `from` in this type.
- */
- def substituteTypes(from: List[Symbol], to: List[Type]): Type
-
- /** If this is a parameterized types, the type arguments.
- * Otherwise the empty list
- */
- def typeArguments: List[Type]
-
- /** For a (potentially wrapped) poly type, its type parameters,
- * the empty list for all other types */
- def typeParams: List[Symbol]
-
- /** For a (nullary) method or poly type, its direct result type,
- * the type itself for all other types. */
- def resultType: Type
-
/** Is this type a type constructor that is missing its type arguments?
*/
- def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no?
+ def takesTypeArgs: Boolean
/** Returns the corresponding type constructor (e.g. List for List[T] or List[String])
*/
def typeConstructor: Type
- /** Does this type refer to spliceable types or is a spliceable type?
- */
- def isConcrete: Boolean
-
- /** Is this type an abstract type that needs to be resolved?
- */
- def isSpliceable: Boolean
-
/**
* Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
* Functions on types are also implemented as PolyTypes.
@@ -92,7 +61,7 @@ trait Types extends base.Types { self: Universe =>
* TypeRef(pre, <List>, List()) is replaced by
* PolyType(X, TypeRef(pre, <List>, List(X)))
*/
- def normalize: Type // !!! Alternative name? "normalize" is used to mean too many things.
+ def normalize: Type
/** Does this type conform to given type argument `that`? */
def <:< (that: Type): Boolean
@@ -104,7 +73,7 @@ trait Types extends base.Types { self: Universe =>
* in reverse linearization order, starting with the class itself and ending
* in class Any.
*/
- def baseClasses: List[Symbol] // !!! Alternative name, perhaps linearization?
+ def baseClasses: List[Symbol]
/** The least type instance of given class which is a supertype
* of this type. Example:
@@ -134,36 +103,7 @@ trait Types extends base.Types { self: Universe =>
/** The erased type corresponding to this type after
* all transformations from Scala to Java have been performed.
*/
- def erasure: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased")
- // why not name it "erasure"?
-
- /** Apply `f` to each part of this type, returning
- * a new type. children get mapped before their parents */
- def map(f: Type => Type): Type
-
- /** Apply `f` to each part of this type, for side effects only */
- def foreach(f: Type => Unit)
-
- /** Returns optionally first type (in a preorder traversal) which satisfies predicate `p`,
- * or None if none exists.
- */
- def find(p: Type => Boolean): Option[Type]
-
- /** Is there part of this type which satisfies predicate `p`? */
- def exists(p: Type => Boolean): Boolean
-
- /** Does this type contain a reference to given symbol? */
- def contains(sym: Symbol): Boolean
-
- /** If this is a compound type, the list of its parent types;
- * otherwise the empty list
- */
- def parents: List[Type]
-
- /** If this is a singleton type, returns the type underlying it;
- * otherwise returns this type itself.
- */
- def underlying: Type
+ def erasure: Type
/** If this is a singleton type, widen it to its nearest underlying non-singleton
* base type by applying one or more `underlying` dereferences.
@@ -186,6 +126,36 @@ trait Types extends base.Types { self: Universe =>
*/
def narrow: Type
+ /******************* helpers *******************/
+
+ /** Substitute symbols in `to` for corresponding occurrences of references to
+ * symbols `from` in this type.
+ */
+ def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type
+
+ /** Substitute types in `to` for corresponding occurrences of references to
+ * symbols `from` in this type.
+ */
+ def substituteTypes(from: List[Symbol], to: List[Type]): Type
+
+ /** Apply `f` to each part of this type, returning
+ * a new type. children get mapped before their parents */
+ def map(f: Type => Type): Type
+
+ /** Apply `f` to each part of this type, for side effects only */
+ def foreach(f: Type => Unit)
+
+ /** Returns optionally first type (in a preorder traversal) which satisfies predicate `p`,
+ * or None if none exists.
+ */
+ def find(p: Type => Boolean): Option[Type]
+
+ /** Is there part of this type which satisfies predicate `p`? */
+ def exists(p: Type => Boolean): Boolean
+
+ /** Does this type contain a reference to given symbol? */
+ def contains(sym: Symbol): Boolean
+
/** The string discriminator of this type; useful for debugging */
def kind: String
}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 8cf20ba062..68144da2d7 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -2486,6 +2486,29 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
mtpeResult = res
res
}
+
+ override def allParams: List[List[Symbol]] = paramss
+
+ override def params: List[Symbol] = {
+ def loop(tpe: Type): List[Symbol] =
+ tpe match {
+ case NullaryMethodType(_) => Nil
+ case MethodType(params, _) => params
+ case PolyType(_, tpe) => loop(tpe)
+ }
+ loop(info)
+ }
+
+ override def resultType: Type = {
+ def loop(tpe: Type): Type =
+ tpe match {
+ case NullaryMethodType(ret) => loop(ret)
+ case MethodType(_, ret) => loop(ret)
+ case PolyType(_, tpe) => loop(tpe)
+ case tpe => tpe
+ }
+ loop(info)
+ }
}
implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol])
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 1386cca42f..442a91774d 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -323,6 +323,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** Is this type higher-kinded, i.e., is it a type constructor @M */
def isHigherKinded: Boolean = false
+ def takesTypeArgs: Boolean = this.isHigherKinded
/** Does this type denote a stable reference (i.e. singleton type)? */
def isStable: Boolean = false
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
index 6a3501b1dd..525673fe6d 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -110,6 +110,9 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol {
override def typeAsMemberOf(pre: Type): Type = synchronized { super.typeAsMemberOf(pre) }
+ override def allParams: List[List[Symbol]] = synchronized { super.allParams }
+ override def params: List[Symbol] = synchronized { super.params }
+ override def resultType: Type = synchronized { super.resultType }
}
trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol {
diff --git a/test/files/run/reflection-methodsymbol-allparams.check b/test/files/run/reflection-methodsymbol-allparams.check
new file mode 100644
index 0000000000..11f349d52b
--- /dev/null
+++ b/test/files/run/reflection-methodsymbol-allparams.check
@@ -0,0 +1,8 @@
+List()
+List(List())
+List(List(value x))
+List(List(value x), List(value y))
+List()
+List(List())
+List(List(value x))
+List(List(value x), List(value y))
diff --git a/test/files/run/reflection-methodsymbol-allparams.scala b/test/files/run/reflection-methodsymbol-allparams.scala
new file mode 100644
index 0000000000..cfd14f56a5
--- /dev/null
+++ b/test/files/run/reflection-methodsymbol-allparams.scala
@@ -0,0 +1,24 @@
+import scala.reflect.runtime.universe._
+
+class C {
+ def x1: Int = ???
+ def x2(): Int = ???
+ def x3(x: Int): Int = ???
+ def x4(x: Int)(y: Int): Int = ???
+
+ def y1[T]: Int = ???
+ def y2[T](): Int = ???
+ def y3[T](x: Int): Int = ???
+ def y4[T](x: Int)(y: Int): Int = ???
+}
+
+object Test extends App {
+ println(typeOf[C].member(newTermName("x1")).asMethodSymbol.allParams)
+ println(typeOf[C].member(newTermName("x2")).asMethodSymbol.allParams)
+ println(typeOf[C].member(newTermName("x3")).asMethodSymbol.allParams)
+ println(typeOf[C].member(newTermName("x4")).asMethodSymbol.allParams)
+ println(typeOf[C].member(newTermName("y1")).asMethodSymbol.allParams)
+ println(typeOf[C].member(newTermName("y2")).asMethodSymbol.allParams)
+ println(typeOf[C].member(newTermName("y3")).asMethodSymbol.allParams)
+ println(typeOf[C].member(newTermName("y4")).asMethodSymbol.allParams)
+} \ No newline at end of file
diff --git a/test/files/run/reflection-methodsymbol-params.check b/test/files/run/reflection-methodsymbol-params.check
new file mode 100644
index 0000000000..899ae15a0c
--- /dev/null
+++ b/test/files/run/reflection-methodsymbol-params.check
@@ -0,0 +1,8 @@
+List()
+List()
+List(value x)
+List(value x)
+List()
+List()
+List(value x)
+List(value x)
diff --git a/test/files/run/reflection-methodsymbol-params.scala b/test/files/run/reflection-methodsymbol-params.scala
new file mode 100644
index 0000000000..654a16b59d
--- /dev/null
+++ b/test/files/run/reflection-methodsymbol-params.scala
@@ -0,0 +1,24 @@
+import scala.reflect.runtime.universe._
+
+class C {
+ def x1: Int = ???
+ def x2(): Int = ???
+ def x3(x: Int): Int = ???
+ def x4(x: Int)(y: Int): Int = ???
+
+ def y1[T]: Int = ???
+ def y2[T](): Int = ???
+ def y3[T](x: Int): Int = ???
+ def y4[T](x: Int)(y: Int): Int = ???
+}
+
+object Test extends App {
+ println(typeOf[C].member(newTermName("x1")).asMethodSymbol.params)
+ println(typeOf[C].member(newTermName("x2")).asMethodSymbol.params)
+ println(typeOf[C].member(newTermName("x3")).asMethodSymbol.params)
+ println(typeOf[C].member(newTermName("x4")).asMethodSymbol.params)
+ println(typeOf[C].member(newTermName("y1")).asMethodSymbol.params)
+ println(typeOf[C].member(newTermName("y2")).asMethodSymbol.params)
+ println(typeOf[C].member(newTermName("y3")).asMethodSymbol.params)
+ println(typeOf[C].member(newTermName("y4")).asMethodSymbol.params)
+} \ No newline at end of file
diff --git a/test/files/run/reflection-methodsymbol-resulttype.check b/test/files/run/reflection-methodsymbol-resulttype.check
new file mode 100644
index 0000000000..0f30d1beaf
--- /dev/null
+++ b/test/files/run/reflection-methodsymbol-resulttype.check
@@ -0,0 +1,8 @@
+Int
+Int
+Int
+Int
+Int
+Int
+Int
+Int
diff --git a/test/files/run/reflection-methodsymbol-resulttype.scala b/test/files/run/reflection-methodsymbol-resulttype.scala
new file mode 100644
index 0000000000..7a9f66dda8
--- /dev/null
+++ b/test/files/run/reflection-methodsymbol-resulttype.scala
@@ -0,0 +1,24 @@
+import scala.reflect.runtime.universe._
+
+class C {
+ def x1: Int = ???
+ def x2(): Int = ???
+ def x3(x: Int): Int = ???
+ def x4(x: Int)(y: Int): Int = ???
+
+ def y1[T]: Int = ???
+ def y2[T](): Int = ???
+ def y3[T](x: Int): Int = ???
+ def y4[T](x: Int)(y: Int): Int = ???
+}
+
+object Test extends App {
+ println(typeOf[C].member(newTermName("x1")).asMethodSymbol.resultType)
+ println(typeOf[C].member(newTermName("x2")).asMethodSymbol.resultType)
+ println(typeOf[C].member(newTermName("x3")).asMethodSymbol.resultType)
+ println(typeOf[C].member(newTermName("x4")).asMethodSymbol.resultType)
+ println(typeOf[C].member(newTermName("y1")).asMethodSymbol.resultType)
+ println(typeOf[C].member(newTermName("y2")).asMethodSymbol.resultType)
+ println(typeOf[C].member(newTermName("y3")).asMethodSymbol.resultType)
+ println(typeOf[C].member(newTermName("y4")).asMethodSymbol.resultType)
+} \ No newline at end of file
diff --git a/test/files/run/reflection-methodsymbol-typeparams.check b/test/files/run/reflection-methodsymbol-typeparams.check
new file mode 100644
index 0000000000..c888e09a17
--- /dev/null
+++ b/test/files/run/reflection-methodsymbol-typeparams.check
@@ -0,0 +1,8 @@
+List()
+List()
+List()
+List()
+List(type T)
+List(type T)
+List(type T)
+List(type T)
diff --git a/test/files/run/reflection-methodsymbol-typeparams.scala b/test/files/run/reflection-methodsymbol-typeparams.scala
new file mode 100644
index 0000000000..28f1c8973d
--- /dev/null
+++ b/test/files/run/reflection-methodsymbol-typeparams.scala
@@ -0,0 +1,24 @@
+import scala.reflect.runtime.universe._
+
+class C {
+ def x1: Int = ???
+ def x2(): Int = ???
+ def x3(x: Int): Int = ???
+ def x4(x: Int)(y: Int): Int = ???
+
+ def y1[T]: Int = ???
+ def y2[T](): Int = ???
+ def y3[T](x: Int): Int = ???
+ def y4[T](x: Int)(y: Int): Int = ???
+}
+
+object Test extends App {
+ println(typeOf[C].member(newTermName("x1")).asMethodSymbol.typeParams)
+ println(typeOf[C].member(newTermName("x2")).asMethodSymbol.typeParams)
+ println(typeOf[C].member(newTermName("x3")).asMethodSymbol.typeParams)
+ println(typeOf[C].member(newTermName("x4")).asMethodSymbol.typeParams)
+ println(typeOf[C].member(newTermName("y1")).asMethodSymbol.typeParams)
+ println(typeOf[C].member(newTermName("y2")).asMethodSymbol.typeParams)
+ println(typeOf[C].member(newTermName("y3")).asMethodSymbol.typeParams)
+ println(typeOf[C].member(newTermName("y4")).asMethodSymbol.typeParams)
+} \ No newline at end of file