├── .gitignore
├── README.markdown
├── project
├── build.properties
├── build
│ └── project.scala
└── plugins
│ ├── Plugins.scala
│ └── project
│ └── build.properties
└── src
├── main
└── scala
│ └── scalaj
│ └── reflect
│ ├── AutographBook.scala
│ ├── Collatable.scala
│ ├── ForwardPipe.scala
│ ├── Mirrors.scala
│ ├── NameHelpers.scala
│ ├── SymbolTreePrinter.scala
│ ├── TypeMirrors.scala
│ └── TypeWrangler.scala
└── test
└── scala
└── scalaj
└── reflect
├── AutographBookSpec.scala
├── CollatableSpec.scala
├── ExpectedPrintTrees.scala
├── MirrorsSpec.scala
├── SymbolTreePrinterSpec.scala
├── TypeWranglerSpec.scala
└── targets
├── BasicSample.scala
├── NestedPolymorphicSample.scala
├── PolymorphicSample.scala
├── TweedleDee.scala
├── TweedleDo.scala
└── TweedleDum.scala
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea/
3 | .classpath
4 | .project
5 | .scala_dependencies
6 | */log/
7 | */tmp/
8 | *~
9 | .#*
10 | CVS/
11 | .svn/
12 | .hg/
13 | target/
14 | lib_managed/
15 | src_managed/
16 | project/boot/
17 | project/build/target/
18 | project/plugins/target/
19 | project/plugins/project/
20 | project/plugins/lib_managed/
21 | project/plugins/src_managed/
22 | .cvsignore
23 | .hgignore
24 | *.iml
25 | *.iws
26 | *.ipr
27 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # scalaj-reflect
2 |
3 | A reflection library based on the Scala Signature logic from scalap
4 |
5 | ## Usage
6 |
7 | TBD
8 |
9 | ## Requirements
10 |
11 | scalaj-reflect requires Scala 2.8.1+
12 |
13 | ## Installation
14 |
15 | ### sbt
16 |
17 | If you're using simple-build-tool, simply add the following line to your project file:
18 |
19 | val scalaj_spring = "org.scalaj" %% "scalaj-reflect" % "0.1-SNAPSHOT"
20 |
21 | ### Maven
22 |
23 | If you're using Maven, add the following to your pom.xml:
24 |
25 |
26 | org.scalaj
27 | scalaj-reflect_${scala.version}
28 | 0.1-SNAPSHOT
29 |
30 |
31 | ### JARs
32 |
33 | Soon to be released at [scala-tools.org](http://www.scala-tools.org/repo-releases/org/scalaj/scalaj-reflect_2.8.1/0.1-SNAPSHOT/)
34 |
35 | ### From source
36 |
37 | Clone the repository from Github:
38 |
39 | git clone git://github.com/scalaj/scalaj-reflect.git
40 |
41 | Build the project and create the JAR (requires [sbt](http://code.google.com/p/simple-build-tool/) version 0.7.4 or greater):
42 |
43 | cd scalaj-reflect
44 | sbt package
45 |
46 | ## Documentation
47 |
48 | TBD
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | #Project properties
2 | #Sun Nov 22 18:53:20 PST 2009
3 | project.organization=org.scalaj
4 | project.name=scalaj-reflect
5 | sbt.version=0.7.7
6 | project.version=0.1-SNAPSHOT
7 | def.scala.version=2.7.7
8 | build.scala.versions=2.9.0
9 | project.initialize=false
10 |
--------------------------------------------------------------------------------
/project/build/project.scala:
--------------------------------------------------------------------------------
1 | import sbt._
2 | import de.element34.sbteclipsify._
3 |
4 |
5 | class ScalajProject(info: ProjectInfo) extends DefaultProject(info)
6 | with IdeaProject
7 | with Eclipsify
8 | with posterous.Publish {
9 | override def compileOptions = Seq(Deprecation, Unchecked)
10 |
11 | //Dependencies
12 | val scalap = "org.scala-lang" % "scalap" % "2.8.1" withSources()
13 | val specs = "org.scala-tools.testing" %% "specs" % "1.6.6"
14 | val unit = "junit" % "junit" % "4.8.2" % "test"
15 | //val logback = "ch.qos.logback" % "logback-classic" % "0.9.25"
16 | //val grizzledSlf4j = "org.clapper" %% "grizzled-slf4j" % "0.3.2"
17 |
18 | // Publishing
19 | override def managedStyle = ManagedStyle.Maven
20 | val publishTo = "Scala Tools Nexus" at "http://nexus.scala-tools.org/content/repositories/snapshots/"
21 | Credentials(Path.userHome / ".ivy2" / ".credentials", log)
22 | override def publishAction = super.publishAction && publishCurrentNotes
23 | override def extraTags = "scalaj" :: super.extraTags
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/project/plugins/Plugins.scala:
--------------------------------------------------------------------------------
1 | import sbt._
2 | class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
3 |
4 | val edinboroughUniRepo = "www2.ph.ed.ac.uk-releases" at "http://www2.ph.ed.ac.uk/maven2/"
5 | val sbtIdeaRepo = "sbt-idea-repo" at "http://mpeltonen.github.com/maven/"
6 | val thuntRepo = "t_repo" at "http://tristanhunt.com:8081/content/groups/public/"
7 | val sbtIdea = "com.github.mpeltonen" % "sbt-idea-plugin" % "0.4.0"
8 | val posterous = "net.databinder" % "posterous-sbt" % "0.1.6"
9 | val eclipse = "de.element34" % "sbt-eclipsify" % "0.7.0"
10 | }
11 |
--------------------------------------------------------------------------------
/project/plugins/project/build.properties:
--------------------------------------------------------------------------------
1 | #Project properties
2 | #Tue Jan 04 07:41:40 GMT 2011
3 | plugin.uptodate=true
4 |
--------------------------------------------------------------------------------
/src/main/scala/scalaj/reflect/AutographBook.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | import tools.scalap.scalax.rules.scalasig._
4 | import reflect.ScalaSignature
5 | import scala.reflect.generic.ByteCodecs
6 |
7 | object AutographBook {
8 |
9 | def decodeSigBytes(bytes: Array[Byte]): Array[Byte] = {
10 | val length = ByteCodecs.decode(bytes)
11 | bytes.take(length)
12 | }
13 |
14 | def sigBytesFromAnnotation(sig: ScalaSignature) = decodeSigBytes(sig.bytes.getBytes)
15 |
16 | def sigBytesFromType(tpe: Class[_]) = {
17 | tpe.getAnnotations.view collect { case x: ScalaSignature => x } map {sigBytesFromAnnotation} headOption
18 | }
19 |
20 | def sigFromBytes(bytes: Array[Byte]) = ScalaSigAttributeParsers.parse(ByteCode(bytes))
21 |
22 | def sigFromType(tpe: Class[_]) = sigBytesFromType(tpe) map (sigFromBytes)
23 |
24 | def topLevelSymsFromSig(s: ScalaSig) = s.topLevelClasses ++ s.topLevelObjects
25 |
26 | def decompile(s: ScalaSig) =
27 | tools.scalap.Main.parseScalaSignature(s, false)
28 |
29 | def safeGetClass(name: String): Option[Class[_]] = {
30 | try Some(Class forName name) catch { case e: Exception => None }
31 | }
32 |
33 | /**
34 | * Given a string, will return a `Class[_] -> String` representing the longest possible
35 | * match that's a valid class name, paired with the remainder of the string.
36 | */
37 |
38 | def resolveClassAndRemainder(path: String) = {
39 | val splitPoints = path.zipWithIndex collect {case ('.',i) => i}
40 | val splits = (path->"") +: (splitPoints.reverse map {path.splitAt} map { case (a,b) => (a,b.tail)})
41 | splits.view flatMap { case (l,r) => safeGetClass(l) map (_ -> r) } headOption
42 | }
43 |
44 | def resolveExternal(path: String) = {
45 | resolveClassAndRemainder(path) map { resolv =>
46 | val (cls, remainder) = resolv
47 | val subparts = remainder split '.'
48 | val sig = sigFromType(cls)
49 | val syms = sig.toSeq flatMap { _.symbols } collect {
50 | case sym: AliasSymbol if sym.name == remainder => sym
51 | }
52 | syms
53 | }
54 | }
55 |
56 | def deAlias(sym: AliasSymbol) = {
57 | sym.infoType
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/scala/scalaj/reflect/Collatable.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | import collection.generic.CanBuildFrom
4 |
5 | /**
6 | * Adds the `collate` method to traversable collections.
7 | *
8 | * This is a cross between collect and partition, comparing elements against a partial function
9 | * and extracting matches into a collection of the same type as the PF's return (as `collect` does).
10 | * But also returning non-matches in a collection with the same type as the input (as `partition` does).
11 | *
12 | */
13 | import collection.generic.CanBuildFrom
14 |
15 | class Collatable[Repr <% Traversable[T], T] {
16 | //class Collatable[Repr, T](xs: Repr)(implicit bf: CanBuildFrom[Repr, T, Repr], ev: Repr => Traversable[T]) {
17 | def of(xs: Repr)(implicit rbf: CanBuildFrom[Repr, T, Repr]) = new Of(xs)
18 | class Of(xs: Repr)(implicit rbf: CanBuildFrom[Repr, T, Repr]) {
19 | trait Results {
20 | def remainder: Repr
21 |
22 | type Append[That] <: Results
23 | def append[That](tup: (That, Repr)): Append[That]
24 |
25 | def andThen[R, That](pf: PartialFunction[T, R])(implicit mbf: CanBuildFrom[Repr, R, That]) = {
26 | val more = of(remainder).collateOne[R,That](pf)
27 | append(more)
28 | }
29 | }
30 |
31 | case class Results9[M1,M2,M3,M4,M5,M6,M7,M8,M9](
32 | m1: M1, m2: M2, m3: M3, m4: M4, m5: M5, m6: M6, m7: M7, m8: M8, m9: M9, remainder: Repr)
33 | extends Results {
34 | implicit def toTuple = (m1, m2, m3, m4, m5, m6, m7, m8, m9, remainder)
35 | def append[That](tup: (That, Repr)) = error("can't collate beyond 9 elements")
36 | }
37 |
38 | case class Results8[M1,M2,M3,M4,M5,M6,M7,M8](
39 | m1: M1, m2: M2, m3: M3, m4: M4, m5: M5, m6: M6, m7: M7, m8: M8, remainder: Repr)
40 | extends Results {
41 | implicit def toTuple = (m1, m2, m3, m4, m5, m6, m7, m8, remainder)
42 | type Append[That] = Results9[M1,M2,M3,M4,M5,M6,M7,M8,That]
43 | def append[That](tup: (That, Repr)) = Results9(m1, m2, m3, m4, m5, m6, m7, m8, tup._1, tup._2)
44 | }
45 |
46 | case class Results7[M1,M2,M3,M4,M5,M6,M7](
47 | m1: M1, m2: M2, m3: M3, m4: M4, m5: M5, m6: M6, m7: M7, remainder: Repr)
48 | extends Results {
49 | implicit def toTuple = (m1, m2, m3, m4, m5, m6, m7, remainder)
50 | type Append[That] = Results8[M1,M2,M3,M4,M5,M6,M7,That]
51 | def append[That](tup: (That, Repr)) = Results8(m1, m2, m3, m4, m5, m6, m7, tup._1, tup._2)
52 | }
53 |
54 | case class Results6[M1,M2,M3,M4,M5,M6](
55 | m1: M1, m2: M2, m3: M3, m4: M4, m5: M5, m6: M6, remainder: Repr)
56 | extends Results {
57 | implicit def toTuple = (m1, m2, m3, m4, m5, m6, remainder)
58 | type Append[That] = Results7[M1,M2,M3,M4,M5,M6,That]
59 | def append[That](tup: (That, Repr)) = Results7(m1, m2, m3, m4, m5, m6, tup._1, tup._2)
60 | }
61 |
62 | case class Results5[M1,M2,M3,M4,M5](
63 | m1: M1, m2: M2, m3: M3, m4: M4, m5: M5, remainder: Repr)
64 | extends Results {
65 | implicit def toTuple = (m1, m2, m3, m4, m5, remainder)
66 | type Append[That] = Results6[M1,M2,M3,M4,M5,That]
67 | def append[That](tup: (That, Repr)) = Results6(m1, m2, m3, m4, m5, tup._1, tup._2)
68 | }
69 |
70 | case class Results4[M1,M2,M3,M4](
71 | m1: M1, m2: M2, m3: M3, m4: M4, remainder: Repr)
72 | extends Results {
73 | implicit def toTuple = (m1, m2, m3, m4, remainder)
74 | type Append[That] = Results5[M1,M2,M3,M4,That]
75 | def append[That](tup: (That, Repr)) = Results5(m1, m2, m3, m4, tup._1, tup._2)
76 | }
77 |
78 | case class Results3[M1,M2,M3](
79 | m1: M1, m2: M2, m3: M3, remainder: Repr)
80 | extends Results {
81 | implicit def toTuple = (m1, m2, m3, remainder)
82 | type Append[That] = Results4[M1,M2,M3,That]
83 | def append[That](tup: (That, Repr)) = Results4(m1, m2, m3, tup._1, tup._2)
84 | }
85 |
86 | case class Results2[M1,M2](
87 | m1: M1, m2: M2, remainder: Repr)
88 | extends Results {
89 | implicit def toTuple = (m1, m2, remainder)
90 | type Append[That] = Results3[M1,M2,That]
91 | def append[That](tup: (That, Repr)) = Results3(m1, m2, tup._1, tup._2)
92 | }
93 |
94 | case class Results1[M1](matches: M1, remainder: Repr) extends Results {
95 | implicit def toTuple = (matches, remainder)
96 |
97 | type Append[That] = Results2[M1, That]
98 | def append[That](tup: (That, Repr)) = Results2(matches, tup._1, tup._2)
99 | }
100 |
101 | def collateOne[R, That](pf: PartialFunction[T, R])(implicit mbf: CanBuildFrom[Repr, R, That]) = {
102 | val matches = mbf(xs)
103 | val remainder = rbf(xs)
104 | for (x <- xs) if (pf.isDefinedAt(x)) matches += pf(x) else remainder += x
105 | (matches.result, remainder.result)
106 | }
107 |
108 | def collate[R, That](pf: PartialFunction[T, R])(implicit mbf: CanBuildFrom[Repr, R, That]): Results1[That] = {
109 | val tup = collateOne[R,That](pf)
110 | Results1(tup._1, tup._2)
111 | }
112 | }
113 | }
114 |
115 | object Collatable {
116 | implicit def traversableIsCollatable[CC[X] <: Traversable[X], T]
117 | (xs: CC[T])(implicit rbf: CanBuildFrom[CC[T], T, CC[T]]) = new Collatable[CC[T], T] of xs
118 |
119 | implicit def stringIsCollatable(xs: String) = new Collatable[String, Char] of xs
120 | }
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/src/main/scala/scalaj/reflect/ForwardPipe.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 |
4 | class ForwardPipe[A](value: A) {
5 | def |>[B](f: A => B): B = f(value)
6 | }
7 |
8 | object ForwardPipe {
9 | implicit def apply[A](a: => A) = new ForwardPipe(a)
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/scala/scalaj/reflect/Mirrors.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | import tools.scalap.scalax.rules.scalasig.{Type => SymType, _}
4 | import java.lang.Class
5 | import java.lang.reflect.{Type => JType}
6 |
7 | import Collatable._
8 | import reflect.{Manifest, NoManifest}
9 |
10 | /**
11 | * Mirrors symbols; anything with a name that can be referenced elsewhere
12 | */
13 | object Mirror {
14 | import NameHelpers._
15 | val cache = collection.mutable.Map.empty[Symbol, Mirror]
16 |
17 | private def generateFor(sym: Symbol): Mirror = sym match {
18 | case o: ObjectSymbol => ObjectMirror(o)
19 | case c: ClassSymbol if !isRefinementClass(c) && !c.isModule => ClassMirror(c)
20 | case m: MethodSymbol => MethodMirror(m)
21 | // case t: TypeSymbol if !t.isParam && !t.name.matches("_\\$\\d+")=> error("not implemented")
22 | case x => RawSymbolMirror(x)
23 | }
24 |
25 | def ofSymbol(sym: Symbol): Mirror = cache.getOrElseUpdate(sym, generateFor(sym))
26 |
27 | def ofClass[T: ClassManifest]: Option[ClassMirror] = {
28 | val tpe = classManifest[T].erasure
29 | val sig = AutographBook.sigFromType(tpe)
30 |
31 | val classes = sig map { _.topLevelClasses }
32 | val sym = classes flatMap { _ find (_.name == tpe.getSimpleName) }
33 | sym map {Mirror ofSymbol} collect { case cm: ClassMirror => cm}
34 | }
35 |
36 | def ofClass[T](clazz: Class[T]): Option[ClassMirror] = {
37 | val sig = AutographBook.sigFromType(clazz)
38 |
39 | val classes = sig map { _.topLevelClasses }
40 | val sym = classes flatMap { _ find (_.name == clazz.getSimpleName) }
41 | sym map {Mirror ofSymbol} collect { case cm: ClassMirror => cm}
42 | }
43 |
44 | def ofObject[T <: AnyRef with Singleton](obj: T): Option[ObjectMirror] = {
45 | val tpe = obj.getClass
46 | val sig = AutographBook.sigFromType(tpe)
47 |
48 | val objects = sig map { _.topLevelObjects }
49 | val sym = objects flatMap { _ find (_.name == tpe.getName) }
50 | sym map {Mirror ofSymbol} collect { case cm: ObjectMirror => cm}
51 | }
52 |
53 | }
54 |
55 | sealed trait Mirror
56 | sealed trait NamedMirror extends Mirror { def name: String }
57 |
58 |
59 | ////////////////////////
60 | // TYPE MIRRORS
61 | //
62 |
63 | object TypeMirror {
64 | def apply(tpe: SymType) = tpe match {
65 | // case mt: MethodType => MethodMirror(mt)
66 | case trt: TypeRefType => TypeRefMirror(trt)
67 | case st: SingleType => SingleTypeMirror(st)
68 | case pt: PolyType => PolyTypeMirror(pt)
69 | case x => RawTypeMirror(x)
70 | }
71 | }
72 |
73 | sealed trait TypeMirror extends Mirror {
74 | def tpe: SymType
75 | def toManifest[T <: AnyRef]: Manifest[T]
76 | override def toString = "<>"
77 | }
78 |
79 | case class RawTypeMirror(tpe: SymType) extends TypeMirror {
80 | def toManifest[T <: AnyRef]: Manifest[T] = tpe match {
81 | case ThisType(symbol) => error("todo - ThisType manifest")
82 | case SingleType(typeRef, symbol) => error("todo - SingleType manifest")
83 | case ConstantType(constant) => error("todo - ConstantType manifest")
84 | //case TypeRefType(prefix, symbol, typeArgs) => ...
85 | case TypeBoundsType(lower, upper) =>
86 | val lbound = TypeMirror(lower).toManifest
87 | val ubound = TypeMirror(upper).toManifest
88 | Manifest.wildcardType(lbound, ubound)
89 | case RefinedType(classSym, typeRefs) => error("todo - RefinedType manifest")
90 | case ClassInfoType(symbol, typeRefs) =>
91 | //todo: check for poly
92 | Manifest.classType(Class.forName(symbol.path))
93 | //error("todo - ClassInfoType manifest")
94 | case ClassInfoTypeWithCons(symbol, typeRefs, cons) => error("todo - ClassInfoTypeWithCons manifest")
95 | case MethodType(resultType, paramSymbols) => error("todo - MethodType manifest")
96 | //case PolyType(typeRef, symbols) => error("todo")
97 | case PolyTypeWithCons(typeRef, symbols, cons) => error("todo - PolyTypeWithCons manifest")
98 | case ImplicitMethodType(resultType, paramSymbols) => error("todo - ImplicitMethodType manifest")
99 | case AnnotatedType(typeRef, attribTreeRefs) => error("todo - AnnotatedType manifest")
100 | case AnnotatedWithSelfType(typeRef, symbol, attribTreeRefs) => error("todo - AnnotatedWithSelfType manifest")
101 | case DeBruijnIndexType(typeLevel, typeIndex) => error("todo - DeBruijnIndexType manifest")
102 | case ExistentialType(typeRef, symbols) => error("todo - ExistentialType manifest")
103 | }
104 | }
105 |
106 | case class SingleTypeMirror(tpe: SingleType) extends TypeMirror with NamedMirror {
107 | // println("SingleTypeMirror for type " + tpe + " with symbol " + tpe.symbol + " of class " + tpe.symbol.getClass)
108 | val name = tpe.symbol.name
109 | val path = tpe.symbol.path
110 | override def toString = name
111 | def toManifest[T <: AnyRef]: Manifest[T] = {
112 | println("fetching Manifest for: " + path)
113 | Manifest.classType(Class.forName(path))
114 | }
115 | }
116 |
117 | case class TypeRefMirror(tpe: TypeRefType) extends TypeMirror with NamedMirror {
118 | val name = tpe.symbol.name
119 | val path = tpe.symbol.path
120 | override def toString = name
121 | def toManifest[T <: AnyRef]: Manifest[T] = {
122 | println("fetching Java type for: " + path)
123 | path match {
124 | case "scala.Nothing" => Manifest.Nothing.asInstanceOf[Manifest[T]]
125 | case "scala.Any" => Manifest.Any.asInstanceOf[Manifest[T]]
126 | case _ => Manifest.classType(Class.forName(path))
127 | }
128 | }
129 |
130 | }
131 |
132 | case class PolyTypeMirror(tpe: PolyType) extends TypeMirror {
133 | val typeRef = TypeMirror(tpe.typeRef)
134 | val rawSymbols = tpe.symbols
135 | val symbols = rawSymbols map { SymbolMirror(_) }
136 | override def toString = symbols.mkString("[", ", ", "]") + typeRef.toString
137 | def toManifest[T <: AnyRef]: Manifest[T] = {
138 | val symbolTypes = symbols collect {
139 | case sym: TypedSymbolMirror => sym.symType
140 | }
141 | if (symbolTypes.size < symbols.size) {
142 | println("untyped symbol in PolyType signature")
143 | }
144 |
145 | val symbolManifests = symbolTypes map {_.toManifest}
146 |
147 | val rawClass = tpe.typeRef match {
148 | case cit: ClassInfoType =>
149 | Class.forName(cit.symbol.path).asInstanceOf[Class[T]]
150 | case _ => error("can only extract a manifest from a PolyType wrapping a ClassInfoType, found " + tpe.typeRef)
151 | }
152 | Manifest.classType(rawClass, symbolManifests.head, symbolManifests.tail: _*)
153 | }
154 | }
155 |
156 | case class RefinedTypeMirror(underlying: TypeMirror, refinedTypes: List[Manifest]) extends TypeMirror {
157 | def tpe = underlying.tpe
158 | def toManifest[T <: AnyRef]: Manifest[T] =
159 | Manifest.classType(underlying.toManifest.erasure, refinedTypes.head, refinedTypes.tail)
160 |
161 | }
162 |
163 | ////////////////////////
164 | // SYMBOL MIRRORS
165 | //
166 |
167 | sealed trait MemberMirror extends NamedMirror { def isPrivate: Boolean }
168 |
169 | /**
170 | * A symbol is ANY atomic entity with a name, such as:
171 | * * T
172 | * * Int
173 | * * someProperty
174 | * * aMethod
175 | * * MyClass
176 | * * ...
177 | */
178 | object SymbolMirror {
179 | def apply(sym: Symbol): NamedMirror = sym match {
180 | case m: MethodSymbol => MethodMirror(m)
181 | case t: TypeSymbol => TypeSymbolMirror(t)
182 | case x => RawSymbolMirror(x)
183 | }
184 | }
185 |
186 | sealed trait SymbolMirror extends NamedMirror {
187 | def sym: Symbol
188 | def name = sym.name
189 | override def toString = "<>"
190 | }
191 |
192 | sealed trait TypedSymbolMirror extends SymbolMirror {
193 | def sym: SymbolInfoSymbol
194 | def symType = TypeMirror(sym.infoType)
195 | def manifest[T <: AnyRef] = symType.toManifest[T]
196 | def typeParams: Seq[Manifest[_]] = manifest.typeArguments
197 | }
198 |
199 | sealed trait Reifiable[Repr <: Reifiable[_]] {
200 | self: TypedSymbolMirror =>
201 | def reify(reifiedParams: Manifest[_]*) : Repr
202 | }
203 |
204 | case class RawSymbolMirror(sym: Symbol) extends SymbolMirror
205 |
206 | case class TypeSymbolMirror(sym: TypeSymbol) extends TypedSymbolMirror {
207 | override def toString = name
208 | }
209 |
210 | /**
211 | * Anything that can hold *publicly visible* members.
212 | * "members" being classes, defs, vals, etc.
213 | */
214 | abstract class MemberContainerMirror extends SymbolMirror {
215 | def memberSymbols: Seq[Symbol]
216 |
217 | lazy val typeAliases = memberSymbols collect { case als: AliasSymbol => RawSymbolMirror(als) }
218 |
219 | lazy val allMethodSymbols = memberSymbols collect { case ms @ MethodSymbol(_,_) => ms }
220 | lazy val reallyTrulyAllMethods = allMethodSymbols map { MethodMirror(_) }
221 | lazy val allNaturalMethods = reallyTrulyAllMethods filterNot { m => m.isSynthetic || m.isLocal }
222 | lazy val allSyntheticMethods = reallyTrulyAllMethods filter { m => m.isSynthetic || m.isLocal }
223 |
224 | lazy val allDefs = allNaturalMethods filterNot { m => m.isAccessor || m.isConstructor }
225 | lazy val publicDefs = allDefs filterNot { _.isPrivate }
226 | lazy val privateDefs = allDefs filter { _.isPrivate }
227 |
228 | lazy val allAccessors = allNaturalMethods filter { _.isAccessor } collect {
229 | case m if !(m.name endsWith "_$eq") =>
230 | val setter = allNaturalMethods find (_.name == m.name + "_$eq")
231 | setter map {VarMirror(m,_)} getOrElse ValMirror(m)
232 | }
233 |
234 | lazy val publicAccessors = allAccessors filterNot (_.isPrivate)
235 |
236 | lazy val vals = allAccessors collect {case v: ValMirror => v}
237 | lazy val vars = allAccessors collect {case v: VarMirror => v}
238 |
239 | //lazy val publicMembers: Seq[NamedMirror] =
240 | }
241 |
242 | case class ClassMirror(sym: ClassSymbol) extends MemberContainerMirror with TypedSymbolMirror with Reifiable[ClassMirror] {
243 | val memberSymbols = sym.children
244 |
245 | val parent = sym.parent
246 | val qualifiedName = (parent map {_.path + "."} getOrElse "") + sym.name
247 | lazy val javaClass = Class.forName(qualifiedName)
248 |
249 | def reify(reifiedParams: Manifest[_]*) : ClassMirror = error("not impl")
250 |
251 | lazy val constructors = allNaturalMethods filter {_.isConstructor} map {ConstructorMirror(this,_)}
252 |
253 | override def toString = "class " + name
254 | //def methods: Seq[MethodMirror] =
255 | }
256 |
257 | case class ObjectMirror(sym: ObjectSymbol) extends MemberContainerMirror {
258 | val TypeRefType(prefix, classSymbol: ClassSymbol, typeArgs) = sym.infoType
259 | val memberSymbols = classSymbol.children
260 | override def toString = "object " + name
261 | }
262 |
263 | /**
264 | * Anything that takes parameters: Constructors, Setters and Methods
265 | */
266 | case class MethodMirror(val sym: MethodSymbol) extends SymbolMirror with MemberMirror {
267 | val isSynthetic = sym.isSynthetic
268 | val isAccessor = sym.isAccessor
269 | val isLocal = sym.isLocal
270 | val isPrivate = sym.isPrivate
271 | val isConstructor = name == NameHelpers.CONSTRUCTOR_NAME
272 |
273 | val rawType = sym.infoType
274 | val (refType, typeParamSymbols) = rawType match {
275 | case PolyType(refType, typeParamSymbols) => (refType, typeParamSymbols)
276 | case x => (x, Seq.empty[TypeSymbol])
277 | }
278 |
279 | val typeParams = typeParamSymbols map TypeSymbolMirror.apply
280 |
281 | private[this] val returnChain = Iterator.iterate(Some(refType): Option[SymType]){
282 | case Some(MethodType(rt, _)) => Some(rt)
283 | case Some(ImplicitMethodType(rt, _)) => Some(rt)
284 | case _ => None
285 | } takeWhile (None !=) map (_.get) map {
286 | case mt: MethodType => ExplicitParamBlockMirror(mt)
287 | case imt: ImplicitMethodType => ImplicitParamBlockMirror(imt)
288 | case x => TypeMirror(x)
289 | } toList
290 |
291 | val paramBlocks = returnChain collect { case pbm: ParamBlockMirror => pbm }
292 | val returnType = returnChain.last
293 |
294 | def flatParams = paramBlocks flatMap (_.params)
295 |
296 | override def toString = {
297 | val prefix = (
298 | Some("SYN").filter(_ => isSynthetic) ::
299 | Some("ACC").filter(_ => isAccessor) ::
300 | Some("CTOR").filter(_ => isConstructor) ::
301 | Some("LCL").filter(_ => isLocal) ::
302 | Nil).flatten mkString " "
303 |
304 | val typeParamsStr = if (typeParams.isEmpty) "" else typeParams.mkString("[",", ","]")
305 | val paramBlocksStr = paramBlocks mkString ""
306 | prefix + "method " + name + typeParamsStr + paramBlocks.mkString("") + ": " + returnType.toString
307 | }
308 | // TODO: def invoke(args: Object*)
309 | }
310 |
311 | //TODO: DefMirror?, ConstructorMirror?
312 | /**
313 | * A val or a var, also (potentially) bean properties
314 | */
315 |
316 | sealed trait PropertyMirror extends MemberMirror {
317 | def isGettable: Boolean
318 | def isSettable: Boolean
319 | }
320 |
321 | case class ValMirror(getter: MethodMirror) extends PropertyMirror {
322 | val name = getter.name
323 | def isPrivate = getter.isPrivate
324 | val isGettable = true
325 | val isSettable = false
326 | }
327 |
328 | case class VarMirror(getter: MethodMirror, setter: MethodMirror) extends PropertyMirror {
329 | val name = getter.name
330 | def isPrivate = getter.isPrivate
331 | val isGettable = true
332 | val isSettable = true
333 | }
334 |
335 | case class ConstructorMirror(clazz: ClassMirror, method: MethodMirror) extends MemberMirror {
336 | def isPrivate = method.isPrivate
337 | def name = "this"
338 | method.flatParams map (_.name)
339 | //def toJavaConstructor = clazz.javaClass.getConstructor()
340 | }
341 |
342 | abstract class ParamBlockMirror(paramSymbols: Seq[Symbol]) extends Mirror {
343 | val params = paramSymbols map {
344 | case ms: MethodSymbol => ParamMirror(ms)
345 | case x => error("Don't know what to do with a param that isn't a MethodSymbol!")
346 | }
347 | }
348 |
349 | case class ExplicitParamBlockMirror(val tpe: MethodType) extends ParamBlockMirror(tpe.paramSymbols) {
350 | override def toString = params.mkString("(", ", ", ")")
351 | }
352 | case class ImplicitParamBlockMirror(val tpe: ImplicitMethodType) extends ParamBlockMirror(tpe.paramSymbols) {
353 | override def toString = params.mkString("(implicit ", ", ", ")")
354 | }
355 |
356 | case class ParamMirror(sym: MethodSymbol) extends TypedSymbolMirror {
357 | override def toString = name + ": " + symType.toString
358 | }
359 |
360 |
361 |
362 |
363 | /**
364 | * Anything that takes a type. Some classes, methods and aliases
365 | */
366 | trait TypeParamaterizedMirror extends Mirror {
367 | def typeParams: Seq[Object]
368 | }
369 |
370 |
371 |
372 |
373 | /**
374 | * Anything that has a constructor.
375 | * Basically just classes at the moment.
376 | * (maybe traits in the future, who knows?)
377 | */
378 | //trait ConstructableMirror extends Mirror {
379 | // def primaryConstructor: MethodMirror
380 | // def secondaryConstructors: Seq[MethodMirror]
381 | // def allConstructors = primaryConstructor +: secondaryConstructors
382 | //}
383 |
384 |
385 |
386 |
387 |
388 |
--------------------------------------------------------------------------------
/src/main/scala/scalaj/reflect/NameHelpers.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | import java.util.regex.Pattern
4 | import tools.scalap.scalax.rules.scalasig._
5 |
6 | object NameHelpers {
7 | val CONSTRUCTOR_NAME = ""
8 |
9 | val _syms = Map(
10 | "\\$bar" -> "|",
11 | "\\$tilde" -> "~",
12 | "\\$bang" -> "!",
13 | "\\$up" -> "^",
14 | "\\$plus" -> "+",
15 | "\\$minus" -> "-",
16 | "\\$eq" -> "=",
17 | "\\$less" -> "<",
18 | "\\$times" -> "*",
19 | "\\$div" -> "/",
20 | "\\$bslash" -> "\\\\",
21 | "\\$greater" -> ">",
22 | "\\$qmark" -> "?",
23 | "\\$percent" -> "%",
24 | "\\$amp" -> "&",
25 | "\\$colon" -> ":",
26 | "\\$u2192" -> "?",
27 | "\\$hash" -> "#")
28 | val pattern = Pattern.compile(_syms.keys.mkString("", "|", ""))
29 | val placeholderPattern = "_\\$(\\d)+"
30 |
31 | private def stripPrivatePrefix(name: String) = {
32 | val i = name.lastIndexOf("$$")
33 | if (i > 0) name.substring(i + 2) else name
34 | }
35 |
36 | def processName(name: String) = {
37 | val stripped = stripPrivatePrefix(name)
38 | val m = pattern.matcher(stripped)
39 | var temp = stripped
40 | while (m.find) {
41 | val key = m.group
42 | val re = "\\" + key
43 | temp = temp.replaceAll(re, _syms(re))
44 | }
45 | val result = temp.replaceAll(placeholderPattern, "_")
46 | scala.reflect.NameTransformer.decode(result)
47 | }
48 |
49 | def isRefinementClass(c: ClassSymbol) = c.name == ""
50 |
51 | def isConstructor(c: Symbol) =
52 | c.isInstanceOf[MethodSymbol] && c.name == ""
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/scala/scalaj/reflect/SymbolTreePrinter.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 | import tools.scalap.scalax.rules.scalasig.{Type => SymType, _}
3 |
4 | object SymbolTreePrinter extends SymbolTreePrinter {
5 | def withoutOwners = new SymbolTreePrinter {
6 | override def mkTree[T](input: T) = (new Run).mkTree(input)(Context(false, true))
7 | }
8 | }
9 |
10 | class SymbolTreePrinter {
11 | def quote(s: String) = "\"" + s + "\""
12 |
13 | def mkTree[T](input: T) =
14 | (new Run).mkTree(input)
15 |
16 | case class Context(skipChildren: Boolean = false, skipOwner: Boolean = false) {
17 | def withoutChildren: Context = this.copy(skipChildren=true)
18 | def withoutOwner: Context = this.copy(skipOwner=true)
19 | }
20 |
21 | class Run {
22 | var symbolsSeen: Set[Symbol] = Set.empty
23 | var typesSeen: Set[SymType] = Set.empty
24 |
25 | def mkTree[T](input: T)(implicit ctx: Context = new Context): String = input match {
26 | case sm: SymbolMirror => mkTree(sm.sym)
27 | case sym: Symbol => symbolsSeen += sym; mkSymbolTree(sym)
28 | case tpe: SymType => typesSeen += tpe; mkTypeTree(tpe)
29 | case i: Int => i.toString
30 | case s: String => s
31 | case e: ScalaSig#Entry => e.toString
32 | case _ => "oops @ " + input.toString + ": " + input.asInstanceOf[AnyRef].getClass
33 | }
34 |
35 | private def optNest[T](input: (String, Option[T]))(implicit ctx: Context = new Context) = input match {
36 | case (name, Some(value)) => nest(name->value)
37 | case _ => ""
38 | }
39 |
40 | private def nestAll[T](input: (String, Seq[T]))(implicit ctx: Context = new Context) = input match {
41 | case (name, values) => values.zipWithIndex map { case (v,i) =>
42 | val indexedName = "%s %d/%d".format(name, i+1, values.size)
43 | nest(indexedName->v)
44 | } mkString ""
45 | }
46 |
47 | private def nest[T](input: (String, T))(implicit ctx: Context = new Context) = {
48 | val (name, x) = input
49 | val nested = x match {
50 | case s: ScalaSigSymbol if symbolsSeen contains s => s.path + " (already seen at #" + s.entry.index + ")"
51 | case s: Symbol if symbolsSeen contains s => s.path + " (already seen)"
52 | case t: SymType if typesSeen contains t => typeName(t) + "(type already seen)"
53 | case null => ""
54 | case _ => mkTree(x)
55 | }
56 | (name + " = " + nested).lines map {"| " + _} mkString("\n","\n","")
57 | }
58 |
59 | def mkTypeTree(tpe: SymType)(implicit ctx: Context = new Context): String = tpe match {
60 | case NoType => "NoType"
61 | case NoPrefixType => "NoPrefixType"
62 | case ThisType(symbol) =>
63 | "ThisType" +
64 | nest("symbol"->symbol)
65 | case SingleType(typeRef, symbol) =>
66 | "SingleType" +
67 | nest("typeRef"->typeRef) +
68 | nest("symbol"->symbol)
69 | case ConstantType(constant) =>
70 | "ConstantType" +
71 | nest("constant"->constant)
72 | case TypeRefType(prefix, symbol, typeArgs) =>
73 | "TypeRefType" +
74 | nest("prefix"->prefix) +
75 | nest("symbol"->symbol) +
76 | nestAll("typeArg"->typeArgs)
77 | case TypeBoundsType(lower, upper) =>
78 | "TypeBoundsType" +
79 | nest("lower"->lower) +
80 | nest("upper"->upper)
81 | case RefinedType(classSym, typeRefs) =>
82 | "RefinedType" +
83 | nest("classSym"->classSym) +
84 | nest("typeRefs"->typeRefs)
85 | case ClassInfoType(symbol, typeRefs) =>
86 | "ClassInfoType" +
87 | nest("symbol"->symbol) +
88 | nestAll("typeRef"->typeRefs)
89 | case ClassInfoTypeWithCons(symbol, typeRefs, cons) =>
90 | "ClassInfoTypeWithCons" +
91 | nest("symbol"->symbol) +
92 | nestAll("typeRef"->typeRefs) +
93 | nest("cons"->cons)
94 | case MethodType(resultType, paramSymbols) =>
95 | "MethodType" +
96 | nest("resultType"->resultType) +
97 | nestAll("paramSymbol"->paramSymbols)
98 | case PolyType(typeRef, symbols) =>
99 | "PolyType" +
100 | nest("typeRef"->typeRef) +
101 | nestAll("symbol"->symbols)
102 | case PolyTypeWithCons(typeRef, symbols, cons) =>
103 | "PolyTypeWithCons" +
104 | nest("typeRef"->typeRef) +
105 | nestAll("symbol"->symbols) +
106 | nest("cons"->cons)
107 | case ImplicitMethodType(resultType, paramSymbols) =>
108 | "ImplicitMethodType" +
109 | nest("resultType"->resultType) +
110 | nestAll("paramSymbol"->paramSymbols)
111 | case AnnotatedType(typeRef, attribTreeRefs) =>
112 | "AnnotatedType" +
113 | nest("typeRef"->typeRef) +
114 | nestAll("attribTreeRef"->attribTreeRefs)
115 | case AnnotatedWithSelfType(typeRef, symbol, attribTreeRefs) =>
116 | "AnnotatedWithSelfType" +
117 | nest("typeRef"->typeRef) +
118 | nest("symbol"->symbol) +
119 | nestAll("attribTreeRef"->attribTreeRefs)
120 | case DeBruijnIndexType(typeLevel, typeIndex) =>
121 | "DeBruijnIndexType" +
122 | nest("typeLevel"->typeLevel) +
123 | nest("typeIndex"->typeIndex)
124 | case ExistentialType(typeRef, symbols) =>
125 | "ExistentialType" +
126 | nest("typeRef"->typeRef) +
127 | nestAll("symbol"->symbols)
128 | }
129 |
130 | def mkSymbolTree(sym: Symbol)(implicit ctx: Context = new Context): String = sym match {
131 | case NoSymbol => "NoSymbol"
132 | case ExternalSymbol(name, parent, entry) =>
133 | quote(sym.path) +
134 | " (external #" + entry.index + " type = " + entryTypeName(entry.entryType) + ")" +
135 | optNest("parent"->parent)(ctx.withoutChildren)
136 | //(if(!ctx.skipChildren) nestAll("child"->sym.children) else "")
137 |
138 | case sym @ TypeSymbol(_) => "TypeSymbol" + addSymbolInfo(sym)
139 | case sym @ AliasSymbol(_) => "AliasSymbol" + addSymbolInfo(sym)
140 | case sym @ ClassSymbol(_, thisTypeRef) => "ClassSymbol" + addSymbolInfo(sym) +
141 | optNest("thisTypeRef"->thisTypeRef)
142 | case sym @ ObjectSymbol(_) => "ObjectSymbol" + addSymbolInfo(sym)
143 | case sym @ MethodSymbol(_, aliasRef) => "MethodSymbol" + addSymbolInfo(sym) +
144 | optNest("aliasRef"->aliasRef)
145 | }
146 |
147 | def addSymbolInfo(sym: SymbolInfoSymbol)(implicit ctx: Context = new Context): String = {
148 | val SymbolInfo(name, owner, flags, privateWithin, info, entry) = sym.symbolInfo
149 | " name = " + quote(name) + " (entry #" + entry.index + ")" +
150 | nest("path"->quote(sym.path)) +
151 | { if (ctx.skipOwner) "" else nest("owner"->owner)(ctx.withoutChildren) } +
152 | nest("flags/info"->(flags.toString + " / " + info.toString)) +
153 | optNest("privateWithin"->privateWithin) +
154 | nest("infoType"->sym.infoType) +
155 | nestAll("child"->sym.children)
156 | }
157 | }
158 |
159 | def typeName(tpe: SymType): String = tpe match {
160 | case NoType => "NoType"
161 | case NoPrefixType => "NoPrefixType"
162 | case ThisType(symbol) => symbol.path
163 | case SingleType(_, symbol) => symbol.path
164 | case ConstantType(constant) => constant.toString
165 | case TypeRefType(prefix, symbol, typeArgs) => symbol.path
166 | case TypeBoundsType(lower, upper) => typeName(lower) + " <: " + typeName(upper)
167 | case RefinedType(classSym, typeRefs) => classSym.path
168 | case ClassInfoType(symbol, typeRefs) => symbol.path
169 | case ClassInfoTypeWithCons(symbol, typeRefs, cons) => symbol.path
170 | case MethodType(resultType, paramSymbols) => "MethodType"
171 | case PolyType(typeRef, symbols) => "PolyType"
172 | case PolyTypeWithCons(typeRef, symbols, cons) => "PolyTypeWithCons"
173 | case ImplicitMethodType(resultType, paramSymbols) => "ImplicitMethodType"
174 | case AnnotatedType(typeRef, attribTreeRefs) => "AnnotatedType"
175 | case AnnotatedWithSelfType(typeRef, symbol, attribTreeRefs) => symbol.path
176 | case DeBruijnIndexType(typeLevel, typeIndex) => "DeBruijnIndexType"
177 | case ExistentialType(typeRef, symbols) => "ExistentialType"
178 | }
179 |
180 | val entryTypeName = Map(
181 | 1->"TERMNAME",
182 | 2->"TYPENAME",
183 | 3->"NONEsym",
184 | 4->"TYPEsym",
185 | 5->"ALIASsym",
186 | 6->"CLASSsym",
187 | 7->"MODULEsym",
188 | 8->"VALsym",
189 | 9->"EXTref",
190 | 10->"EXTMODCLASSref",
191 | 11->"NOtpe",
192 | 12->"NOPREFIXtpe",
193 | 13->"THIStpe",
194 | 14->"SINGLEtpe",
195 | 15->"CONSTANTtpe",
196 | 16->"TYPEREFtpe",
197 | 17->"TYPEBOUNDStpe",
198 | 18->"REFINEDtpe",
199 | 19->"CLASSINFOtpe",
200 | 20->"METHODtpe",
201 | 21->"POLYTtpe",
202 | 22->"IMPLICITMETHODtpe",
203 | 52->"SUPERtpe",
204 | 24->"LITERALunit",
205 | 25->"LITERALboolean",
206 | 26->"LITERALbyte",
207 | 27->"LITERALshort",
208 | 28->"LITERALchar",
209 | 29->"LITERALint",
210 | 30->"LITERALlong",
211 | 31->"LITERALfloat",
212 | 32->"LITERALdouble",
213 | 33->"LITERALstring",
214 | 34->"LITERALnull",
215 | 35->"LITERALclass",
216 | 36->"LITERALenum",
217 | 40->"SYMANNOT",
218 | 41->"CHILDREN",
219 | 42->"ANNOTATEDtpe",
220 | 43->"ANNOTINFO",
221 | 44->"ANNOTARGARRAY",
222 | 47->"DEBRUIJNINDEXtpe",
223 | 48->"EXISTENTIALtpe") map {case (a,b) => a -> "%s[%s]".format(b,a)}
224 |
225 | }
226 |
--------------------------------------------------------------------------------
/src/main/scala/scalaj/reflect/TypeMirrors.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | import tools.scalap.scalax.rules.scalasig.{Type => SymType, _}
4 | import tools.scalap.scalax.util.StringUtil
5 |
6 | //object TypeMirror {
7 | // def of(symType: SymType): TypeMirror = symType match {
8 | // case trt: TypeRefType => RefTypeMirror(trt)
9 | // case pt: PolyType => PolyTypeMirror(pt)
10 | // case mt: MethodType => MethodTypeMirror(mt)
11 | // case mt: ImplicitMethodType => MethodTypeMirror(mt)
12 | // case x => UnknownTypeMirror(x)
13 | // }
14 | //}
15 |
16 | //sealed abstract trait TypeMirror {
17 | // val symType: SymType
18 | //}
19 | //
20 | //case class PolyTypeMirror(symType: PolyType) extends TypeMirror {
21 | // val innerSymMirror = TypeMirror.of(symType.typeRef)
22 | // val typeSymbols = symType.symbols map Mirror.of
23 | // def typesStr = typeSymbols map {_.toString} mkString ","
24 | // override def toString = "" + innerSymMirror.toString
25 | //}
26 | //
27 | //case class SimpleTypeMirror(symType: SymType) extends TypeMirror {
28 | // import NameHelpers._
29 | //
30 | // def innerToString(t: SymType, sep: String) = symType match {
31 | // case ThisType(symbol) => sep + processName(symbol.path) + ".type"
32 | // case SingleType(typeRef, symbol) => sep + processName(symbol.path) + ".type"
33 | // case ConstantType(constant) => sep + (constant match {
34 | // case null => "Null"
35 | // case _: Unit => "Unit"
36 | // case _: Boolean => "Boolean"
37 | // case _: Byte => "Byte"
38 | // case _: Char => "Char"
39 | // case _: Short => "Short"
40 | // case _: Int => "Int"
41 | // case _: Long => "Long"
42 | // case _: Float => "Float"
43 | // case _: Double => "Double"
44 | // case _: String => "String"
45 | // case c: Class[_] => "Class[" + c.getComponentType.getCanonicalName.replace("$", ".") + "]"
46 | // })
47 | //// case TypeRefType(prefix, symbol, typeArgs) => sep + (symbol.path match {
48 | //// case "scala." => flags match {
49 | //// case TypeFlags(true) => toString(typeArgs.head) + "*"
50 | //// case _ => "scala.Seq" + typeArgString(typeArgs)
51 | //// }
52 | //// case "scala." => "=> " + toString(typeArgs.head)
53 | //// case _ => {
54 | //// val path = StringUtil.cutSubstring(symbol.path)(".package") //remove package object reference
55 | //// StringUtil.trimStart(processName(path) + typeArgString(typeArgs), ".")
56 | //// }
57 | //// })
58 | //// case TypeBoundsType(lower, upper) => {
59 | //// val lb = toString(lower)
60 | //// val ub = toString(upper)
61 | //// val lbs = if (!lb.equals("scala.Nothing")) " >: " + lb else ""
62 | //// val ubs = if (!ub.equals("scala.Any")) " <: " + ub else ""
63 | //// lbs + ubs
64 | //// }
65 | //// case RefinedType(classSym, typeRefs) => sep + typeRefs.map(toString).mkString("", " with ", "")
66 | //// case ClassInfoType(symbol, typeRefs) => sep + typeRefs.map(toString).mkString(" extends ", " with ", "")
67 | //// case ClassInfoTypeWithCons(symbol, typeRefs, cons) => sep + typeRefs.map(toString).
68 | //// mkString(cons + " extends ", " with ", "")
69 | ////
70 | //// case ImplicitMethodType(resultType, _) => toString(resultType, sep)
71 | //// case MethodType(resultType, _) => toString(resultType, sep)
72 | ////
73 | //// case PolyType(typeRef, symbols) => typeParamString(symbols) + toString(typeRef, sep)
74 | //// case PolyTypeWithCons(typeRef, symbols, cons) => typeParamString(symbols) + processName(cons) + toString(typeRef, sep)
75 | //// case AnnotatedType(typeRef, attribTreeRefs) => {
76 | //// toString(typeRef, sep)
77 | //// }
78 | //// case AnnotatedWithSelfType(typeRef, symbol, attribTreeRefs) => toString(typeRef, sep)
79 | //// //case DeBruijnIndexType(typeLevel, typeIndex) =>
80 | //// case ExistentialType(typeRef, symbols) => {
81 | //// val refs = symbols.map(toString _).filter(!_.startsWith("_")).map("type " + _)
82 | //// toString(typeRef, sep) + (if (refs.size > 0) refs.mkString(" forSome {", "; ", "}") else "")
83 | //// }
84 | // case _ => sep + "" + t.toString
85 | // }
86 | //
87 | // override def toString = innerToString(symType, "")
88 | //}
89 | //
90 | //case class RefTypeMirror(symType: TypeRefType) extends TypeMirror {
91 | // val targetSymbol = Mirror.of(symType.symbol)
92 | // override def toString = "" + targetSymbol.toString
93 | //}
94 | //
95 | //case class UnknownTypeMirror(symType: SymType) extends TypeMirror {
96 | // override def toString = "" + symType.toString
97 | //}
98 | //
99 | //case class MethodTypeMirror(symType: SymType) extends TypeMirror {
100 | //
101 | // val typeParams: Seq[TypeParamMirror] = symType match {
102 | // //multiple param blocks
103 | // case pt@PolyType(mt, typeParams) => typeParams map { TypeParamMirror.apply }
104 | // case _ => Seq.empty
105 | // }
106 | //
107 | // val isImplicit = symType.isInstanceOf[ImplicitMethodType]
108 | //
109 | // val resultType: TypeMirror = symType match {
110 | // case MethodType(rt, _) => MethodTypeMirror(rt)
111 | // case ImplicitMethodType(rt, _) => MethodTypeMirror(rt)
112 | // case rt @ TypeRefType(_, _, _) => RefTypeMirror(rt)
113 | // case x => SimpleTypeMirror(x)
114 | // }
115 | //
116 | // def paramToMirror(param: Symbol) = param match {
117 | // case ms: MethodSymbol => ParamMirror(ms)
118 | // case _ => UnknownMirror(param)
119 | // }
120 | //
121 | // val paramSymbols = symType match {
122 | // case MethodType(_, ps) => ps map {paramToMirror}
123 | // case ImplicitMethodType(_, ps) => ps map {paramToMirror}
124 | // case x => Seq.empty
125 | // }
126 | //
127 | // def resultToString = resultType match {
128 | // case MethodTypeMirror(_) => resultType.toString
129 | // case _ => ": " + resultType.toString
130 | // }
131 | //
132 | // override def toString = {
133 | // "" + (if (paramSymbols.isEmpty) {
134 | // ""
135 | // } else {
136 | // paramSymbols.map{_.toString}.mkString(
137 | // if(isImplicit) "(implicit " else "(",
138 | // ",",
139 | // ")"
140 | // )
141 | // }) + resultToString
142 | // }
143 | //}
144 | //
145 | //trait ParamBlockTypeMirror {
146 | // def resultType: SymType
147 | // def paramSymbols: Seq[Symbol]
148 | //
149 | // def params: Seq[ParamMirror] = paramSymbols map {
150 | // case ms: MethodSymbol => ParamMirror(ms)
151 | // case ps => error(ps.toString)
152 | // }
153 | //}
154 | //
155 | //case class SimpleParamBlockTypeMirror(symType: MethodType) extends ParamBlockTypeMirror {
156 | // val resultType = symType.resultType
157 | // val paramSymbols = symType.paramSymbols
158 | //}
159 | //
160 | //case class ImplicitParamBlockTypeMirror(symType: ImplicitMethodType) extends ParamBlockTypeMirror {
161 | // val resultType = symType.resultType
162 | // val paramSymbols = symType.paramSymbols
163 | //}
164 |
--------------------------------------------------------------------------------
/src/main/scala/scalaj/reflect/TypeWrangler.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | import java.{lang => jl}
4 | import java.lang.reflect.{ Type => JType, Array => _, _ }
5 | import scala.reflect.Manifest
6 | import scala.reflect.Manifest.{ classType, intersectionType, arrayType, wildcardType }
7 |
8 |
9 | /**
10 | * Negotiates between Spring's TypeDescriptor and Scala's Manifest mechanisms
11 | */
12 |
13 | object TypeWrangler {
14 |
15 | val ByteClass = classOf[scala.Byte]
16 | val ShortClass = classOf[scala.Short]
17 | val CharClass = classOf[scala.Char]
18 | val IntClass = classOf[scala.Int]
19 | val LongClass = classOf[scala.Long]
20 | val FloatClass = classOf[scala.Float]
21 | val DoubleClass = classOf[scala.Double]
22 | val BooleanClass = classOf[scala.Boolean]
23 | val NullClass = classOf[scala.Null]
24 | val UnitClass = classOf[scala.Unit]
25 |
26 | val JByteClass = classOf[jl.Byte]
27 | val JShortClass = classOf[jl.Short]
28 | val JCharClass = classOf[jl.Character]
29 | val JIntClass = classOf[jl.Integer]
30 | val JLongClass = classOf[jl.Long]
31 | val JFloatClass = classOf[jl.Float]
32 | val JDoubleClass = classOf[jl.Double]
33 | val JBooleanClass = classOf[jl.Boolean]
34 |
35 |
36 | // Manifest.classType(x) will return a Manifest
37 | def manifestOf(c : Class[_]) = c match {
38 | case JByteClass | jl.Byte.TYPE | ByteClass => Manifest.Byte
39 | case JShortClass | jl.Short.TYPE | ShortClass => Manifest.Short
40 | case JCharClass | jl.Character.TYPE | CharClass => Manifest.Char
41 | case JIntClass | jl.Integer.TYPE | IntClass => Manifest.Int
42 | case JLongClass | jl.Long.TYPE | LongClass => Manifest.Long
43 | case JFloatClass | jl.Float.TYPE | FloatClass => Manifest.Float
44 | case JDoubleClass | jl.Double.TYPE | DoubleClass => Manifest.Double
45 | case JBooleanClass | jl.Boolean.TYPE | BooleanClass => Manifest.Boolean
46 | case jl.Void.TYPE | UnitClass => Manifest.Unit
47 | case null | NullClass => Manifest.Null
48 | case x => classType(x)
49 | }
50 |
51 | def intersect(tps: JType*): Manifest[_] = intersectionType(tps map javaType: _*)
52 |
53 | def javaType(tp: JType): Manifest[_] = tp match {
54 | case null => Manifest.Null
55 | case x: Class[_] => manifestOf(x)
56 | case x: ParameterizedType =>
57 | val owner = x.getOwnerType
58 | val raw = x.getRawType() match { case clazz: Class[_] => clazz }
59 | val targs = x.getActualTypeArguments() map javaType
60 |
61 | (owner == null, targs.isEmpty) match {
62 | case (true, true) => javaType(raw)
63 | case (true, false) => classType(raw, targs.head, targs.tail: _*)
64 | case (false, _) => classType(javaType(owner), raw, targs: _*)
65 | }
66 | case x: GenericArrayType => arrayType(javaType(x.getGenericComponentType))
67 | case x: WildcardType => wildcardType(intersect(x.getLowerBounds: _*), intersect(x.getUpperBounds: _*))
68 | case x: TypeVariable[_] => intersect(x.getBounds(): _*)
69 | }
70 |
71 |
72 | }
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/AutographBookSpec.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | //give the wrangler a short name, don't import methods as we want full control without using them as implicits
4 | import scalaj.reflect.{TypeWrangler => wrangler}
5 | import org.specs.SpecificationWithJUnit
6 |
7 | import AutographBook._
8 | import tools.scalap.scalax.rules.scalasig._
9 |
10 | class AutographBookSpec extends SpecificationWithJUnit {
11 |
12 |
13 | "the AutographBook" should {
14 | "correctly resolve the mirror of a class" in {
15 | val tpe = classOf[targets.BasicSample]
16 | val sig = sigFromType(tpe)
17 |
18 | // val decompiledText = sig map decompile getOrElse("couldn't decompile")
19 | // println(decompiledText)
20 | // println("=====")
21 |
22 | val syms = sig map (topLevelSymsFromSig) getOrElse Nil
23 |
24 | val mirrors = syms map (Mirror.ofSymbol)
25 | // mirrors collect { case mcm: MemberContainerMirror => mcm } foreach { mcm =>
26 | // println(mcm.toString)
27 | // mcm.allNaturalMethods map (_.toString) foreach {println}
28 | // mcm.allSyntheticMethods map (_.toString) foreach {println}
29 | // }
30 | val tgtMirror = (mirrors collect { case m: ClassMirror => m }).head
31 | tgtMirror.qualifiedName mustEqual "scalaj.reflect.targets.BasicSample"
32 |
33 | }
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/CollatableSpec.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | import org.specs.SpecificationWithJUnit
4 | import Collatable._
5 |
6 | class CollatableSpec extends SpecificationWithJUnit {
7 | "Collatable" should {
8 | "collate a List[Int]" in {
9 | val ints = List(0,9,4,5,-3,-5,6,5,-2,1,0,6,-3,-2)
10 | val results = ints collate {
11 | case i: Int if(i < 0) => i.floatValue
12 | } andThen {
13 | case i: Int if(i > 5) => i.toString
14 | } andThen {
15 | case i: Int if(i == 0) => i
16 | } toTuple
17 | val expected = (List(-3.0, -5.0, -2.0, -3.0, -2.0), List("9", "6", "6"), List(0, 0), List(4, 5, 5, 1))
18 | results mustEqual expected
19 | }
20 |
21 | "collate a String" in {
22 | val input = "129sdS DDFJ37$%$w__9 7sSF:::#\t tWE"
23 | val results = input collate {
24 | case c: Char if(c.isDigit) => c
25 | } andThen {
26 | case c: Char if(c.isUpper) => c
27 | } andThen {
28 | case c: Char if(c.isLower) => c
29 | } andThen {
30 | case c: Char if(c.isWhitespace) => c
31 | } toTuple
32 | val expected = ("1293797","SDDFJSFWE","sdwst"," \t ","$%$__:::#")
33 | results mustEqual expected
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/ExpectedPrintTrees.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 | object ExpectedPrintTrees {
3 | val simpleVarGetter =
4 | """>MethodSymbol name = "simpleVar" (entry #74)
5 | >| path = "scalaj.reflect.targets.BasicSample.simpleVar"
6 | >| flags/info = 134218240 / 76
7 | >| infoType = PolyType
8 | >| | typeRef = TypeRefType
9 | >| | | prefix = ThisType
10 | >| | | | symbol = "scala" (external #20 type = EXTMODCLASSref[10])
11 | >| | | symbol = "scala.Int" (external #36 type = EXTref[9])
12 | >| | | | parent = scala (already seen at #20)""".stripMargin('>')
13 |
14 | val simpleVarSetter =
15 | """>MethodSymbol name = "simpleVar_$eq" (entry #77)
16 | >| path = "scalaj.reflect.targets.BasicSample.simpleVar_$eq"
17 | >| flags/info = 134218240 / 79
18 | >| infoType = MethodType
19 | >| | resultType = TypeRefType
20 | >| | | prefix = ThisType
21 | >| | | | symbol = "scala" (external #20 type = EXTMODCLASSref[10])
22 | >| | | symbol = "scala.Unit" (external #81 type = EXTref[9])
23 | >| | | | parent = scala (already seen at #20)
24 | >| | paramSymbol 1/1 = MethodSymbol name = "x$1" (entry #83)
25 | >| | | path = "scalaj.reflect.targets.BasicSample.simpleVar_$eq.x$1"
26 | >| | | flags/info = 2105344 / 35
27 | >| | | infoType = TypeRefType
28 | >| | | | prefix = scala(type already seen)
29 | >| | | | symbol = "scala.Int" (external #36 type = EXTref[9])
30 | >| | | | | parent = scala (already seen at #20)
31 | >| child 1/1 = scalaj.reflect.targets.BasicSample.simpleVar_$eq.x$1 (already seen at #83)""".stripMargin('>')
32 |
33 | val simpleMethodArg =
34 | """>MethodSymbol name = "arg" (entry #90)
35 | >| path = "scalaj.reflect.targets.BasicSample.simpleMethod.arg"
36 | >| flags/info = 8192 / 26
37 | >| infoType = TypeRefType
38 | >| | prefix = SingleType
39 | >| | | typeRef = ThisType
40 | >| | | | symbol = "scala" (external #20 type = EXTMODCLASSref[10])
41 | >| | | symbol = "scala.Predef" (external #28 type = EXTref[9])
42 | >| | | | parent = scala (already seen at #20)
43 | >| | symbol = "scala.Predef.String" (external #30 type = EXTref[9])
44 | >| | | parent = "scala.Predef" (external #32 type = EXTMODCLASSref[10])
45 | >| | | | parent = scala (already seen at #20)""".stripMargin('>')
46 |
47 | val genericMethodArg =
48 | """>MethodSymbol name = "arg" (entry #117)
49 | >| path = "scalaj.reflect.targets.BasicSample.genericMethod.arg"
50 | >| flags/info = 8192 / 118
51 | >| infoType = TypeRefType
52 | >| | prefix = NoPrefixType
53 | >| | symbol = TypeSymbol name = "T" (entry #120)
54 | >| | | path = "T"
55 | >| | | flags/info = 1073750272 / 122
56 | >| | | infoType = TypeBoundsType
57 | >| | | | lower = TypeRefType
58 | >| | | | | prefix = ThisType
59 | >| | | | | | symbol = "scala" (external #20 type = EXTMODCLASSref[10])
60 | >| | | | | symbol = "scala.Nothing" (external #124 type = EXTref[9])
61 | >| | | | | | parent = scala (already seen at #20)
62 | >| | | | upper = TypeRefType
63 | >| | | | | prefix = scala(type already seen)
64 | >| | | | | symbol = "scala.Any" (external #127 type = EXTref[9])
65 | >| | | | | | parent = scala (already seen at #20)""".stripMargin('>').replace("\\r","")
66 |
67 |
68 | val basicSampleClass =
69 | """>ClassSymbol name = "BasicSample" (entry #0)
70 | >| path = "scalaj.reflect.targets.BasicSample"
71 | >| owner = "scalaj.reflect.targets" (external #2 type = EXTMODCLASSref[10])
72 | >| | parent = "scalaj.reflect" (external #4 type = EXTMODCLASSref[10])
73 | >| | | parent = "scalaj" (external #6 type = EXTMODCLASSref[10])
74 | >| flags/info = 1073741824 / 9
75 | >| infoType = ClassInfoType
76 | >| | symbol = scalaj.reflect.targets.BasicSample (already seen at #0)
77 | >| | typeRef 1/2 = TypeRefType
78 | >| | | prefix = ThisType
79 | >| | | | symbol = "java.lang" (external #12 type = EXTMODCLASSref[10])
80 | >| | | | | parent = "java" (external #14 type = EXTMODCLASSref[10])
81 | >| | | symbol = "java.lang.Object" (external #16 type = EXTref[9])
82 | >| | | | parent = java.lang (already seen at #12)
83 | >| | typeRef 2/2 = TypeRefType
84 | >| | | prefix = ThisType
85 | >| | | | symbol = "scala" (external #20 type = EXTMODCLASSref[10])
86 | >| | | symbol = "scala.ScalaObject" (external #22 type = EXTref[9])
87 | >| | | | parent = scala (already seen at #20)
88 | >| child 1/19 = MethodSymbol name = "param1" (entry #24)
89 | >| | path = "scalaj.reflect.targets.BasicSample.param1"
90 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
91 | >| | flags/info = 537395204 / 26
92 | >| | infoType = TypeRefType
93 | >| | | prefix = SingleType
94 | >| | | | typeRef = scala(type already seen)
95 | >| | | | symbol = "scala.Predef" (external #28 type = EXTref[9])
96 | >| | | | | parent = scala (already seen at #20)
97 | >| | | symbol = "scala.Predef.String" (external #30 type = EXTref[9])
98 | >| | | | parent = "scala.Predef" (external #32 type = EXTMODCLASSref[10])
99 | >| | | | | parent = scala (already seen at #20)
100 | >| child 2/19 = MethodSymbol name = "param2" (entry #33)
101 | >| | path = "scalaj.reflect.targets.BasicSample.param2"
102 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
103 | >| | flags/info = 537395204 / 35
104 | >| | infoType = TypeRefType
105 | >| | | prefix = scala(type already seen)
106 | >| | | symbol = "scala.Int" (external #36 type = EXTref[9])
107 | >| | | | parent = scala (already seen at #20)
108 | >| child 3/19 = MethodSymbol name = "" (entry #38)
109 | >| | path = "scalaj.reflect.targets.BasicSample."
110 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
111 | >| | flags/info = 512 / 40
112 | >| | infoType = MethodType
113 | >| | | resultType = TypeRefType
114 | >| | | | prefix = ThisType
115 | >| | | | | symbol = scalaj.reflect.targets (already seen at #2)
116 | >| | | | symbol = scalaj.reflect.targets.BasicSample (already seen at #0)
117 | >| | | paramSymbol 1/2 = MethodSymbol name = "param1" (entry #43)
118 | >| | | | path = "scalaj.reflect.targets.BasicSample..param1"
119 | >| | | | owner = scalaj.reflect.targets.BasicSample. (already seen at #38)
120 | >| | | | flags/info = 8192 / 26
121 | >| | | | infoType = scala.Predef.String(type already seen)
122 | >| | | paramSymbol 2/2 = MethodSymbol name = "param2" (entry #44)
123 | >| | | | path = "scalaj.reflect.targets.BasicSample..param2"
124 | >| | | | owner = scalaj.reflect.targets.BasicSample. (already seen at #38)
125 | >| | | | flags/info = 8192 / 35
126 | >| | | | infoType = scala.Int(type already seen)
127 | >| | child 1/2 = scalaj.reflect.targets.BasicSample..param1 (already seen at #43)
128 | >| | child 2/2 = scalaj.reflect.targets.BasicSample..param2 (already seen at #44)
129 | >| child 4/19 = MethodSymbol name = "" (entry #45)
130 | >| | path = "scalaj.reflect.targets.BasicSample."
131 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
132 | >| | flags/info = 512 / 46
133 | >| | infoType = MethodType
134 | >| | | resultType = scalaj.reflect.targets.BasicSample(type already seen)
135 | >| | | paramSymbol 1/1 = MethodSymbol name = "param2a" (entry #47)
136 | >| | | | path = "scalaj.reflect.targets.BasicSample..param2a"
137 | >| | | | owner = scalaj.reflect.targets.BasicSample. (already seen at #45)
138 | >| | | | flags/info = 8192 / 49
139 | >| | | | infoType = TypeRefType
140 | >| | | | | prefix = scala(type already seen)
141 | >| | | | | symbol = "scala.Float" (external #50 type = EXTref[9])
142 | >| | | | | | parent = scala (already seen at #20)
143 | >| | child 1/1 = scalaj.reflect.targets.BasicSample..param2a (already seen at #47)
144 | >| child 5/19 = AliasSymbol name = "StringAlias" (entry #52)
145 | >| | path = "StringAlias"
146 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
147 | >| | flags/info = 1073741824 / 26
148 | >| | infoType = scala.Predef.String(type already seen)
149 | >| child 6/19 = ClassSymbol name = "Foo" (entry #54)
150 | >| | path = "scalaj.reflect.targets.BasicSample.Foo"
151 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
152 | >| | flags/info = 1073741824 / 56
153 | >| | infoType = ClassInfoType
154 | >| | | symbol = scalaj.reflect.targets.BasicSample.Foo (already seen at #54)
155 | >| | | typeRef 1/2 = java.lang.Object(type already seen)
156 | >| | | typeRef 2/2 = scala.ScalaObject(type already seen)
157 | >| | child 1/3 = MethodSymbol name = "param" (entry #57)
158 | >| | | path = "scalaj.reflect.targets.BasicSample.Foo.param"
159 | >| | | owner = scalaj.reflect.targets.BasicSample.Foo (already seen at #54)
160 | >| | | flags/info = 675283456 / 59
161 | >| | | infoType = PolyType
162 | >| | | | typeRef = scala.Predef.String(type already seen)
163 | >| | child 2/3 = MethodSymbol name = "param " (entry #60)
164 | >| | | path = "scalaj.reflect.targets.BasicSample.Foo.param "
165 | >| | | owner = scalaj.reflect.targets.BasicSample.Foo (already seen at #54)
166 | >| | | flags/info = 537395204 / 26
167 | >| | | infoType = scala.Predef.String(type already seen)
168 | >| | child 3/3 = MethodSymbol name = "" (entry #62)
169 | >| | | path = "scalaj.reflect.targets.BasicSample.Foo."
170 | >| | | owner = scalaj.reflect.targets.BasicSample.Foo (already seen at #54)
171 | >| | | flags/info = 512 / 63
172 | >| | | infoType = MethodType
173 | >| | | | resultType = TypeRefType
174 | >| | | | | prefix = ThisType
175 | >| | | | | | symbol = scalaj.reflect.targets.BasicSample (already seen at #0)
176 | >| | | | | symbol = scalaj.reflect.targets.BasicSample.Foo (already seen at #54)
177 | >| | | | paramSymbol 1/1 = MethodSymbol name = "param" (entry #66)
178 | >| | | | | path = "scalaj.reflect.targets.BasicSample.Foo..param"
179 | >| | | | | owner = scalaj.reflect.targets.BasicSample.Foo. (already seen at #62)
180 | >| | | | | flags/info = 8192 / 26
181 | >| | | | | infoType = scala.Predef.String(type already seen)
182 | >| | | child 1/1 = scalaj.reflect.targets.BasicSample.Foo..param (already seen at #66)
183 | >| child 7/19 = MethodSymbol name = "implicitString" (entry #67)
184 | >| | path = "scalaj.reflect.targets.BasicSample.implicitString"
185 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
186 | >| | flags/info = 138412545 / 69
187 | >| | infoType = PolyType
188 | >| | | typeRef = TypeRefType
189 | >| | | | prefix = java.lang(type already seen)
190 | >| | | | symbol = "java.lang.String" (external #71 type = EXTref[9])
191 | >| | | | | parent = java.lang (already seen at #12)
192 | >| child 8/19 = MethodSymbol name = "implicitString " (entry #72)
193 | >| | path = "scalaj.reflect.targets.BasicSample.implicitString "
194 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
195 | >| | flags/info = 524292 / 70
196 | >| | infoType = java.lang.String(type already seen)
197 | >| child 9/19 = MethodSymbol name = "simpleVar" (entry #74)
198 | >| | path = "scalaj.reflect.targets.BasicSample.simpleVar"
199 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
200 | >| | flags/info = 134218240 / 76
201 | >| | infoType = PolyType
202 | >| | | typeRef = scala.Int(type already seen)
203 | >| child 10/19 = MethodSymbol name = "simpleVar_$eq" (entry #77)
204 | >| | path = "scalaj.reflect.targets.BasicSample.simpleVar_$eq"
205 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
206 | >| | flags/info = 134218240 / 79
207 | >| | infoType = MethodType
208 | >| | | resultType = TypeRefType
209 | >| | | | prefix = scala(type already seen)
210 | >| | | | symbol = "scala.Unit" (external #81 type = EXTref[9])
211 | >| | | | | parent = scala (already seen at #20)
212 | >| | | paramSymbol 1/1 = MethodSymbol name = "x$1" (entry #83)
213 | >| | | | path = "scalaj.reflect.targets.BasicSample.simpleVar_$eq.x$1"
214 | >| | | | owner = scalaj.reflect.targets.BasicSample.simpleVar_$eq (already seen at #77)
215 | >| | | | flags/info = 2105344 / 35
216 | >| | | | infoType = scala.Int(type already seen)
217 | >| | child 1/1 = scalaj.reflect.targets.BasicSample.simpleVar_$eq.x$1 (already seen at #83)
218 | >| child 11/19 = MethodSymbol name = "simpleVar " (entry #85)
219 | >| | path = "scalaj.reflect.targets.BasicSample.simpleVar "
220 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
221 | >| | flags/info = 528388 / 35
222 | >| | infoType = scala.Int(type already seen)
223 | >| child 12/19 = MethodSymbol name = "simpleMethod" (entry #87)
224 | >| | path = "scalaj.reflect.targets.BasicSample.simpleMethod"
225 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
226 | >| | flags/info = 512 / 89
227 | >| | infoType = MethodType
228 | >| | | resultType = java.lang.String(type already seen)
229 | >| | | paramSymbol 1/1 = MethodSymbol name = "arg" (entry #90)
230 | >| | | | path = "scalaj.reflect.targets.BasicSample.simpleMethod.arg"
231 | >| | | | owner = scalaj.reflect.targets.BasicSample.simpleMethod (already seen at #87)
232 | >| | | | flags/info = 8192 / 26
233 | >| | | | infoType = scala.Predef.String(type already seen)
234 | >| | child 1/1 = scalaj.reflect.targets.BasicSample.simpleMethod.arg (already seen at #90)
235 | >| child 13/19 = MethodSymbol name = "defaultArgMethod" (entry #92)
236 | >| | path = "scalaj.reflect.targets.BasicSample.defaultArgMethod"
237 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
238 | >| | flags/info = 512 / 94
239 | >| | infoType = MethodType
240 | >| | | resultType = java.lang.String(type already seen)
241 | >| | | paramSymbol 1/1 = MethodSymbol name = "arg" (entry #95)
242 | >| | | | path = "scalaj.reflect.targets.BasicSample.defaultArgMethod.arg"
243 | >| | | | owner = scalaj.reflect.targets.BasicSample.defaultArgMethod (already seen at #92)
244 | >| | | | flags/info = 33562624 / 26
245 | >| | | | infoType = scala.Predef.String(type already seen)
246 | >| | child 1/1 = scalaj.reflect.targets.BasicSample.defaultArgMethod.arg (already seen at #95)
247 | >| child 14/19 = MethodSymbol name = "implicitArgMethod" (entry #96)
248 | >| | path = "scalaj.reflect.targets.BasicSample.implicitArgMethod"
249 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
250 | >| | flags/info = 512 / 98
251 | >| | infoType = ImplicitMethodType
252 | >| | | resultType = java.lang.String(type already seen)
253 | >| | | paramSymbol 1/1 = MethodSymbol name = "arg" (entry #99)
254 | >| | | | path = "scalaj.reflect.targets.BasicSample.implicitArgMethod.arg"
255 | >| | | | owner = scalaj.reflect.targets.BasicSample.implicitArgMethod (already seen at #96)
256 | >| | | | flags/info = 8193 / 26
257 | >| | | | infoType = scala.Predef.String(type already seen)
258 | >| | child 1/1 = scalaj.reflect.targets.BasicSample.implicitArgMethod.arg (already seen at #99)
259 | >| child 15/19 = MethodSymbol name = "multiArgMethod" (entry #100)
260 | >| | path = "scalaj.reflect.targets.BasicSample.multiArgMethod"
261 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
262 | >| | flags/info = 512 / 102
263 | >| | infoType = MethodType
264 | >| | | resultType = java.lang.String(type already seen)
265 | >| | | paramSymbol 1/2 = MethodSymbol name = "arg1" (entry #103)
266 | >| | | | path = "scalaj.reflect.targets.BasicSample.multiArgMethod.arg1"
267 | >| | | | owner = scalaj.reflect.targets.BasicSample.multiArgMethod (already seen at #100)
268 | >| | | | flags/info = 8192 / 26
269 | >| | | | infoType = scala.Predef.String(type already seen)
270 | >| | | paramSymbol 2/2 = MethodSymbol name = "arg2" (entry #105)
271 | >| | | | path = "scalaj.reflect.targets.BasicSample.multiArgMethod.arg2"
272 | >| | | | owner = scalaj.reflect.targets.BasicSample.multiArgMethod (already seen at #100)
273 | >| | | | flags/info = 8192 / 26
274 | >| | | | infoType = scala.Predef.String(type already seen)
275 | >| | child 1/2 = scalaj.reflect.targets.BasicSample.multiArgMethod.arg1 (already seen at #103)
276 | >| | child 2/2 = scalaj.reflect.targets.BasicSample.multiArgMethod.arg2 (already seen at #105)
277 | >| child 16/19 = MethodSymbol name = "multiBlockMethod" (entry #107)
278 | >| | path = "scalaj.reflect.targets.BasicSample.multiBlockMethod"
279 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
280 | >| | flags/info = 512 / 109
281 | >| | infoType = MethodType
282 | >| | | resultType = MethodType
283 | >| | | | resultType = java.lang.String(type already seen)
284 | >| | | | paramSymbol 1/1 = MethodSymbol name = "arg2" (entry #111)
285 | >| | | | | path = "scalaj.reflect.targets.BasicSample.multiBlockMethod.arg2"
286 | >| | | | | owner = scalaj.reflect.targets.BasicSample.multiBlockMethod (already seen at #107)
287 | >| | | | | flags/info = 8192 / 26
288 | >| | | | | infoType = scala.Predef.String(type already seen)
289 | >| | | paramSymbol 1/1 = MethodSymbol name = "arg1" (entry #112)
290 | >| | | | path = "scalaj.reflect.targets.BasicSample.multiBlockMethod.arg1"
291 | >| | | | owner = scalaj.reflect.targets.BasicSample.multiBlockMethod (already seen at #107)
292 | >| | | | flags/info = 8192 / 26
293 | >| | | | infoType = scala.Predef.String(type already seen)
294 | >| | child 1/2 = scalaj.reflect.targets.BasicSample.multiBlockMethod.arg2 (already seen at #111)
295 | >| | child 2/2 = scalaj.reflect.targets.BasicSample.multiBlockMethod.arg1 (already seen at #112)
296 | >| child 17/19 = MethodSymbol name = "genericMethod" (entry #113)
297 | >| | path = "scalaj.reflect.targets.BasicSample.genericMethod"
298 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
299 | >| | flags/info = 512 / 115
300 | >| | infoType = PolyType
301 | >| | | typeRef = MethodType
302 | >| | | | resultType = java.lang.String(type already seen)
303 | >| | | | paramSymbol 1/1 = MethodSymbol name = "arg" (entry #117)
304 | >| | | | | path = "scalaj.reflect.targets.BasicSample.genericMethod.arg"
305 | >| | | | | owner = scalaj.reflect.targets.BasicSample.genericMethod (already seen at #113)
306 | >| | | | | flags/info = 8192 / 118
307 | >| | | | | infoType = TypeRefType
308 | >| | | | | | prefix = NoPrefixType
309 | >| | | | | | symbol = TypeSymbol name = "T" (entry #120)
310 | >| | | | | | | path = "T"
311 | >| | | | | | | owner = scalaj.reflect.targets.BasicSample.genericMethod (already seen at #113)
312 | >| | | | | | | flags/info = 1073750272 / 122
313 | >| | | | | | | infoType = TypeBoundsType
314 | >| | | | | | | | lower = TypeRefType
315 | >| | | | | | | | | prefix = scala(type already seen)
316 | >| | | | | | | | | symbol = "scala.Nothing" (external #124 type = EXTref[9])
317 | >| | | | | | | | | | parent = scala (already seen at #20)
318 | >| | | | | | | | upper = TypeRefType
319 | >| | | | | | | | | prefix = scala(type already seen)
320 | >| | | | | | | | | symbol = "scala.Any" (external #127 type = EXTref[9])
321 | >| | | | | | | | | | parent = scala (already seen at #20)
322 | >| | | symbol 1/1 = T (already seen at #120)
323 | >| | child 1/2 = scalaj.reflect.targets.BasicSample.genericMethod.arg (already seen at #117)
324 | >| | child 2/2 = T (already seen at #120)
325 | >| child 18/19 = MethodSymbol name = "viewBoundMethod" (entry #129)
326 | >| | path = "scalaj.reflect.targets.BasicSample.viewBoundMethod"
327 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
328 | >| | flags/info = 512 / 131
329 | >| | infoType = PolyType
330 | >| | | typeRef = MethodType
331 | >| | | | resultType = ImplicitMethodType
332 | >| | | | | resultType = java.lang.String(type already seen)
333 | >| | | | | paramSymbol 1/1 = MethodSymbol name = "evidence$1" (entry #134)
334 | >| | | | | | path = "scalaj.reflect.targets.BasicSample.viewBoundMethod.evidence$1"
335 | >| | | | | | owner = scalaj.reflect.targets.BasicSample.viewBoundMethod (already seen at #129)
336 | >| | | | | | flags/info = 8193 / 136
337 | >| | | | | | infoType = TypeRefType
338 | >| | | | | | | prefix = scala(type already seen)
339 | >| | | | | | | symbol = "scala.Function1" (external #137 type = EXTref[9])
340 | >| | | | | | | | parent = scala (already seen at #20)
341 | >| | | | | | | typeArg 1/2 = TypeRefType
342 | >| | | | | | | | prefix = NoPrefixType(type already seen)
343 | >| | | | | | | | symbol = TypeSymbol name = "T" (entry #140)
344 | >| | | | | | | | | path = "T"
345 | >| | | | | | | | | owner = scalaj.reflect.targets.BasicSample.viewBoundMethod (already seen at #129)
346 | >| | | | | | | | | flags/info = 1073750272 / 122
347 | >| | | | | | | | | infoType = scala.Nothing <: scala.Any(type already seen)
348 | >| | | | | | | typeArg 2/2 = TypeRefType
349 | >| | | | | | | | prefix = SingleType
350 | >| | | | | | | | | typeRef = SingleType
351 | >| | | | | | | | | | typeRef = ThisType
352 | >| | | | | | | | | | | symbol = "." (external #145 type = EXTMODCLASSref[10])
353 | >| | | | | | | | | | | | parent = NoSymbol
354 | >| | | | | | | | | | symbol = "scala" (external #147 type = EXTref[9])
355 | >| | | | | | | | | symbol = "scala.package" (external #148 type = EXTref[9])
356 | >| | | | | | | | | | parent = scala (already seen at #20)
357 | >| | | | | | | | symbol = "scala.package.Ordered" (external #150 type = EXTref[9])
358 | >| | | | | | | | | parent = "scala.package" (external #152 type = EXTMODCLASSref[10])
359 | >| | | | | | | | | | parent = scala (already seen at #20)
360 | >| | | | | | | | typeArg 1/1 = T(type already seen)
361 | >| | | | paramSymbol 1/1 = MethodSymbol name = "arg" (entry #153)
362 | >| | | | | path = "scalaj.reflect.targets.BasicSample.viewBoundMethod.arg"
363 | >| | | | | owner = scalaj.reflect.targets.BasicSample.viewBoundMethod (already seen at #129)
364 | >| | | | | flags/info = 8192 / 139
365 | >| | | | | infoType = T(type already seen)
366 | >| | | symbol 1/1 = T (already seen at #140)
367 | >| | child 1/3 = scalaj.reflect.targets.BasicSample.viewBoundMethod.evidence$1 (already seen at #134)
368 | >| | child 2/3 = T (already seen at #140)
369 | >| | child 3/3 = scalaj.reflect.targets.BasicSample.viewBoundMethod.arg (already seen at #153)
370 | >| child 19/19 = MethodSymbol name = "defaultArgMethod$default$1" (entry #154)
371 | >| | path = "scalaj.reflect.targets.BasicSample.defaultArgMethod$default$1"
372 | >| | owner = scalaj.reflect.targets.BasicSample (already seen at #0)
373 | >| | flags/info = 35652096 / 156
374 | >| | infoType = PolyType
375 | >| | | typeRef = AnnotatedType
376 | >| | | | typeRef = scala.Predef.String(type already seen)
377 | >| | | | attribTreeRef 1/1 = 158""".stripMargin('>')
378 |
379 | val polymorphicSampleClass =
380 | """>ClassSymbol name = "PolymorphicSample" (entry #0)
381 | >| path = "scalaj.reflect.targets.PolymorphicSample"
382 | >| owner = "scalaj.reflect.targets" (external #2 type = EXTMODCLASSref[10])
383 | >| | parent = "scalaj.reflect" (external #4 type = EXTMODCLASSref[10])
384 | >| | | parent = "scalaj" (external #6 type = EXTMODCLASSref[10])
385 | >| flags/info = 128 / 9
386 | >| infoType = PolyType
387 | >| | typeRef = ClassInfoType
388 | >| | | symbol = scalaj.reflect.targets.PolymorphicSample (already seen at #0)
389 | >| | | typeRef 1/2 = TypeRefType
390 | >| | | | prefix = ThisType
391 | >| | | | | symbol = "java.lang" (external #13 type = EXTMODCLASSref[10])
392 | >| | | | | | parent = "java" (external #15 type = EXTMODCLASSref[10])
393 | >| | | | symbol = "java.lang.Object" (external #17 type = EXTref[9])
394 | >| | | | | parent = java.lang (already seen at #13)
395 | >| | | typeRef 2/2 = TypeRefType
396 | >| | | | prefix = ThisType
397 | >| | | | | symbol = "scala" (external #21 type = EXTMODCLASSref[10])
398 | >| | | | symbol = "scala.ScalaObject" (external #23 type = EXTref[9])
399 | >| | | | | parent = scala (already seen at #21)
400 | >| | symbol 1/1 = TypeSymbol name = "T" (entry #32)
401 | >| | | path = "T"
402 | >| | | owner = scalaj.reflect.targets.PolymorphicSample (already seen at #0)
403 | >| | | flags/info = 1073750272 / 34
404 | >| | | infoType = TypeBoundsType
405 | >| | | | lower = TypeRefType
406 | >| | | | | prefix = scala(type already seen)
407 | >| | | | | symbol = "scala.Nothing" (external #36 type = EXTref[9])
408 | >| | | | | | parent = scala (already seen at #21)
409 | >| | | | upper = TypeRefType
410 | >| | | | | prefix = scala(type already seen)
411 | >| | | | | symbol = "scala.Any" (external #39 type = EXTref[9])
412 | >| | | | | | parent = scala (already seen at #21)
413 | >| child 1/4 = MethodSymbol name = "" (entry #25)
414 | >| | path = "scalaj.reflect.targets.PolymorphicSample."
415 | >| | owner = scalaj.reflect.targets.PolymorphicSample (already seen at #0)
416 | >| | flags/info = 512 / 27
417 | >| | infoType = MethodType
418 | >| | | resultType = TypeRefType
419 | >| | | | prefix = ThisType
420 | >| | | | | symbol = scalaj.reflect.targets (already seen at #2)
421 | >| | | | symbol = scalaj.reflect.targets.PolymorphicSample (already seen at #0)
422 | >| | | | typeArg 1/1 = TypeRefType
423 | >| | | | | prefix = NoPrefixType
424 | >| | | | | symbol = T (already seen at #32)
425 | >| child 2/4 = T (already seen at #32)
426 | >| child 3/4 = MethodSymbol name = "sampleVal" (entry #41)
427 | >| | path = "scalaj.reflect.targets.PolymorphicSample.sampleVal"
428 | >| | owner = scalaj.reflect.targets.PolymorphicSample (already seen at #0)
429 | >| | flags/info = 768 / 43
430 | >| | infoType = PolyType
431 | >| | | typeRef = T(type already seen)
432 | >| child 4/4 = MethodSymbol name = "method" (entry #44)
433 | >| | path = "scalaj.reflect.targets.PolymorphicSample.method"
434 | >| | owner = scalaj.reflect.targets.PolymorphicSample (already seen at #0)
435 | >| | flags/info = 512 / 46
436 | >| | infoType = PolyType
437 | >| | | typeRef = MethodType
438 | >| | | | resultType = TypeRefType
439 | >| | | | | prefix = NoPrefixType(type already seen)
440 | >| | | | | symbol = TypeSymbol name = "T" (entry #49)
441 | >| | | | | | path = "T"
442 | >| | | | | | owner = scalaj.reflect.targets.PolymorphicSample.method (already seen at #44)
443 | >| | | | | | flags/info = 1073750272 / 34
444 | >| | | | | | infoType = scala.Nothing <: scala.Any(type already seen)
445 | >| | | | paramSymbol 1/1 = MethodSymbol name = "x" (entry #50)
446 | >| | | | | path = "scalaj.reflect.targets.PolymorphicSample.method.x"
447 | >| | | | | owner = scalaj.reflect.targets.PolymorphicSample.method (already seen at #44)
448 | >| | | | | flags/info = 8192 / 48
449 | >| | | | | infoType = T(type already seen)
450 | >| | | symbol 1/1 = T (already seen at #49)
451 | >| | child 1/2 = T (already seen at #49)
452 | >| | child 2/2 = scalaj.reflect.targets.PolymorphicSample.method.x (already seen at #50)""".stripMargin('>')
453 |
454 | }
455 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/MirrorsSpec.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 |
4 | import scalaj.reflect.{TypeWrangler => wrangler}
5 | import org.specs.SpecificationWithJUnit
6 | import reflect.Manifest
7 |
8 | class MirrorsSpec extends SpecificationWithJUnit {
9 | val tgtMirror = Mirror.ofClass[targets.BasicSample].get
10 |
11 | "a class mirror" should {
12 | "reflect a dynamically sourced Class[_] instance" in {
13 | val dynMirror = Mirror.ofClass(Class.forName("scalaj.reflect.targets.BasicSample"))
14 | dynMirror map { m => m.name mustEqual "BasicSample" }
15 | }
16 |
17 | "locate all defs" in {
18 |
19 | val defs = tgtMirror.allDefs map (_.name)
20 | // println("defs = " + (defs mkString ", "))
21 | defs mustEqual Seq(
22 | "simpleMethod",
23 | "defaultArgMethod",
24 | "implicitArgMethod",
25 | "multiArgMethod",
26 | "multiBlockMethod",
27 | "genericMethod",
28 | "viewBoundMethod")
29 | }
30 |
31 | "locate all constructors" in {
32 | val constructors = tgtMirror.constructors
33 | // println("constructors = " + (constructors.map(_.method) mkString ", "))
34 | constructors.size mustEqual 2
35 |
36 | val Seq(ctor1,ctor2) = constructors
37 | }
38 |
39 | "locate all accessors" in {
40 | val accessors = tgtMirror.allAccessors map (_.name)
41 | // println("accessors = " + (accessors mkString ", "))
42 | accessors mustEqual Seq("implicitString", "simpleVar")
43 | }
44 |
45 | "locate all vals" in {
46 | val vals = tgtMirror.vals map (_.name)
47 | // println("vals = " + (vals mkString ", "))
48 | vals mustEqual Seq("implicitString")
49 | }
50 |
51 | "locate all vars" in {
52 | val vars = tgtMirror.vars map (_.name)
53 | // println("vars = " + (vars mkString ", "))
54 | vars mustEqual Seq("simpleVar")
55 | }
56 |
57 | "locate all type aliases" in {
58 | val typeAliases = tgtMirror.typeAliases map (_.name)
59 | // println("typeAliases = " + (typeAliases mkString ", "))
60 | typeAliases mustEqual Seq("StringAlias")
61 | }
62 |
63 | "correctly display the name of the mirrored class" in {
64 | // symNames mustEqual Seq("class SampleTarget", "object SampleTarget")
65 | tgtMirror.toString mustEqual "class BasicSample"
66 |
67 | tgtMirror.name mustEqual "BasicSample"
68 | tgtMirror.qualifiedName mustEqual "scalaj.reflect.targets.BasicSample"
69 | }
70 |
71 | "locate default type params for a generic polymorphic mirrored class" in {
72 | val mirror = Mirror.ofClass[targets.PolymorphicSample[_]].get
73 | val actual = mirror.typeParams
74 | val expected = Seq(Manifest.wildcardType(Manifest.Nothing, Manifest.Any))
75 | actual mustEqual expected
76 | }
77 |
78 | "generate a manifest for a simple (monomorphic) mirrored class" in {
79 | val mani = tgtMirror.manifest
80 | mani mustEqual manifest[targets.BasicSample]
81 | }
82 |
83 | "generate a manifest for a wildcard polymorphic mirrored class" in {
84 | val mirror = Mirror.ofClass[targets.PolymorphicSample[_]].get
85 | val actual = mirror.manifest
86 | val expected = manifest[targets.PolymorphicSample[_]]
87 | actual mustEqual expected
88 | }
89 |
90 | "directly refine a generic polymorphic mirrored class" in {
91 | val mirror = Mirror.ofClass[targets.PolymorphicSample[_]].get
92 | val refined = mirror.reify(manifest[Int])
93 | val actual = refined.manifest
94 | val expected = manifest[targets.PolymorphicSample[Int]]
95 | actual mustEqual expected
96 | }
97 |
98 | "generate a manifest for a refined polymorphic mirrored class" in {
99 | val mirror = Mirror.ofClass[targets.PolymorphicSample[Int]].get
100 | val actual = mirror.manifest
101 | val expected = manifest[targets.PolymorphicSample[Int]]
102 | actual mustEqual expected
103 | }
104 |
105 | // "generate a manifest for a nested polymorphic mirrored class" in {
106 | // val mirror = Mirror.ofClass[targets.NestedPolymorphicSample[Int]#Inner].get
107 | // val actual = mirror.manifest
108 | // val expected = manifest[targets.NestedPolymorphicSample[Int]#Inner]
109 | // actual mustEqual expected
110 | // }
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/SymbolTreePrinterSpec.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect
2 |
3 | import org.specs.SpecificationWithJUnit
4 |
5 | class SymbolTreePrinterSpec extends SpecificationWithJUnit {
6 | "a symbol tree printer" should {
7 | "print tree of primitive var" in {
8 | val classMirror = Mirror.ofClass[targets.BasicSample].get
9 |
10 | val varMirror = classMirror.vars.find(_.name=="simpleVar").get
11 |
12 | val getterTree = SymbolTreePrinter.withoutOwners mkTree varMirror.getter
13 | compareLines(getterTree, ExpectedPrintTrees.simpleVarGetter)
14 |
15 | val setterTree = SymbolTreePrinter.withoutOwners mkTree varMirror.setter
16 | compareLines(setterTree, ExpectedPrintTrees.simpleVarSetter)
17 | }
18 |
19 | "print tree of simple method param" in {
20 | val classMirror = Mirror.ofClass[targets.BasicSample].get
21 |
22 | val method = classMirror.allDefs.find(_.name=="simpleMethod").get
23 | val params = method.flatParams
24 | val paramStrings = params map {p => p.name + ": " + p.symType.toString}
25 | val actualTree = SymbolTreePrinter.withoutOwners mkTree params.head
26 | compareLines(actualTree, ExpectedPrintTrees.simpleMethodArg)
27 | }
28 |
29 | "print tree of generic method param" in {
30 | val classMirror = Mirror.ofClass[targets.BasicSample].get
31 |
32 | val method = classMirror.allDefs.find(_.name=="genericMethod").get
33 | val params = method.flatParams
34 | val paramStrings = params map {p => p.name + ": " + p.symType.toString}
35 | val actualTree = SymbolTreePrinter.withoutOwners mkTree params.head
36 | compareLines(actualTree, ExpectedPrintTrees.genericMethodArg)
37 | }
38 |
39 | "print tree of a simple class" in {
40 | val classMirror = Mirror.ofClass[targets.BasicSample].get
41 | val actualTree = SymbolTreePrinter mkTree classMirror
42 | compareLines(actualTree, ExpectedPrintTrees.basicSampleClass)
43 | }
44 |
45 | "print tree of a polymorphic class" in {
46 | val classMirror = Mirror.ofClass[targets.PolymorphicSample[_]].get
47 | val actualTree = SymbolTreePrinter mkTree classMirror
48 | compareLines(actualTree, ExpectedPrintTrees.polymorphicSampleClass)
49 | }
50 |
51 | // "print tree with nested class" in {
52 | // val classMirror = Mirror.ofClass[targets.TweedleDee]
53 | // try {
54 | // println (classMirror map {SymbolTreePrinter.withoutOwners.mkTree} )
55 | // } catch {
56 | // case e: Exception =>
57 | // println(e.getMessage)
58 | // e.printStackTrace
59 | // }
60 | // }
61 | //
62 | // "print tree with path-dependent alias" in {
63 | // val classMirror = Mirror.ofClass[targets.TweedleDo]
64 | // try {
65 | // //val member = classMirror.allNaturalMethods.find(_.name=="member").get
66 | // println (classMirror map {SymbolTreePrinter.withoutOwners.mkTree})
67 | // } catch {
68 | // case e: Exception =>
69 | // println(e.getMessage)
70 | // e.printStackTrace
71 | // }
72 | // }
73 | def compareLines(actual: String, expected: String): Unit =
74 | (actual.lines zip expected.lines) foreach {
75 | case (l,r) => l.trim mustEqual r.trim
76 | }
77 |
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/TypeWranglerSpec.scala:
--------------------------------------------------------------------------------
1 | package scalaj.spring
2 |
3 | //give the wrangler a short name, don't import methods as we want full control without using them as implicits
4 | import scalaj.reflect.{TypeWrangler => wrangler}
5 | import org.specs.SpecificationWithJUnit
6 |
7 |
8 | class TypeWranglerSpec extends SpecificationWithJUnit {
9 | "the TypeWrangler" should {
10 | "dynamically lookup a Seq[String] manifest" in {
11 | val actual : Manifest[_] = wrangler.manifestOf(classOf[Seq[String]])
12 | val expected : Manifest[_] = manifest[Seq[String]]
13 |
14 | 1 mustEqual 1
15 | //actual.toString mustEqual expected.toString
16 | //actual mustEqual expected
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/targets/BasicSample.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect.targets
2 |
3 | class BasicSample(param1: String, param2: Int) {
4 |
5 | def this(param2a: Float) = this("float", param2a.toInt)
6 |
7 | type StringAlias = String
8 |
9 | class Foo(val param: String)
10 |
11 | // case class Bar(val param: String)
12 |
13 | implicit val implicitString = "xxx"
14 |
15 | var simpleVar = 42
16 |
17 | def simpleMethod(arg: String) = "xxx"
18 | def defaultArgMethod(arg: String = "default") = "xxx"
19 | def implicitArgMethod(implicit arg: String) = "xxx"
20 |
21 | def multiArgMethod(arg1: String, arg2: String) = "xxx"
22 | def multiBlockMethod(arg1: String)(arg2: String) = "xxx"
23 |
24 | def genericMethod[T](arg: T) = "xxx"
25 | def viewBoundMethod[T <% Ordered[T]](arg: T) = "xxx"
26 |
27 | }
28 |
29 | //object SampleTarget
30 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/targets/NestedPolymorphicSample.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect.targets
2 |
3 | abstract class NestedPolymorphicSample[T] {
4 | abstract class Inner {
5 | def sampleVal: T
6 | def method[T](x: T) = x
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/targets/PolymorphicSample.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect.targets
2 |
3 | abstract class PolymorphicSample[T] {
4 | def sampleVal: T
5 | def method[T](x: T) = x
6 | }
7 |
8 | class polymorphicSub extends PolymorphicSample[Int] {
9 | def sampleVal: Int = 42
10 | }
11 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/targets/TweedleDee.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect.targets
2 |
3 | class TweedleDee {
4 | class InnerDee {
5 | val member = (new TweedleDum).getInner
6 | }
7 |
8 | type InnerT = InnerDee
9 | def getInner: InnerT = new InnerDee
10 | }
11 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/targets/TweedleDo.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect.targets
2 | class TweedleDo {
3 |
4 | def a = (new TweedleDee)
5 | val b: TweedleDee#InnerT = a.getInner
6 | val c = b.member
7 | def d = c.member
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/test/scala/scalaj/reflect/targets/TweedleDum.scala:
--------------------------------------------------------------------------------
1 | package scalaj.reflect.targets;
2 | class TweedleDum {
3 | class InnerDum {
4 | val member = "XXX"
5 | }
6 |
7 | type InnerT = InnerDum
8 | def getInner: InnerT = new InnerDum
9 | }
10 |
--------------------------------------------------------------------------------