summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/util/package.scala
blob: 0db351f918ca943acd3fdc55379b227e4090caa3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* NSC -- new Scala compiler
 * Copyright 2005-2013 LAMP/EPFL
 * @author Paul Phillips
 */

package scala
package tools
package nsc

import java.io.{ OutputStream, PrintStream, ByteArrayOutputStream, PrintWriter, StringWriter }

package object util {
  // forwarder for old code that builds against 2.9 and 2.10
  val Chars = scala.reflect.internal.Chars

  type Set[T <: AnyRef] = scala.reflect.internal.util.Set[T]
  type HashSet[T >: Null <: AnyRef] = scala.reflect.internal.util.HashSet[T]
  val HashSet = scala.reflect.internal.util.HashSet

  /** Apply a function and return the passed value */
  def returning[T](x: T)(f: T => Unit): T = { f(x) ; x }

  /** Execute code and then wait for all non-daemon Threads
   *  created and begun during its execution to complete.
   */
  def waitingForThreads[T](body: => T) = {
    val (result, created) = trackingThreads(body)
    val threads = created filterNot (_.isDaemon)

    // As long as there are non-daemon, live threads (the latter
    // condition should exclude shutdown hooks) we will wait.
    while (threads exists (_.isAlive))
      threads filter (_.isAlive) foreach (_.join())

    result
  }

  /** Executes the code and returns the result and any threads
   *  which were created during its execution.
   */
  def trackingThreads[T](body: => T): (T, Seq[Thread]) = {
    val ts1    = sys.allThreads()
    val result = body
    val ts2    = sys.allThreads()

    (result, ts2 filterNot (ts1 contains _))
  }

  /** Generate a string using a routine that wants to write on a stream. */
  def stringFromWriter(writer: PrintWriter => Unit): String = {
    val stringWriter = new StringWriter()
    val stream = new NewLinePrintWriter(stringWriter)
    writer(stream)
    stream.close()
    stringWriter.toString
  }
  def stringFromStream(stream: OutputStream => Unit): String = {
    val bs = new ByteArrayOutputStream()
    val ps = new PrintStream(bs)
    stream(ps)
    ps.close()
    bs.toString()
  }
  def stackTraceString(ex: Throwable): String = stringFromWriter(ex printStackTrace _)

  /** A one line string which contains the class of the exception, the
   *  message if any, and the first non-Predef location in the stack trace
   *  (to exclude assert, require, etc.)
   */
  def stackTraceHeadString(ex: Throwable): String = {
    val frame = ex.getStackTrace.dropWhile(_.getClassName contains "Predef") take 1 mkString ""
    val msg   = ex.getMessage match { case null | "" => "" ; case s => s"""("$s")""" }
    val clazz = ex.getClass.getName.split('.').last

    s"$clazz$msg @ $frame"
  }

  implicit class StackTraceOps(val e: Throwable) extends AnyVal with StackTracing {
    /** Format the stack trace, returning the prefix consisting of frames that satisfy
     *  a given predicate.
     *  The format is similar to the typical case described in the JavaDoc
     *  for [[java.lang.Throwable#printStackTrace]].
     *  If a stack trace is truncated, it will be followed by a line of the form
     *  `... 3 elided`, by analogy to the lines `... 3 more` which indicate
     *  shared stack trace segments.
     *  @param p the predicate to select the prefix
     */
    def stackTracePrefixString(p: StackTraceElement => Boolean): String = stackTracePrefixString(e)(p)
  }

  lazy val trace = new SimpleTracer(System.out)

  @deprecated("Moved to scala.reflect.internal.util.StringOps", "2.10.0")
  val StringOps = scala.reflect.internal.util.StringOps

  @deprecated("Moved to scala.reflect.internal.util.StringOps", "2.10.0")
  type StringOps = scala.reflect.internal.util.StringOps

  @deprecated("scala.reflect.internal.util.WeakHashSet", "2.10.0")
  type WeakHashSet[T <: AnyRef] = scala.reflect.internal.util.WeakHashSet[T]

  @deprecated("Moved to scala.reflect.internal.util.Position", "2.10.0")
  val Position = scala.reflect.internal.util.Position

  @deprecated("Moved to scala.reflect.internal.util.Position", "2.10.0")
  type Position = scala.reflect.internal.util.Position

  @deprecated("Moved to scala.reflect.internal.util.NoPosition", "2.10.0")
  val NoPosition = scala.reflect.internal.util.NoPosition

  @deprecated("Moved to scala.reflect.internal.util.FakePos", "2.10.0")
  val FakePos = scala.reflect.internal.util.FakePos

  @deprecated("Moved to scala.reflect.internal.util.FakePos", "2.10.0")
  type FakePos = scala.reflect.internal.util.FakePos

  @deprecated("Moved to scala.reflect.internal.util.OffsetPosition", "2.10.0")
  type OffsetPosition = scala.reflect.internal.util.OffsetPosition

  @deprecated("Moved to scala.reflect.internal.util.RangePosition", "2.10.0")
  type RangePosition = scala.reflect.internal.util.RangePosition

  @deprecated("Moved to scala.reflect.internal.util.SourceFile", "2.10.0")
  type SourceFile = scala.reflect.internal.util.SourceFile

  @deprecated("Moved to scala.reflect.internal.util.NoSourceFile", "2.10.0")
  val NoSourceFile = scala.reflect.internal.util.NoSourceFile

  @deprecated("Moved to scala.reflect.internal.util.NoFile", "2.10.0")
  val NoFile = scala.reflect.internal.util.NoFile

  @deprecated("Moved to scala.reflect.internal.util.ScriptSourceFile", "2.10.0")
  val ScriptSourceFile = scala.reflect.internal.util.ScriptSourceFile

  @deprecated("Moved to scala.reflect.internal.util.ScriptSourceFile", "2.10.0")
  type ScriptSourceFile = scala.reflect.internal.util.ScriptSourceFile

  @deprecated("Moved to scala.reflect.internal.util.BatchSourceFile", "2.10.0")
  type BatchSourceFile = scala.reflect.internal.util.BatchSourceFile

  @deprecated("Moved to scala.reflect.internal.util.AbstractFileClassLoader", "2.11.0")
  type AbstractFileClassLoader = scala.reflect.internal.util.AbstractFileClassLoader

  @deprecated("Moved to scala.reflect.internal.util.ScalaClassLoader", "2.11.0")
  val ScalaClassLoader = scala.reflect.internal.util.ScalaClassLoader

  @deprecated("Moved to scala.reflect.internal.util.ScalaClassLoader", "2.11.0")
  type ScalaClassLoader = scala.reflect.internal.util.ScalaClassLoader
}