summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-11-22 03:17:53 -0800
committerJason Zaugg <jzaugg@gmail.com>2013-11-22 03:17:53 -0800
commit33eba97dcdffd1248721faf42e573e73cb80b04c (patch)
tree24513c62953c1a39c3dd6e414ff1bcfb9dccd8fc /src
parent5710c58b405e107ec29283d846acafd0cda13dcf (diff)
parentd6ef83a2d75292e44e165a438594c035ed1b1330 (diff)
downloadscala-33eba97dcdffd1248721faf42e573e73cb80b04c.tar.gz
scala-33eba97dcdffd1248721faf42e573e73cb80b04c.tar.bz2
scala-33eba97dcdffd1248721faf42e573e73cb80b04c.zip
Merge pull request #3138 from densh/pr/fresh-name-extractor
Refactor out fresh name prefix extraction logic
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala20
-rw-r--r--src/reflect/scala/reflect/internal/FreshNames.scala35
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala6
-rw-r--r--src/reflect/scala/reflect/internal/util/FreshNameCreator.scala7
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala1
5 files changed, 43 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
index 3901184c25..126c14ac81 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
@@ -55,9 +55,7 @@ trait Parsers { self: Quasiquotes =>
def isHole(name: Name): Boolean = holeMap.contains(name)
- override implicit def fresh: FreshNameCreator = new FreshNameCreator {
- override def newName(prefix: String) = super.newName(nme.QUASIQUOTE_PREFIX + prefix)
- }
+ override implicit def fresh: FreshNameCreator = new FreshNameCreator(nme.QUASIQUOTE_PREFIX)
override val treeBuilder = new ParserTreeBuilder {
override implicit def fresh: FreshNameCreator = parser.fresh
@@ -189,19 +187,5 @@ trait Parsers { self: Quasiquotes =>
}
}
- // Extractor that matches names which were generated by call to
- // freshTermName or freshTypeName within quasiquotes. Such names
- // have qq$some$random$prefix$0 shape where qq$ part is added
- // by modified fresh name creator in QuasiquoteParser.
- object FreshName {
- def unapply(name: Name): Option[String] =
- name.toString.split("\\$").toSeq match {
- case qq +: (middle :+ last)
- if qq + "$" == nme.QUASIQUOTE_PREFIX
- && Try(last.toInt).isSuccess && middle.nonEmpty =>
- Some(middle.mkString("", "$", "$"))
- case _ =>
- None
- }
- }
+ object FreshName extends FreshNameExtractor(nme.QUASIQUOTE_PREFIX)
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/internal/FreshNames.scala b/src/reflect/scala/reflect/internal/FreshNames.scala
new file mode 100644
index 0000000000..bb488aa2a8
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/FreshNames.scala
@@ -0,0 +1,35 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2013 LAMP/EPFL
+ */
+
+package scala
+package reflect
+package internal
+
+import scala.reflect.internal.util.FreshNameCreator
+
+trait FreshNames { self: Names =>
+ // default fresh name creator used to abstract over currentUnit.fresh and runtime fresh name creator
+ def currentFreshNameCreator: FreshNameCreator
+
+ // create fresh term/type name using implicit fresh name creator
+ def freshTermName(prefix: String = "x$")(implicit creator: FreshNameCreator): TermName = newTermName(creator.newName(prefix))
+ def freshTypeName(prefix: String)(implicit creator: FreshNameCreator): TypeName = newTypeName(creator.newName(prefix))
+
+ // Extractor that matches names which were generated by some
+ // FreshNameCreator with known prefix. Extracts user-specified
+ // prefix that was used as a parameter to newName by stripping
+ // global creator prefix and unique number in the end of the name.
+ class FreshNameExtractor(creatorPrefix: String = "") {
+ // quote prefix so that it can be used with replaceFirst
+ // which expects regExp rather than simple string
+ val quotedCreatorPrefix = java.util.regex.Pattern.quote(creatorPrefix)
+
+ def unapply(name: Name): Option[String] = {
+ val sname = name.toString
+ // name should start with creatorPrefix and end with number
+ if (!sname.startsWith(creatorPrefix) || !sname.matches("^.*\\d*$")) None
+ else Some(NameTransformer.decode(sname.replaceFirst(quotedCreatorPrefix, "").replaceAll("\\d*$", "")))
+ }
+ }
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index 4998580a7d..c3f3e35fb3 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -42,6 +42,7 @@ abstract class SymbolTable extends macros.Universe
with BuildUtils
with PrivateWithin
with pickling.Translations
+ with FreshNames
{
val gen = new TreeGen { val global: SymbolTable.this.type = SymbolTable.this }
@@ -398,11 +399,6 @@ abstract class SymbolTable extends macros.Universe
* Adds the `sm` String interpolator to a [[scala.StringContext]].
*/
implicit val StringContextStripMarginOps: StringContext => StringContextStripMarginOps = util.StringContextStripMarginOps
-
- // fresh name creation
- def currentFreshNameCreator: FreshNameCreator
- def freshTermName(prefix: String = "x$")(implicit creator: FreshNameCreator): TermName = newTermName(creator.newName(prefix))
- def freshTypeName(prefix: String)(implicit creator: FreshNameCreator): TypeName = newTypeName(creator.newName(prefix))
}
object SymbolTableStats {
diff --git a/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala b/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala
index 3e54de8e1e..8442c1015f 100644
--- a/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala
+++ b/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala
@@ -11,7 +11,7 @@ import java.util.concurrent.atomic.AtomicLong
import scala.collection.mutable
import scala.reflect.NameTransformer
-class FreshNameCreator {
+class FreshNameCreator(creatorPrefix: String = "") {
protected val counters = new ConcurrentHashMap[String, AtomicLong]()
/**
@@ -21,7 +21,8 @@ class FreshNameCreator {
*/
def newName(prefix: String): String = {
val safePrefix = NameTransformer.encode(prefix)
- counters.putIfAbsent(safePrefix, new AtomicLong(0));
- safePrefix + counters.get(safePrefix).incrementAndGet();
+ counters.putIfAbsent(safePrefix, new AtomicLong(0))
+ val idx = counters.get(safePrefix).incrementAndGet()
+ s"$creatorPrefix$safePrefix$idx"
}
}
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index bce506ee0a..344f7682c1 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -51,6 +51,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
// inaccessible: this.SimpleNameOrdering
this.traceSymbols
this.perRunCaches
+ this.FreshNameExtractor
this.FixedMirrorTreeCreator
this.FixedMirrorTypeCreator
this.CompoundTypeTreeOriginalAttachment