summaryrefslogtreecommitdiff
path: root/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-03-06 07:39:19 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-03-09 11:59:07 -0800
commitc6ca941ccc017a8869f4def717cfeb640f965077 (patch)
treee21038cc55d3a4231544d148913504a754eafdf8 /src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala
parent9094822181c398b945b7f30ac1e2b05da9796f53 (diff)
downloadscala-c6ca941ccc017a8869f4def717cfeb640f965077.tar.gz
scala-c6ca941ccc017a8869f4def717cfeb640f965077.tar.bz2
scala-c6ca941ccc017a8869f4def717cfeb640f965077.zip
Moved scaladoc sources into separate directory.
This change is not externally visible. It moves the scaladoc sources into src/scaladoc and adds an ant target for building them. The compilation products are still packaged into scala-compiler.jar as before, but with a small change to build.xml a separate jar can be created instead.
Diffstat (limited to 'src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala')
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala
new file mode 100644
index 0000000000..5781e680dd
--- /dev/null
+++ b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala
@@ -0,0 +1,286 @@
+/* NSC -- new Scala compiler
+ * Copyright 2010-2013 LAMP/EPFL
+ * @author Stephane Micheloud
+ */
+
+package scala.tools.nsc.doc.html
+
+import scala.xml.NodeSeq
+
+/** Highlight the syntax of Scala code appearing in a `{{{` wiki block
+ * (see method `HtmlPage.blockToHtml`).
+ *
+ * @author Stephane Micheloud
+ * @version 1.0
+ */
+private[html] object SyntaxHigh {
+
+ /** Reserved words, sorted alphabetically
+ * (see [[scala.reflect.internal.StdNames]]) */
+ val reserved = Array(
+ "abstract", "case", "catch", "class", "def",
+ "do", "else", "extends", "false", "final", "finally",
+ "for", "if", "implicit", "import", "lazy", "match",
+ "new", "null", "object", "override", "package",
+ "private", "protected", "return", "sealed", "super",
+ "this", "throw", "trait", "true", "try", "type",
+ "val", "var", "while", "with", "yield")
+
+ /** Annotations, sorted alphabetically */
+ val annotations = Array(
+ "BeanProperty", "SerialVersionUID",
+ "beanGetter", "beanSetter", "bridge",
+ "deprecated", "deprecatedName", "deprecatedOverriding", "deprecatedInheritance",
+ "elidable", "field", "getter", "inline",
+ "migration", "native", "noinline", "param",
+ "remote", "setter", "specialized", "strictfp", "switch",
+ "tailrec", "throws", "transient",
+ "unchecked", "uncheckedStable", "uncheckedVariance",
+ "varargs", "volatile")
+
+ /** Standard library classes/objects, sorted alphabetically */
+ val standards = Array (
+ "WeakTypeTag", "Any", "AnyRef", "AnyVal", "App", "Array",
+ "Boolean", "Byte", "Char", "Class", "ClassTag", "ClassManifest",
+ "Console", "Double", "Enumeration", "Float", "Function", "Int",
+ "List", "Long", "Manifest", "Map",
+ "NoManifest", "None", "Nothing", "Null", "Object", "Option", "OptManifest",
+ "Pair", "Predef",
+ "Seq", "Set", "Short", "Some", "String", "Symbol",
+ "Triple", "TypeTag", "Unit")
+
+ def apply(data: String): NodeSeq = {
+ val buf = data.getBytes
+ val out = new StringBuilder
+
+ def compare(offset: Int, key: String): Int = {
+ var i = offset
+ var j = 0
+ val l = key.length
+ while (i < buf.length && j < l) {
+ val bch = buf(i).toChar
+ val kch = key charAt j
+ if (bch < kch) return -1
+ else if (bch > kch) return 1
+ i += 1
+ j += 1
+ }
+ if (j < l) -1
+ else if (i < buf.length &&
+ ('A' <= buf(i) && buf(i) <= 'Z' ||
+ 'a' <= buf(i) && buf(i) <= 'z' ||
+ '0' <= buf(i) && buf(i) <= '9' ||
+ buf(i) == '_')) 1
+ else 0
+ }
+
+ def lookup(a: Array[String], i: Int): Int = {
+ var lo = 0
+ var hi = a.length - 1
+ while (lo <= hi) {
+ val m = (hi + lo) / 2
+ val d = compare(i, a(m))
+ if (d < 0) hi = m - 1
+ else if (d > 0) lo = m + 1
+ else return m
+ }
+ -1
+ }
+
+ def comment(i: Int): String = {
+ val out = new StringBuilder("/")
+ def line(i: Int): Int =
+ if (i == buf.length || buf(i) == '\n') i
+ else {
+ out append buf(i).toChar
+ line(i+1)
+ }
+ var level = 0
+ def multiline(i: Int, star: Boolean): Int = {
+ if (i == buf.length) return i
+ val ch = buf(i).toChar
+ out append ch
+ ch match {
+ case '*' =>
+ if (star) level += 1
+ multiline(i+1, !star)
+ case '/' =>
+ if (star) {
+ if (level > 0) level -= 1
+ if (level == 0) i else multiline(i+1, star = true)
+ } else
+ multiline(i+1, star = false)
+ case _ =>
+ multiline(i+1, star = false)
+ }
+ }
+ if (buf(i) == '/') line(i) else multiline(i, star = true)
+ out.toString
+ }
+
+ /* e.g. `val endOfLine = '\u000A'`*/
+ def charlit(j: Int): String = {
+ val out = new StringBuilder("'")
+ def charlit0(i: Int, bslash: Boolean): Int = {
+ if (i == buf.length) i
+ else if (i > j+6) { out setLength 0; j }
+ else {
+ val ch = buf(i).toChar
+ out append ch
+ ch match {
+ case '\\' =>
+ charlit0(i+1, bslash = true)
+ case '\'' if !bslash =>
+ i
+ case _ =>
+ if (bslash && '0' <= ch && ch <= '9') charlit0(i+1, bslash = true)
+ else charlit0(i+1, bslash = false)
+ }
+ }
+ }
+ charlit0(j, bslash = false)
+ out.toString
+ }
+
+ def strlit(i: Int): String = {
+ val out = new StringBuilder("\"")
+ def strlit0(i: Int, bslash: Boolean): Int = {
+ if (i == buf.length) return i
+ val ch = buf(i).toChar
+ out append ch
+ ch match {
+ case '\\' =>
+ strlit0(i+1, bslash = true)
+ case '"' if !bslash =>
+ i
+ case _ =>
+ strlit0(i+1, bslash = false)
+ }
+ }
+ strlit0(i, bslash = false)
+ out.toString
+ }
+
+ def numlit(i: Int): String = {
+ val out = new StringBuilder
+ def intg(i: Int): Int = {
+ if (i == buf.length) return i
+ val ch = buf(i).toChar
+ ch match {
+ case '.' =>
+ out append ch
+ frac(i+1)
+ case _ =>
+ if (Character.isDigit(ch)) {
+ out append ch
+ intg(i+1)
+ } else i
+ }
+ }
+ def frac(i: Int): Int = {
+ if (i == buf.length) return i
+ val ch = buf(i).toChar
+ ch match {
+ case 'e' | 'E' =>
+ out append ch
+ expo(i+1, signed = false)
+ case _ =>
+ if (Character.isDigit(ch)) {
+ out append ch
+ frac(i+1)
+ } else i
+ }
+ }
+ def expo(i: Int, signed: Boolean): Int = {
+ if (i == buf.length) return i
+ val ch = buf(i).toChar
+ ch match {
+ case '+' | '-' if !signed =>
+ out append ch
+ expo(i+1, signed = true)
+ case _ =>
+ if (Character.isDigit(ch)) {
+ out append ch
+ expo(i+1, signed)
+ } else i
+ }
+ }
+ intg(i)
+ out.toString
+ }
+
+ def parse(pre: String, i: Int): Int = {
+ out append pre
+ if (i == buf.length) return i
+ buf(i) match {
+ case '\n' =>
+ parse("\n", i+1)
+ case ' ' =>
+ parse(" ", i+1)
+ case '&' =>
+ parse("&amp;", i+1)
+ case '<' if i+1 < buf.length =>
+ val ch = buf(i+1).toChar
+ if (ch == '-' || ch == ':' || ch == '%')
+ parse("<span class=\"kw\">&lt;"+ch+"</span>", i+2)
+ else
+ parse("&lt;", i+1)
+ case '>' =>
+ if (i+1 < buf.length && buf(i+1) == ':')
+ parse("<span class=\"kw\">&gt;:</span>", i+2)
+ else
+ parse("&gt;", i+1)
+ case '=' =>
+ if (i+1 < buf.length && buf(i+1) == '>')
+ parse("<span class=\"kw\">=&gt;</span>", i+2)
+ else
+ parse(buf(i).toChar.toString, i+1)
+ case '/' =>
+ if (i+1 < buf.length && (buf(i+1) == '/' || buf(i+1) == '*')) {
+ val c = comment(i+1)
+ parse("<span class=\"cmt\">"+c+"</span>", i+c.length)
+ } else
+ parse(buf(i).toChar.toString, i+1)
+ case '\'' =>
+ val s = charlit(i+1)
+ if (s.length > 0)
+ parse("<span class=\"lit\">"+s+"</span>", i+s.length)
+ else
+ parse(buf(i).toChar.toString, i+1)
+ case '"' =>
+ val s = strlit(i+1)
+ parse("<span class=\"lit\">"+s+"</span>", i+s.length)
+ case '@' =>
+ val k = lookup(annotations, i+1)
+ if (k >= 0)
+ parse("<span class=\"ano\">@"+annotations(k)+"</span>", i+annotations(k).length+1)
+ else
+ parse(buf(i).toChar.toString, i+1)
+ case _ =>
+ if (i == 0 || (i >= 1 && !Character.isJavaIdentifierPart(buf(i-1).toChar))) {
+ if (Character.isDigit(buf(i)) ||
+ (buf(i) == '.' && i + 1 < buf.length && Character.isDigit(buf(i+1)))) {
+ val s = numlit(i)
+ parse("<span class=\"num\">"+s+"</span>", i+s.length)
+ } else {
+ val k = lookup(reserved, i)
+ if (k >= 0)
+ parse("<span class=\"kw\">"+reserved(k)+"</span>", i+reserved(k).length)
+ else {
+ val k = lookup(standards, i)
+ if (k >= 0)
+ parse("<span class=\"std\">"+standards(k)+"</span>", i+standards(k).length)
+ else
+ parse(buf(i).toChar.toString, i+1)
+ }
+ }
+ } else
+ parse(buf(i).toChar.toString, i+1)
+ }
+ i
+ }
+
+ parse("", 0)
+ scala.xml.Unparsed(out.toString)
+ }
+}