From 339809ed82e14699681a5a7765c87133cd681ec0 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 3 Jun 2013 11:33:53 +0200 Subject: More solid design of Namer with some Typer bits added. --- src/dotty/tools/dotc/core/Decorators.scala | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/dotty/tools/dotc/core/Decorators.scala') diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala index 094aa7b4a..476b97ec2 100644 --- a/src/dotty/tools/dotc/core/Decorators.scala +++ b/src/dotty/tools/dotc/core/Decorators.scala @@ -4,6 +4,8 @@ package core import annotation.tailrec import Symbols._ import Contexts._, Names._, Phases._, printing.Texts._, printing.Printer +import util.Positions.Position, util.SourcePosition +import collection.mutable.ListBuffer /** This object provides useful implicit decorators for types defined elsewhere */ object Decorators { @@ -35,6 +37,33 @@ object Decorators { */ implicit class ListDecorator[T](val xs: List[T]) extends AnyVal { + @inline final def mapconserve[U](f: T => U): List[U] = { + @tailrec + def loop(mapped: ListBuffer[U], unchanged: List[U], pending: List[T]): List[U] = + if (pending.isEmpty) { + if (mapped eq null) unchanged + else mapped.prependToList(unchanged) + } else { + val head0 = pending.head + val head1 = f(head0) + + if (head1.asInstanceOf[AnyRef] eq head0.asInstanceOf[AnyRef]) + loop(mapped, unchanged, pending.tail) + else { + val b = if (mapped eq null) new ListBuffer[U] else mapped + var xc = unchanged + while (xc ne pending) { + b += xc.head + xc = xc.tail + } + b += head1 + val tail0 = pending.tail + loop(b, tail0.asInstanceOf[List[U]], tail0) + } + } + loop(null, xs.asInstanceOf[List[U]], xs) + } + /** Like `xs filter p` but returns list `xs` itself - instead of a copy - * if `p` is true for all elements and `xs` is not longer * than `MaxFilterRecursions`. @@ -86,5 +115,8 @@ object Decorators { def containsPhase(phase: Phase) = names exists (phase.name.startsWith) } + + implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition = + ctx.source.atPos(pos) } -- cgit v1.2.3