src/Pure/PIDE/command_span.scala
author wenzelm
Thu, 12 Mar 2015 16:47:47 +0100
changeset 59683 d6824d8490be
parent 58802 3cc68ec558b0
child 59684 86a76300137e
permissions -rw-r--r--
tuned -- more uniform ML vs. Scala;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/PIDE/command_span.scala
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     3
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     4
Syntactic representation of command spans.
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     5
*/
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     6
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     7
package isabelle
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     8
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
     9
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    10
import scala.collection.mutable
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    11
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    12
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    13
object Command_Span
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    14
{
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    15
  sealed abstract class Kind {
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    16
    override def toString: String =
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    17
      this match {
57910
a50837b637dc maintain Command_Range position as in ML;
wenzelm
parents: 57905
diff changeset
    18
        case Command_Span(name, _) => if (name != "") name else "<command>"
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    19
        case Ignored_Span => "<ignored>"
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    20
        case Malformed_Span => "<malformed>"
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    21
      }
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    22
  }
57910
a50837b637dc maintain Command_Range position as in ML;
wenzelm
parents: 57905
diff changeset
    23
  case class Command_Span(name: String, pos: Position.T) extends Kind
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    24
  case object Ignored_Span extends Kind
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    25
  case object Malformed_Span extends Kind
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    26
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    27
  sealed case class Span(kind: Kind, content: List[Token])
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    28
  {
58802
3cc68ec558b0 find command span in buffer;
wenzelm
parents: 57910
diff changeset
    29
    def length: Int = (0 /: content)(_ + _.source.length)
3cc68ec558b0 find command span in buffer;
wenzelm
parents: 57910
diff changeset
    30
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    31
    def compact_source: (String, Span) =
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    32
    {
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    33
      val source: String =
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    34
        content match {
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    35
          case List(tok) => tok.source
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    36
          case toks => toks.map(_.source).mkString
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    37
        }
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    38
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    39
      val content1 = new mutable.ListBuffer[Token]
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    40
      var i = 0
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    41
      for (Token(kind, s) <- content) {
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    42
        val n = s.length
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    43
        val s1 = source.substring(i, i + n)
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    44
        content1 += Token(kind, s1)
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    45
        i += n
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    46
      }
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    47
      (source, Span(kind, content1.toList))
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    48
    }
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    49
  }
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    50
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    51
  val empty: Span = Span(Ignored_Span, Nil)
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    52
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    53
  def unparsed(source: String): Span =
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    54
    Span(Malformed_Span, List(Token(Token.Kind.UNPARSED, source)))
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    55
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    56
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    57
  /* resolve inlined files */
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    58
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    59
  private def clean_tokens(tokens: List[Token]): List[(Token, Int)] =
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    60
  {
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    61
    def clean(toks: List[(Token, Int)]): List[(Token, Int)] =
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    62
      toks match {
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    63
        case (t1, i1) :: (t2, i2) :: rest =>
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    64
          if (t1.is_keyword && (t1.source == "%" || t1.source == "--")) clean(rest)
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    65
          else (t1, i1) :: clean((t2, i2) :: rest)
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    66
        case _ => toks
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    67
      }
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    68
    clean(tokens.zipWithIndex.filter({ case (t, _) => t.is_proper }))
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    69
  }
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    70
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    71
  private def find_file(tokens: List[(Token, Int)]): Option[(String, Int)] =
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    72
    tokens match {
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    73
      case (tok, _) :: toks =>
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    74
        if (tok.is_command)
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    75
          toks.collectFirst({ case (t, i) if t.is_name => (t.content, i) })
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    76
        else None
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    77
      case Nil => None
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    78
    }
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    79
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    80
  def span_files(syntax: Prover.Syntax, span: Span): (List[String], Int) =
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    81
    span.kind match {
57910
a50837b637dc maintain Command_Range position as in ML;
wenzelm
parents: 57905
diff changeset
    82
      case Command_Span(name, _) =>
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    83
        syntax.load_command(name) match {
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    84
          case Some(exts) =>
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    85
            find_file(clean_tokens(span.content)) match {
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    86
              case Some((file, i)) =>
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    87
                if (exts.isEmpty) (List(file), i)
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    88
                else (exts.map(ext => file + "." + ext), i)
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    89
              case None => (Nil, -1)
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    90
            }
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    91
          case None => (Nil, -1)
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    92
        }
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
    93
      case _ => (Nil, -1)
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    94
    }
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    95
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    96
  def resolve_files(
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    97
      resources: Resources,
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    98
      syntax: Prover.Syntax,
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
    99
      node_name: Document.Node.Name,
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   100
      span: Span,
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   101
      get_blob: Document.Node.Name => Option[Document.Blob])
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   102
    : List[Command.Blob] =
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   103
  {
59683
d6824d8490be tuned -- more uniform ML vs. Scala;
wenzelm
parents: 58802
diff changeset
   104
    span_files(syntax, span)._1.map(file_name =>
57905
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   105
      Exn.capture {
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   106
        val name =
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   107
          Document.Node.Name(resources.append(node_name.master_dir, Path.explode(file_name)))
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   108
        val blob = get_blob(name).map(blob => ((blob.bytes.sha1_digest, blob.chunk)))
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   109
        (name, blob)
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   110
      })
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   111
  }
c0c5652e796e separate module Command_Span: mostly syntactic representation;
wenzelm
parents:
diff changeset
   112
}