From a3d53243c6ac56d973d437cf16d4d235bb64141b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 16 May 2011 21:08:23 +0000 Subject: This patch and the several to follow represent ... This patch and the several to follow represent an attempt to break up a very large patch from martin which moves much of the compiler's typing infrastructure into the library so that we can utilize the same machinery at runtime that we do at compile time. Said attempt was not very successful, either at maintaining working order while committing incrementally or at subdividing the patch into distinct cohesive units. So let the record show that I tried. -- some notes on the implementation -- This should not be judged as a finished work, but it's a necessary opening step for implementing a reflection API without duplicating much of the compiler. The files in scala.reflect.common are destined for the library (not the compiler, where they are now) but have not yet made the leap to manage compatibility issues. scala.reflect.generic is likely to be replaced by an alias to scala.reflect.common. The fate of scala.reflect.Code and its derived classes is yet to be determined. This first patch contains about the only delta against martin's patch, which is to promote Chars into scala.reflect. Review by odersky. --- src/compiler/scala/reflect/Chars.scala | 92 ++++++++++++++++++++++ src/compiler/scala/tools/nsc/ast/DocComments.scala | 2 +- .../scala/tools/nsc/ast/parser/Scanners.scala | 2 +- .../scala/tools/nsc/ast/parser/Tokens.scala | 2 +- .../scala/tools/nsc/javac/JavaScanners.scala | 2 +- .../scala/tools/nsc/util/CharArrayReader.scala | 2 +- src/compiler/scala/tools/nsc/util/DocStrings.scala | 2 +- .../scala/tools/nsc/util/JavaCharArrayReader.scala | 2 +- src/compiler/scala/tools/nsc/util/SourceFile.scala | 2 +- 9 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 src/compiler/scala/reflect/Chars.scala diff --git a/src/compiler/scala/reflect/Chars.scala b/src/compiler/scala/reflect/Chars.scala new file mode 100644 index 0000000000..739c0ca22b --- /dev/null +++ b/src/compiler/scala/reflect/Chars.scala @@ -0,0 +1,92 @@ +/* NSC -- new Scala compiler + * Copyright 2006-2011 LAMP/EPFL + * @author Martin Odersky + */ +package scala.reflect + +import annotation.{ tailrec, switch } +import java.lang.{ Character => JCharacter } + +/** Contains constants and classifier methods for characters */ +trait Chars { + // Be very careful touching these. + // Apparently trivial changes to the way you write these constants + // will cause Scanners.scala to go from a nice efficient switch to + // a ghastly nested if statement which will bring the type checker + // to its knees. See ticket #1456 + // Martin: (this should be verified now that the pattern rules have been redesigned). + final val LF = '\u000A' + final val FF = '\u000C' + final val CR = '\u000D' + final val SU = '\u001A' + + /** Convert a character digit to an Int according to given base, + * -1 if no success */ + def digit2int(ch: Char, base: Int): Int = { + if ('0' <= ch && ch <= '9' && ch < '0' + base) + ch - '0' + else if ('A' <= ch && ch < 'A' + base - 10) + ch - 'A' + 10 + else if ('a' <= ch && ch < 'a' + base - 10) + ch - 'a' + 10 + else + -1 + } + + /** Convert a character to a backslash-u escape */ + def char2uescape(c: Char): String = { + var rest = c.toInt + val buf = new StringBuilder + for (i <- 1 to 4) { + buf ++= (rest % 16).toHexString + rest = rest / 16 + } + "\\u" + buf.toString.reverse + } + + /** Is character a line break? */ + @inline def isLineBreakChar(c: Char) = (c: @switch) match { + case LF|FF|CR|SU => true + case _ => false + } + + /** Is character a whitespace character (but not a new line)? */ + def isWhitespace(c: Char) = + c == ' ' || c == '\t' || c == CR + + /** Can character form part of a doc comment variable $xxx? */ + def isVarPart(c: Char) = + '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' + + /** Can character start an alphanumeric Scala identifier? */ + def isIdentifierStart(c: Char): Boolean = + (c == '_') || (c == '$') || Character.isUnicodeIdentifierStart(c) + + /** Can character form part of an alphanumeric Scala identifier? */ + def isIdentifierPart(c: Char) = + (c == '$') || Character.isUnicodeIdentifierPart(c) + + /** Is character a math or other symbol in Unicode? */ + def isSpecial(c: Char) = { + val chtp = Character.getType(c) + chtp == Character.MATH_SYMBOL.toInt || chtp == Character.OTHER_SYMBOL.toInt + } + + private final val otherLetters = Set[Char]('\u0024', '\u005F') // '$' and '_' + private final val letterGroups = { + import JCharacter._ + Set[Byte](LOWERCASE_LETTER, UPPERCASE_LETTER, OTHER_LETTER, TITLECASE_LETTER, LETTER_NUMBER) + } + def isScalaLetter(ch: Char) = letterGroups(JCharacter.getType(ch).toByte) || otherLetters(ch) + + /** Can character form part of a Scala operator name? */ + def isOperatorPart(c : Char) : Boolean = (c: @switch) match { + case '~' | '!' | '@' | '#' | '%' | + '^' | '*' | '+' | '-' | '<' | + '>' | '?' | ':' | '=' | '&' | + '|' | '/' | '\\' => true + case c => isSpecial(c) + } +} + +object Chars extends Chars { } diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 5d276e2004..be729904db 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -10,7 +10,7 @@ import symtab._ import reporters.Reporter import util.{Position, NoPosition} import util.DocStrings._ -import util.Chars._ +import scala.reflect.Chars._ import scala.collection.mutable.{HashMap, ListBuffer, StringBuilder} /* diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 3208615757..78bfa1f5ff 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package ast.parser import scala.tools.nsc.util._ -import Chars._ +import scala.reflect.Chars._ import Tokens._ import scala.annotation.switch import scala.collection.mutable.{ ListBuffer, ArrayBuffer } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index e530b725e3..533690fe2e 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -13,7 +13,7 @@ import annotation.switch * identical token sets. */ abstract class Tokens { - import util.Chars._ + import scala.reflect.Chars._ /** special tokens */ final val EMPTY = -3 diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala index ed5ebb1a01..841b28c56f 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala @@ -7,7 +7,7 @@ package scala.tools.nsc package javac import scala.tools.nsc.util._ -import Chars._ +import scala.reflect.Chars._ import JavaTokens._ import scala.annotation.switch diff --git a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala index bdf33476cc..e38f99b42c 100644 --- a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package util -import Chars._ +import scala.reflect.Chars._ abstract class CharArrayReader { self => diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala index ecac4f7755..014c90365c 100755 --- a/src/compiler/scala/tools/nsc/util/DocStrings.scala +++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala @@ -7,7 +7,7 @@ package scala.tools.nsc package util -import Chars._ +import scala.reflect.Chars._ import scala.collection.mutable.{HashMap, ListBuffer, StringBuilder} /** Utilitity methods for doc comment strings diff --git a/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala b/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala index f27d25d1b0..98ec4dc29b 100644 --- a/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package util -import Chars._ +import scala.reflect.Chars._ class JavaCharArrayReader(buf: IndexedSeq[Char], start: Int, /* startline: int, startcol: int, */ decodeUni: Boolean, error: String => Unit) extends Iterator[Char] with Cloneable { diff --git a/src/compiler/scala/tools/nsc/util/SourceFile.scala b/src/compiler/scala/tools/nsc/util/SourceFile.scala index 90a9057f01..5ab4a5cee3 100644 --- a/src/compiler/scala/tools/nsc/util/SourceFile.scala +++ b/src/compiler/scala/tools/nsc/util/SourceFile.scala @@ -12,7 +12,7 @@ import scala.collection.mutable.ArrayBuffer import annotation.tailrec import java.util.regex.Pattern import java.io.IOException -import Chars._ +import scala.reflect.Chars._ /** abstract base class of a source file used in the compiler */ abstract class SourceFile { -- cgit v1.2.3