summaryrefslogtreecommitdiff
path: root/src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala
blob: 8d446cbbf84df0506d08f9c7f1d836be79cffc06 (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
/* NSC -- new Scala compiler
 * Copyright 2009-2013 Typesafe/Scala Solutions and LAMP/EPFL
 * @author Martin Odersky
 */
package scala.tools.nsc
package interactive
package tests.core

import scala.tools.nsc.interactive.Response
import scala.reflect.internal.util.Position
import scala.reflect.internal.util.SourceFile

/**
 * A trait for defining commands that can be queried to the
 * presentation compiler.
 * */
trait AskCommand {

  /** presentation compiler's instance. */
  protected val compiler: Global

  /**
   * Presentation compiler's `askXXX` actions work by doing side-effects
   * on a `Response` instance passed as an argument during the `askXXX`
   * call.
   * The defined method `ask` is meant to encapsulate this behavior.
   * */
  protected def ask[T](op: Response[T] => Unit): Response[T] = {
    val r = new Response[T]
    op(r)
    r
  }
}

/** Ask the presentation compiler to shut-down. */
trait AskShutdown extends AskCommand {
  def askShutdown() = compiler.askShutdown()
}

/** Ask the presentation compiler to parse a sequence of `sources` */
trait AskParse extends AskCommand {
  import compiler.Tree

  /** `sources` need to be entirely parsed before running the test
   *  (else commands such as `AskCompletionAt` may fail simply because
   *  the source's AST is not yet loaded).
   */
  def askParse(sources: Seq[SourceFile]) {
    val responses = sources map (askParse(_))
    responses.foreach(_.get) // force source files parsing
  }

  private def askParse(src: SourceFile, keepLoaded: Boolean = true): Response[Tree] = {
    ask {
      compiler.askParsedEntered(src, keepLoaded, _)
    }
  }
}

/** Ask the presentation compiler to reload a sequence of `sources` */
trait AskReload extends AskCommand {

  /** Reload the given source files and wait for them to be reloaded. */
  protected def askReload(sources: Seq[SourceFile])(implicit reporter: Reporter): Response[Unit] = {
    val sortedSources = (sources map (_.file.name)).sorted
    reporter.println("reload: " + sortedSources.mkString(", "))

    ask {
      compiler.askReload(sources.toList, _)
    }
  }
}

/** Ask the presentation compiler for completion at a given position. */
trait AskCompletionAt extends AskCommand {
  import compiler.Member

  private[tests] def askCompletionAt(pos: Position)(implicit reporter: Reporter): Response[List[Member]] = {
    reporter.println("\naskTypeCompletion at " + pos.source.file.name + ((pos.line, pos.column)))

    ask {
      compiler.askTypeCompletion(pos, _)
    }
  }
}

/** Ask the presentation compiler for type info at a given position. */
trait AskTypeAt extends AskCommand {
  import compiler.Tree

  private[tests] def askTypeAt(pos: Position)(implicit reporter: Reporter): Response[Tree] = {
    reporter.println("\naskType at " + pos.source.file.name + ((pos.line, pos.column)))

    ask {
      compiler.askTypeAt(pos, _)
    }
  }
}

trait AskLoadedTyped extends AskCommand {
  import compiler.Tree

  protected def askLoadedTyped(source: SourceFile)(implicit reporter: Reporter): Response[Tree] = {
    ask {
      compiler.askLoadedTyped(source, _)
    }
  }

}