From b2e8905678781db3a7903ab4b247b551e319408d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 7 Feb 2015 18:07:14 +0100 Subject: [PATCH 1/3] Make line search logic in SourcePositions generally available. Create an object Util for utility methods that are used in several places. --- src/dotty/tools/dotc/util/SourceFile.scala | 7 +---- src/dotty/tools/dotc/util/Util.scala | 35 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 src/dotty/tools/dotc/util/Util.scala diff --git a/src/dotty/tools/dotc/util/SourceFile.scala b/src/dotty/tools/dotc/util/SourceFile.scala index 4e1eb224ac2f..c5d88d7bf95f 100644 --- a/src/dotty/tools/dotc/util/SourceFile.scala +++ b/src/dotty/tools/dotc/util/SourceFile.scala @@ -99,12 +99,7 @@ case class SourceFile(file: AbstractFile, content: Array[Char]) { * Lines are numbered from 0 */ def offsetToLine(offset: Int): Int = { - val lines = lineIndices - def findLine(lo: Int, hi: Int, mid: Int): Int = - if (offset < lines(mid)) findLine(lo, mid - 1, (lo + mid - 1) / 2) - else if (offset >= lines(mid + 1)) findLine(mid + 1, hi, (mid + 1 + hi) / 2) - else mid - lastLine = findLine(0, lines.length, lastLine) + lastLine = Util.bestFit(lineIndices, offset, lastLine) lastLine } diff --git a/src/dotty/tools/dotc/util/Util.scala b/src/dotty/tools/dotc/util/Util.scala new file mode 100644 index 000000000000..e323d47db08b --- /dev/null +++ b/src/dotty/tools/dotc/util/Util.scala @@ -0,0 +1,35 @@ +package dotty.tools.dotc.util +import reflect.ClassTag + +object Util { + + /** The index `i` in `candidates.indices` such that `candidates(i) <= x` and + * `candidates(i)` is closest to `x`, determined by binary search, or -1 + * if `x < candidates(0)`. + * @param hint If between 0 and `candidates.length` use this + * as the first search point, otherwise use + * `candidates.length/2`. + * @pre candidates is sorted + * @pre candidates(0) <= x + */ + def bestFit(candidates: Array[Int], x: Int, hint: Int = -1): Int = { + def recur(lo: Int, hi: Int, mid: Int): Int = + if (x < candidates(mid)) + recur(lo, mid - 1, (lo + mid - 1) / 2) + else if (mid + 1 < candidates.length && x >= candidates(mid + 1)) + recur(mid + 1, hi, (mid + 1 + hi) / 2) + else mid + val initMid = + if (0 <= hint && hint < candidates.length) hint + else candidates.length / 2 + if (candidates.isEmpty || x < candidates(0)) -1 + else recur(0, candidates.length, initMid) + } + + /** An array twice the size of given array, with existing elements copied over */ + def dble[T: ClassTag](arr: Array[T]) = { + val arr1 = new Array[T](arr.length * 2) + Array.copy(arr, 0, arr1, 0, arr.length) + arr1 + } +} \ No newline at end of file From b6efacf0d9e56b0efc480c79f3ecfe52340970fa Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 10 Feb 2015 12:52:11 +0100 Subject: [PATCH 2/3] After boxing its value, a captured var should become a val. As noted by @sjrd. --- src/dotty/tools/dotc/transform/CapturedVars.scala | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/dotty/tools/dotc/transform/CapturedVars.scala b/src/dotty/tools/dotc/transform/CapturedVars.scala index e923c94de688..68bda9782ec0 100644 --- a/src/dotty/tools/dotc/transform/CapturedVars.scala +++ b/src/dotty/tools/dotc/transform/CapturedVars.scala @@ -59,16 +59,12 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo refMap.getOrElse(cls, refMap(defn.ObjectClass)) } - def capturedType(vble: Symbol)(implicit ctx: Context): Type = { - val oldInfo = vble.denot(ctx.withPhase(thisTransform)).info - refCls(oldInfo.classSymbol, vble.isVolatile).typeRef - } - override def prepareForValDef(vdef: ValDef)(implicit ctx: Context) = { val sym = vdef.symbol if (captured contains sym) { val newd = sym.denot(ctx.withPhase(thisTransform)).copySymDenotation( - info = refCls(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)).typeRef) + info = refCls(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)).typeRef, + initFlags = sym.flags &~ Mutable) newd.removeAnnotation(defn.VolatileAnnot) newd.installAfter(thisTransform) } From 0fd1ced53a0c450134b064ee9de4cfeaa288833f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 10 Feb 2015 14:44:16 +0100 Subject: [PATCH 3/3] Fixed doc comment. --- src/dotty/tools/dotc/util/Util.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dotty/tools/dotc/util/Util.scala b/src/dotty/tools/dotc/util/Util.scala index e323d47db08b..ed9a54e38d09 100644 --- a/src/dotty/tools/dotc/util/Util.scala +++ b/src/dotty/tools/dotc/util/Util.scala @@ -10,7 +10,6 @@ object Util { * as the first search point, otherwise use * `candidates.length/2`. * @pre candidates is sorted - * @pre candidates(0) <= x */ def bestFit(candidates: Array[Int], x: Int, hint: Int = -1): Int = { def recur(lo: Int, hi: Int, mid: Int): Int =