summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/util/SourceFile.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/util/SourceFile.scala')
-rw-r--r--src/compiler/scala/tools/nsc/util/SourceFile.scala136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/util/SourceFile.scala b/src/compiler/scala/tools/nsc/util/SourceFile.scala
new file mode 100644
index 0000000000..0d4354d325
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/util/SourceFile.scala
@@ -0,0 +1,136 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala.tools.nsc.util;
+import scala.tools.util.AbstractFile;
+import scala.tools.util.CharArrayFile;
+
+/** Uses positions that are offsets rather than line/column pairs.
+ *
+ * @author Sean McDirmid
+ */
+object SourceFile {
+ val LF : Char = 0x0A;
+ val FF : Char = 0x0C;
+ val CR : Char = 0x0D;
+ val SU : Char = 0x1A;
+ def isLineBreak(c : Char) = c == LF || c == FF || c == CR || c == SU;
+}
+
+
+class SourceFile(_file : AbstractFile, _content : Array[Char]) {
+ import SourceFile._;
+
+
+ val file = _file;
+ val content = normalize(_content);
+
+ def getContent() = content;
+
+ def getFile() = file;
+
+ def this(sourceName: String, content : Array[Char]) =
+ this(new CharArrayFile(sourceName, content), content);
+
+ def isLineBreak(idx : Int) = if (!SourceFile.isLineBreak(content(idx))) false;
+ else if (content(idx) == CR && idx + 1 < content.length && content(idx + 1) == LF) false;
+ else true;
+
+
+ def position(offset : Int) = new Position(this, offset);
+ def position(line : Int, column : Int) = new Position(this, lineToOffset(line) + column);
+
+ // constants
+
+ // NOTE: all indexes are based on zero!!!!
+ override def toString(): String = file.getName() /* + ":" + content.length */ ;
+
+
+ def dbg(offset : Int) = (new Position(this, offset)).dbgString;
+
+
+ object line {
+ var index = 0;
+ var offset = 0;
+
+ def find(toFind : Int, isIndex : Boolean) : Int = {
+ if (toFind == 0) return 0;
+
+ if (!isIndex) assert(toFind != Position.NOPOS);
+ if ( isIndex) assert(toFind > Position.NOLINE - Position.FIRSTLINE);
+
+ if (!isIndex && (toFind >= content.length)) throw new Error(toFind + " not valid offset in " + file.getName() + ":" + content.length);
+
+ def get(isIndex : Boolean) = if (isIndex) index else offset;
+
+ val isBackward = toFind <= get(isIndex);
+ val increment = if (isBackward) -1 else + 1;
+ val oneIfBackward = if (isBackward) +1 else 0;
+
+ // System.err.println("FIND-0: " + toFind + " " + isIndex);
+
+ while (true) {
+ // System.err.println("FIND-1: " + offset + " " + index);
+
+ if (!isIndex && offset == toFind) return index;
+ if ( isBackward && offset <= 0) throw new Error(offset + " " + index + " " + toFind + " " + isIndex);
+ offset = offset + increment;
+ if (!isBackward) assert(offset < content.length);
+
+ if (isLineBreak(offset + (if (isBackward) 0 else -1))) {
+ index = index + increment;
+ if (isIndex && index + oneIfBackward == toFind)
+ return offset + oneIfBackward;
+ }
+ }
+ throw new Error();
+ }
+ }
+ def offsetToLine(offset : Int) : Int = line.find(offset, false);
+ def lineToOffset(index : Int) : Int = line.find(index , true);
+
+ def beginsWith(offset : Int, text : String): Boolean = {
+ var idx = 0;
+ while (idx < text.length()) {
+ if (offset + idx >= content.length) return false;
+ if (content(offset + idx) != text.charAt(idx)) return false;
+ idx = idx + 1;
+ }
+ return true;
+ }
+ def path = getFile().getPath();
+
+ def skipWhitespace(offset : Int): Int =
+ if (Character.isWhitespace(content(offset))) skipWhitespace(offset + 1) else offset;
+
+
+ def lineToString(index : Int) = {
+ var offset = lineToOffset(index);
+ val buf = new StringBuffer();
+ while (!isLineBreak(offset) && offset < content.length) {
+ buf.append(content(offset));
+ offset = offset + 1;
+ }
+ buf.toString();
+ }
+
+
+ private def normalize(input : Array[char]): Array[char] =
+ if (input.length > 0 && input(input.length - 1) == SU) input;
+ else {
+ val content = new Array[char](input.length + 1);
+ System.arraycopy(input, 0, content, 0, input.length);
+ content(input.length) = SU;
+ content;
+ }
+
+
+
+
+}