From ba82b29b929f47ae345dbd32e5b6200bf68c231e Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 27 Jan 2011 20:25:26 +0000 Subject: Primarily a cleanup of the organization of keyw... Primarily a cleanup of the organization of keywords for the scala and java parsers, and a few other Name-related items. No review. --- .../scala/tools/nsc/ast/parser/Scanners.scala | 162 ++++++------ .../scala/tools/nsc/ast/parser/Tokens.scala | 1 - .../scala/tools/nsc/javac/JavaScanners.scala | 292 ++++++++++----------- .../scala/tools/nsc/symtab/NameManglers.scala | 43 ++- src/compiler/scala/tools/nsc/symtab/Names.scala | 2 + src/compiler/scala/tools/nsc/symtab/StdNames.scala | 207 ++++++++++----- src/compiler/scala/tools/nsc/symtab/Symbols.scala | 4 +- .../scala/tools/nsc/symtab/classfile/Pickler.scala | 5 +- 8 files changed, 398 insertions(+), 318 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index b791d10c93..3208615757 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -29,6 +29,16 @@ trait ScannersCommon { def error (off: Int, msg: String): Unit def incompleteInputError(off: Int, msg: String): Unit } + + def createKeywordArray(keywords: Seq[(Name, Int)], defaultToken: Int): (Int, Array[Int]) = { + val names = keywords sortBy (_._1.start) map { case (k, v) => (k.start, v) } + val low = names.head._1 + val high = names.last._1 + val arr = Array.fill(high - low + 1)(defaultToken) + + names foreach { case (k, v) => arr(k + low) = v } + (low, arr) + } } trait Scanners extends ScannersCommon { @@ -908,92 +918,74 @@ trait Scanners extends ScannersCommon { // ------------- keyword configuration ----------------------------------- - /** Keyword array; maps from name indices to tokens */ - private var keyCode: Array[Byte] = _ - /** The highest name index of a keyword token */ - private var maxKey = 0 - /** An array of all keyword token names */ - private var keyName = new Array[TermName](128) - /** The highest keyword token plus one */ - private var tokenCount = 0 - - /** Enter keyword with given name and token id */ - protected def enterKeyword(n: TermName, tokenId: Int) { - while (tokenId >= keyName.length) { - val newTokName = new Array[TermName](keyName.length * 2) - compat.Platform.arraycopy(keyName, 0, newTokName, 0, newTokName.length) - keyName = newTokName - } - keyName(tokenId) = n - if (n.start > maxKey) maxKey = n.start - if (tokenId >= tokenCount) tokenCount = tokenId + 1 + private val allKeywords = List[(Name, Int)]( + nme.ABSTRACTkw -> ABSTRACT, + nme.CASEkw -> CASE, + nme.CATCHkw -> CATCH, + nme.CLASSkw -> CLASS, + nme.DEFkw -> DEF, + nme.DOkw -> DO, + nme.ELSEkw -> ELSE, + nme.EXTENDSkw -> EXTENDS, + nme.FALSEkw -> FALSE, + nme.FINALkw -> FINAL, + nme.FINALLYkw -> FINALLY, + nme.FORkw -> FOR, + nme.FORSOMEkw -> FORSOME, + nme.IFkw -> IF, + nme.IMPLICITkw -> IMPLICIT, + nme.IMPORTkw -> IMPORT, + nme.LAZYkw -> LAZY, + nme.MATCHkw -> MATCH, + nme.NEWkw -> NEW, + nme.NULLkw -> NULL, + nme.OBJECTkw -> OBJECT, + nme.OVERRIDEkw -> OVERRIDE, + nme.PACKAGEkw -> PACKAGE, + nme.PRIVATEkw -> PRIVATE, + nme.PROTECTEDkw -> PROTECTED, + nme.RETURNkw -> RETURN, + nme.SEALEDkw -> SEALED, + nme.SUPERkw -> SUPER, + nme.THISkw -> THIS, + nme.THROWkw -> THROW, + nme.TRAITkw -> TRAIT, + nme.TRUEkw -> TRUE, + nme.TRYkw -> TRY, + nme.TYPEkw -> TYPE, + nme.VALkw -> VAL, + nme.VARkw -> VAR, + nme.WHILEkw -> WHILE, + nme.WITHkw -> WITH, + nme.YIELDkw -> YIELD, + nme.DOTkw -> DOT, + nme.USCOREkw -> USCORE, + nme.COLONkw -> COLON, + nme.EQUALSkw -> EQUALS, + nme.ARROWkw -> ARROW, + nme.LARROWkw -> LARROW, + nme.SUBTYPEkw -> SUBTYPE, + nme.VIEWBOUNDkw -> VIEWBOUND, + nme.SUPERTYPEkw -> SUPERTYPE, + nme.HASHkw -> HASH, + nme.ATkw -> AT + ) + + private var kwOffset: Int = -1 + private val kwArray: Array[Int] = { + val (offset, arr) = createKeywordArray(allKeywords, IDENTIFIER) + kwOffset = offset + arr } - /** Enter all keywords */ - protected def enterKeywords() { - enterKeyword(nme.ABSTRACTkw, ABSTRACT) - enterKeyword(nme.CASEkw, CASE) - enterKeyword(nme.CATCHkw, CATCH) - enterKeyword(nme.CLASSkw, CLASS) - enterKeyword(nme.DEFkw, DEF) - enterKeyword(nme.DOkw, DO) - enterKeyword(nme.ELSEkw, ELSE) - enterKeyword(nme.EXTENDSkw, EXTENDS) - enterKeyword(nme.FALSEkw, FALSE) - enterKeyword(nme.FINALkw, FINAL) - enterKeyword(nme.FINALLYkw, FINALLY) - enterKeyword(nme.FORkw, FOR) - enterKeyword(nme.FORSOMEkw, FORSOME) - enterKeyword(nme.IFkw, IF) - enterKeyword(nme.IMPLICITkw, IMPLICIT) - enterKeyword(nme.IMPORTkw, IMPORT) - enterKeyword(nme.LAZYkw, LAZY) - enterKeyword(nme.MATCHkw, MATCH) - enterKeyword(nme.NEWkw, NEW) - enterKeyword(nme.NULLkw, NULL) - enterKeyword(nme.OBJECTkw, OBJECT) - enterKeyword(nme.OVERRIDEkw, OVERRIDE) - enterKeyword(nme.PACKAGEkw, PACKAGE) - enterKeyword(nme.PRIVATEkw, PRIVATE) - enterKeyword(nme.PROTECTEDkw, PROTECTED) - enterKeyword(nme.RETURNkw, RETURN) - enterKeyword(nme.SEALEDkw, SEALED) - enterKeyword(nme.SUPERkw, SUPER) - enterKeyword(nme.THISkw, THIS) - enterKeyword(nme.THROWkw, THROW) - enterKeyword(nme.TRAITkw, TRAIT) - enterKeyword(nme.TRUEkw, TRUE) - enterKeyword(nme.TRYkw, TRY) - enterKeyword(nme.TYPEkw, TYPE) - enterKeyword(nme.VALkw, VAL) - enterKeyword(nme.VARkw, VAR) - enterKeyword(nme.WHILEkw, WHILE) - enterKeyword(nme.WITHkw, WITH) - enterKeyword(nme.YIELDkw, YIELD) - enterKeyword(nme.DOTkw, DOT) - enterKeyword(nme.USCOREkw, USCORE) - enterKeyword(nme.COLONkw, COLON) - enterKeyword(nme.EQUALSkw, EQUALS) - enterKeyword(nme.ARROWkw, ARROW) - enterKeyword(nme.LARROWkw, LARROW) - enterKeyword(nme.SUBTYPEkw, SUBTYPE) - enterKeyword(nme.VIEWBOUNDkw, VIEWBOUND) - enterKeyword(nme.SUPERTYPEkw, SUPERTYPE) - enterKeyword(nme.HASHkw, HASH) - enterKeyword(nme.ATkw, AT) - } - - { // initialization - enterKeywords() - // Build keyword array - keyCode = Array.fill(maxKey + 1)(IDENTIFIER) - for (j <- 0 until tokenCount if keyName(j) ne null) - keyCode(keyName(j).start) = j.toByte - } + final val token2name = allKeywords map (_.swap) toMap /** Convert name to token */ - def name2token(name: Name): Int = - if (name.start <= maxKey) keyCode(name.start) else IDENTIFIER + final def name2token(name: Name) = { + val idx = name.start - kwOffset + if (idx >= 0 && idx < kwArray.length) kwArray(idx) + else IDENTIFIER + } // Token representation ---------------------------------------------------- @@ -1023,8 +1015,10 @@ trait Scanners extends ScannersCommon { case CASEOBJECT => "case object" case XMLSTART => "$XMLSTART$<" case _ => - if (token <= maxKey) "'" + keyName(token) + "'" - else "'<" + token + ">'" + (token2name get token) match { + case Some(name) => "'" + name + "'" + case _ => "'<" + token + ">'" + } } class MalformedInput(val offset: Int, val msg: String) extends Exception diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index edc48e2ce9..e530b725e3 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -105,7 +105,6 @@ object Tokens extends Tokens { final val RETURN = 57 final val MATCH = 58 final val FORSOME = 59 - final val REQUIRES = 60 final val LAZY = 61 def isKeyword(code : Int) = diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala index 90503480cc..3de17d6b56 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala @@ -77,170 +77,144 @@ trait JavaScanners extends ast.parser.ScannersCommon { object JavaScannerConfiguration { // Keywords ----------------------------------------------------------------- - /** Keyword array; maps from name indices to tokens */ - private var key: Array[Byte] = _ - private var maxKey = 0 - private var tokenName = new Array[Name](128) - - { - var tokenCount = 0 - - // Enter keywords - - def enterKeyword(s: String, tokenId: Int) { - val n = newTermName(s) - while (tokenId >= tokenName.length) { - val newTokName = new Array[Name](tokenName.length * 2) - Array.copy(tokenName, 0, newTokName, 0, newTokName.length) - tokenName = newTokName - } - tokenName(tokenId) = n - if (n.start > maxKey) maxKey = n.start - if (tokenId >= tokenCount) tokenCount = tokenId + 1 - } - - enterKeyword("abstract", ABSTRACT) - enterKeyword("assert", ASSERT) - enterKeyword("boolean", BOOLEAN) - enterKeyword("break", BREAK) - enterKeyword("byte", BYTE) - enterKeyword("case", CASE) - enterKeyword("catch", CATCH) - enterKeyword("char", CHAR) - enterKeyword("class", CLASS) - enterKeyword("const", CONST) - enterKeyword("continue", CONTINUE) - enterKeyword("default", DEFAULT) - enterKeyword("do", DO) - enterKeyword("double", DOUBLE) - enterKeyword("else", ELSE) - enterKeyword("enum", ENUM) - enterKeyword("extends", EXTENDS) - enterKeyword("final", FINAL) - enterKeyword("finally", FINALLY) - enterKeyword("float", FLOAT) - enterKeyword("for", FOR) - enterKeyword("if", IF) - enterKeyword("goto", GOTO) - enterKeyword("implements", IMPLEMENTS) - enterKeyword("import", IMPORT) - enterKeyword("instanceof", INSTANCEOF) - enterKeyword("int", INT) - enterKeyword("interface", INTERFACE) - enterKeyword("long", LONG) - enterKeyword("native", NATIVE) - enterKeyword("new", NEW) - enterKeyword("package", PACKAGE) - enterKeyword("private", PRIVATE) - enterKeyword("protected", PROTECTED) - enterKeyword("public", PUBLIC) - enterKeyword("return", RETURN) - enterKeyword("short", SHORT) - enterKeyword("static", STATIC) - enterKeyword("strictfp", STRICTFP) - enterKeyword("super", SUPER) - enterKeyword("switch", SWITCH) - enterKeyword("synchronized", SYNCHRONIZED) - enterKeyword("this", THIS) - enterKeyword("throw", THROW) - enterKeyword("throws", THROWS) - enterKeyword("transient", TRANSIENT) - enterKeyword("try", TRY) - enterKeyword("void", VOID) - enterKeyword("volatile", VOLATILE) - enterKeyword("while", WHILE) - - // Build keyword array - key = new Array[Byte](maxKey + 1) - for (i <- 0 to maxKey) - key(i) = IDENTIFIER - for (j <- 0 until tokenCount) - if (tokenName(j) ne null) - key(tokenName(j).start) = j.toByte + private val allKeywords = List[(Name, Int)]( + javanme.ABSTRACTkw -> ABSTRACT, + javanme.ASSERTkw -> ASSERT, + javanme.BOOLEANkw -> BOOLEAN, + javanme.BREAKkw -> BREAK, + javanme.BYTEkw -> BYTE, + javanme.CASEkw -> CASE, + javanme.CATCHkw -> CATCH, + javanme.CHARkw -> CHAR, + javanme.CLASSkw -> CLASS, + javanme.CONSTkw -> CONST, + javanme.CONTINUEkw -> CONTINUE, + javanme.DEFAULTkw -> DEFAULT, + javanme.DOkw -> DO, + javanme.DOUBLEkw -> DOUBLE, + javanme.ELSEkw -> ELSE, + javanme.ENUMkw -> ENUM, + javanme.EXTENDSkw -> EXTENDS, + javanme.FINALkw -> FINAL, + javanme.FINALLYkw -> FINALLY, + javanme.FLOATkw -> FLOAT, + javanme.FORkw -> FOR, + javanme.IFkw -> IF, + javanme.GOTOkw -> GOTO, + javanme.IMPLEMENTSkw -> IMPLEMENTS, + javanme.IMPORTkw -> IMPORT, + javanme.INSTANCEOFkw -> INSTANCEOF, + javanme.INTkw -> INT, + javanme.INTERFACEkw -> INTERFACE, + javanme.LONGkw -> LONG, + javanme.NATIVEkw -> NATIVE, + javanme.NEWkw -> NEW, + javanme.PACKAGEkw -> PACKAGE, + javanme.PRIVATEkw -> PRIVATE, + javanme.PROTECTEDkw -> PROTECTED, + javanme.PUBLICkw -> PUBLIC, + javanme.RETURNkw -> RETURN, + javanme.SHORTkw -> SHORT, + javanme.STATICkw -> STATIC, + javanme.STRICTFPkw -> STRICTFP, + javanme.SUPERkw -> SUPER, + javanme.SWITCHkw -> SWITCH, + javanme.SYNCHRONIZEDkw -> SYNCHRONIZED, + javanme.THISkw -> THIS, + javanme.THROWkw -> THROW, + javanme.THROWSkw -> THROWS, + javanme.TRANSIENTkw -> TRANSIENT, + javanme.TRYkw -> TRY, + javanme.VOIDkw -> VOID, + javanme.VOLATILEkw -> VOLATILE, + javanme.WHILEkw -> WHILE + ) + + private var kwOffset = -1 + private val kwArray: Array[Int] = { + val (offset, arr) = createKeywordArray(allKeywords, IDENTIFIER) + kwOffset = offset + arr } + final val tokenName = allKeywords map (_.swap) toMap //Token representation ----------------------------------------------------- - /** Convert name to token */ - def name2token(name: TermName): Int = - if (name.start <= maxKey) key(name.start) else IDENTIFIER - - /** Returns the string representation of given token. */ - def token2string(token: Int): String = token match { - case IDENTIFIER => - "identifier"/* + \""+name+"\""*/ - case CHARLIT => - "character literal" - case INTLIT => - "integer literal" - case LONGLIT => - "long literal" - case FLOATLIT => - "float literal" - case DOUBLELIT => - "double literal" - case STRINGLIT => - "string literal" - case COMMA => "`,'" - case SEMI => "`;'" - case DOT => "`.'" - case AT => "`@'" - case COLON => "`:'" - case ASSIGN => "`='" - case EQEQ => "`=='" - case BANGEQ => "`!='" - case LT => "`<'" - case GT => "`>'" - case LTEQ => "`<='" - case GTEQ => "`>='" - case BANG => "`!'" - case QMARK => "`?'" - case AMP => "`&'" - case BAR => "`|'" - case PLUS => "`+'" - case MINUS => "`-'" - case ASTERISK => "`*'" - case SLASH => "`/'" - case PERCENT => "`%'" - case HAT => "`^'" - case LTLT => "`<<'" - case GTGT => "`>>'" - case GTGTGT => "`>>>'" - case AMPAMP => "`&&'" - case BARBAR => "`||'" - case PLUSPLUS => "`++'" - case MINUSMINUS => "`--'" - case TILDE => "`~'" - case DOTDOTDOT => "`...'" - case AMPEQ => "`&='" - case BAREQ => "`|='" - case PLUSEQ => "`+='" - case MINUSEQ => "`-='" - case ASTERISKEQ => "`*='" - case SLASHEQ => "`/='" - case PERCENTEQ => "`%='" - case HATEQ => "`^='" - case LTLTEQ => "`<<='" - case GTGTEQ => "`>>='" - case GTGTGTEQ => "`>>>='" - case LPAREN => "`('" - case RPAREN => "`)'" - case LBRACE => "`{'" - case RBRACE => "`}'" - case LBRACKET => "`['" - case RBRACKET => "`]'" - case EOF => "eof" - case ERROR => "something" - case _ => - try { - "`" + tokenName(token) + "'" - } catch { - case _: ArrayIndexOutOfBoundsException => - "`<" + token + ">'" - case _: NullPointerException => - "`<(" + token + ")>'" - } + /** Convert name to token */ + def name2token(name: Name) = { + val idx = name.start - kwOffset + if (idx >= 0 && idx < kwArray.length) kwArray(idx) + else IDENTIFIER + } + + /** Returns the string representation of given token. */ + def token2string(token: Int): String = token match { + case IDENTIFIER => "identifier" + case CHARLIT => "character literal" + case DOUBLELIT => "double literal" + case FLOATLIT => "float literal" + case INTLIT => "integer literal" + case LONGLIT => "long literal" + case STRINGLIT => "string literal" + case EOF => "eof" + case ERROR => "something" + case AMP => "`&'" + case AMPAMP => "`&&'" + case AMPEQ => "`&='" + case ASSIGN => "`='" + case ASTERISK => "`*'" + case ASTERISKEQ => "`*='" + case AT => "`@'" + case BANG => "`!'" + case BANGEQ => "`!='" + case BAR => "`|'" + case BARBAR => "`||'" + case BAREQ => "`|='" + case COLON => "`:'" + case COMMA => "`,'" + case DOT => "`.'" + case DOTDOTDOT => "`...'" + case EQEQ => "`=='" + case GT => "`>'" + case GTEQ => "`>='" + case GTGT => "`>>'" + case GTGTEQ => "`>>='" + case GTGTGT => "`>>>'" + case GTGTGTEQ => "`>>>='" + case HAT => "`^'" + case HATEQ => "`^='" + case LBRACE => "`{'" + case LBRACKET => "`['" + case LPAREN => "`('" + case LT => "`<'" + case LTEQ => "`<='" + case LTLT => "`<<'" + case LTLTEQ => "`<<='" + case MINUS => "`-'" + case MINUSEQ => "`-='" + case MINUSMINUS => "`--'" + case PERCENT => "`%'" + case PERCENTEQ => "`%='" + case PLUS => "`+'" + case PLUSEQ => "`+='" + case PLUSPLUS => "`++'" + case QMARK => "`?'" + case RBRACE => "`}'" + case RBRACKET => "`]'" + case RPAREN => "`)'" + case SEMI => "`;'" + case SLASH => "`/'" + case SLASHEQ => "`/='" + case TILDE => "`~'" + case _ => + try ("`" + tokenName(token) + "'") + catch { + case _: ArrayIndexOutOfBoundsException => + "`<" + token + ">'" + case _: NullPointerException => + "`<(" + token + ")>'" + } } } diff --git a/src/compiler/scala/tools/nsc/symtab/NameManglers.scala b/src/compiler/scala/tools/nsc/symtab/NameManglers.scala index 69b6a5c042..828ca5b0dd 100644 --- a/src/compiler/scala/tools/nsc/symtab/NameManglers.scala +++ b/src/compiler/scala/tools/nsc/symtab/NameManglers.scala @@ -6,6 +6,8 @@ package scala.tools.nsc package symtab +import java.security.MessageDigest +import scala.io.Codec import util.Chars.isOperatorPart /** A trait to encapsulate name mangling. It's intended for the @@ -15,7 +17,39 @@ import util.Chars.isOperatorPart trait NameManglers { self: SymbolTable => - trait NameMangling { + trait NameManglingCommon { + self: CompilerCommonNames => + + def flattenedName(segments: Name*): NameType = compactedString(segments mkString "$") + + private final val MaxFileNameLength = 255 + private final val MaxNameLength = MaxFileNameLength - 6 // leave space for ".class" + + /** "COMPACTIFY" */ + private lazy val md5 = MessageDigest.getInstance("MD5") + private def toMD5(s: String, edge: Int) = { + val prefix = s take edge + val suffix = s takeRight edge + val marker = "$$$$" + + val cs = s.toArray + val bytes = Codec fromUTF8 cs + md5 update bytes + val md5chars = md5.digest() map (b => (b & 0xFF).toHexString) mkString + + prefix + marker + md5chars + marker + suffix + } + private def compactedString(s: String) = + if (s.length <= MaxNameLength) s + else toMD5(s, MaxNameLength / 4) + } + + trait TypeNameMangling extends NameManglingCommon { + self: tpnme.type => + + } + + trait TermNameMangling extends NameManglingCommon { self: nme.type => val IMPL_CLASS_SUFFIX = "$class" @@ -71,9 +105,10 @@ trait NameManglers { */ def splitSpecializedName(name: Name): (Name, String, String) = if (name.endsWith("$sp")) { - val name1 = name.subName(0, name.length - 3) - val idxC = name1.lastPos('c') - val idxM = name1.lastPos('m', idxC) + val name1 = name stripEnd "$sp" + val idxC = name1 lastIndexOf 'c' + val idxM = name1 lastIndexOf 'm' + (name1.subName(0, idxM - 1), name1.subName(idxC + 1, name1.length).toString, name1.subName(idxM + 1, idxC).toString) diff --git a/src/compiler/scala/tools/nsc/symtab/Names.scala b/src/compiler/scala/tools/nsc/symtab/Names.scala index fc03a5866f..8c512d359f 100644 --- a/src/compiler/scala/tools/nsc/symtab/Names.scala +++ b/src/compiler/scala/tools/nsc/symtab/Names.scala @@ -361,6 +361,8 @@ trait Names extends reflect.generic.Names { final def stripEnd(suffix: Name): Name = subName(0, len - suffix.length) final def stripEnd(suffix: String): Name = subName(0, len - suffix.length) + def lastIndexOf(ch: Char) = toChars lastIndexOf ch + /** Return the subname with characters from start to end-1. */ def subName(from: Int, to: Int): Name diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index fdc828a96f..7d8adb8ef9 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -11,6 +11,75 @@ import scala.collection.immutable trait StdNames extends reflect.generic.StdNames with NameManglers { self: SymbolTable => + /** This should be the first trait in the linearization. */ + trait CompilerKeywords { + private var kws: Set[TermName] = Set() + private def kw(s: String): TermName = { + val result = newTermName(s) + kws = kws + result + result + } + + final val ABSTRACTkw: TermName = kw("abstract") + final val CASEkw: TermName = kw("case") + final val CLASSkw: TermName = kw("class") + final val CATCHkw: TermName = kw("catch") + final val DEFkw: TermName = kw("def") + final val DOkw: TermName = kw("do") + final val ELSEkw: TermName = kw("else") + final val EXTENDSkw: TermName = kw("extends") + final val FALSEkw: TermName = kw("false") + final val FINALkw: TermName = kw("final") + final val FINALLYkw: TermName = kw("finally") + final val FORkw: TermName = kw("for") + final val FORSOMEkw: TermName = kw("forSome") + final val IFkw: TermName = kw("if") + final val IMPLICITkw: TermName = kw("implicit") + final val IMPORTkw: TermName = kw("import") + final val LAZYkw: TermName = kw("lazy") + final val MATCHkw: TermName = kw("match") + final val NEWkw: TermName = kw("new") + final val NULLkw: TermName = kw("null") + final val OBJECTkw: TermName = kw("object") + final val OVERRIDEkw: TermName = kw("override") + final val PACKAGEkw: TermName = kw("package") + final val PRIVATEkw: TermName = kw("private") + final val PROTECTEDkw: TermName = kw("protected") + final val RETURNkw: TermName = kw("return") + final val SEALEDkw: TermName = kw("sealed") + final val SUPERkw: TermName = kw("super") + final val THISkw: TermName = kw("this") + final val THROWkw: TermName = kw("throw") + final val TRAITkw: TermName = kw("trait") + final val TRUEkw: TermName = kw("true") + final val TRYkw: TermName = kw("try") + final val TYPEkw: TermName = kw("type") + final val VALkw: TermName = kw("val") + final val VARkw: TermName = kw("var") + final val WITHkw: TermName = kw("with") + final val WHILEkw: TermName = kw("while") + final val YIELDkw: TermName = kw("yield") + final val DOTkw: TermName = kw(".") + final val USCOREkw: TermName = kw("_") + final val COLONkw: TermName = kw(":") + final val EQUALSkw: TermName = kw("=") + final val ARROWkw: TermName = kw("=>") + final val LARROWkw: TermName = kw("<-") + final val SUBTYPEkw: TermName = kw("<:") + final val VIEWBOUNDkw: TermName = kw("<%") + final val SUPERTYPEkw: TermName = kw(">:") + final val HASHkw: TermName = kw("#") + final val ATkw: TermName = kw("@") + + final val keywords = { + val result = kws.toSet + kws = null + result + } + + final val javaKeywords = new JavaKeywords() + } + trait CompilerCommonNames extends LibraryCommonNames { // value types are all used as terms as well final val Boolean: NameType = "Boolean" @@ -81,60 +150,8 @@ trait StdNames extends reflect.generic.StdNames with NameManglers { final val SyntheticATTR: NameType = "Synthetic" } - trait CompilerTermNames extends CompilerCommonNames { - // Scala keywords - final val ABSTRACTkw: NameType = "abstract" - final val CASEkw: NameType = "case" - final val CLASSkw: NameType = "class" - final val CATCHkw: NameType = "catch" - final val DEFkw: NameType = "def" - final val DOkw: NameType = "do" - final val ELSEkw: NameType = "else" - final val EXTENDSkw: NameType = "extends" - final val FALSEkw: NameType = "false" - final val FINALkw: NameType = "final" - final val FINALLYkw: NameType = "finally" - final val FORkw: NameType = "for" - final val FORSOMEkw: NameType = "forSome" - final val IFkw: NameType = "if" - final val IMPLICITkw: NameType = "implicit" - final val IMPORTkw: NameType = "import" - final val LAZYkw: NameType = "lazy" - final val MATCHkw: NameType = "match" - final val NEWkw: NameType = "new" - final val NULLkw: NameType = "null" - final val OBJECTkw: NameType = "object" - final val OVERRIDEkw: NameType = "override" - final val PACKAGEkw: NameType = "package" - final val PRIVATEkw: NameType = "private" - final val PROTECTEDkw: NameType = "protected" - final val RETURNkw: NameType = "return" - final val REQUIRESkw: NameType = "requires" - final val SEALEDkw: NameType = "sealed" - final val SUPERkw: NameType = "super" - final val THISkw: NameType = "this" - final val THROWkw: NameType = "throw" - final val TRAITkw: NameType = "trait" - final val TRUEkw: NameType = "true" - final val TRYkw: NameType = "try" - final val TYPEkw: NameType = "type" - final val VALkw: NameType = "val" - final val VARkw: NameType = "var" - final val WITHkw: NameType = "with" - final val WHILEkw: NameType = "while" - final val YIELDkw: NameType = "yield" - final val DOTkw: NameType = "." - final val USCOREkw: NameType = "_" - final val COLONkw: NameType = ":" - final val EQUALSkw: NameType = "=" - final val ARROWkw: NameType = "=>" - final val LARROWkw: NameType = "<-" - final val SUBTYPEkw: NameType = "<:" - final val VIEWBOUNDkw: NameType = "<%" - final val SUPERTYPEkw: NameType = ">:" - final val HASHkw: NameType = "#" - final val ATkw: NameType = "@" + trait CompilerTermNames extends CompilerKeywords with CompilerCommonNames { // Compiler internal names val ANYNAME: NameType = "" val CONSTRUCTOR: NameType = "" @@ -270,27 +287,17 @@ trait StdNames extends reflect.generic.StdNames with NameManglers { val toDouble: NameType = "toDouble" } - object tpnme extends CompilerTypeNames with LibraryTypeNames { + object tpnme extends CompilerTypeNames with LibraryTypeNames with TypeNameMangling { type NameType = TypeName implicit def createNameType(name: String): TypeName = newTypeName(name) } - object nme extends CompilerTermNames with LibraryTermNames with NameMangling { + val javanme = nme.javaKeywords + + object nme extends CompilerTermNames with LibraryTermNames with TermNameMangling { type NameType = TermName implicit def createNameType(name: String): TermName = newTermName(name) - final val keywords = Set[TermName]( - ABSTRACTkw, CASEkw, CLASSkw, CATCHkw, DEFkw, DOkw, ELSEkw, - EXTENDSkw, FALSEkw, FINALkw, FINALLYkw, FORkw, FORSOMEkw, IFkw, - IMPLICITkw, IMPORTkw, LAZYkw, MATCHkw, NEWkw, NULLkw, OBJECTkw, - OVERRIDEkw, PACKAGEkw, PRIVATEkw, PROTECTEDkw, RETURNkw, REQUIRESkw, - SEALEDkw, SUPERkw, THISkw, THROWkw, TRAITkw, TRUEkw, TRYkw, TYPEkw, - VALkw, VARkw, WITHkw, WHILEkw, YIELDkw - ) ++ Set[TermName]( - DOTkw, USCOREkw, COLONkw, EQUALSkw, ARROWkw, LARROWkw, SUBTYPEkw, - VIEWBOUNDkw, SUPERTYPEkw, HASHkw, ATkw - ) - /** Translate a String into a list of simple TypeNames and TermNames. * In all segments before the last, type/term is determined by whether * the following separator char is '.' or '#'. In the last segment, @@ -426,6 +433,72 @@ trait StdNames extends reflect.generic.StdNames with NameManglers { val Boxed: immutable.Map[TypeName, TypeName] } + class JavaKeywords { + private var kws: Set[TermName] = Set() + private def kw(s: String): TermName = { + val result = newTermName(s) + kws = kws + result + result + } + + final val ABSTRACTkw: TermName = kw("abstract") + final val ASSERTkw: TermName = kw("assert") + final val BOOLEANkw: TermName = kw("boolean") + final val BREAKkw: TermName = kw("break") + final val BYTEkw: TermName = kw("byte") + final val CASEkw: TermName = kw("case") + final val CATCHkw: TermName = kw("catch") + final val CHARkw: TermName = kw("char") + final val CLASSkw: TermName = kw("class") + final val CONSTkw: TermName = kw("const") + final val CONTINUEkw: TermName = kw("continue") + final val DEFAULTkw: TermName = kw("default") + final val DOkw: TermName = kw("do") + final val DOUBLEkw: TermName = kw("double") + final val ELSEkw: TermName = kw("else") + final val ENUMkw: TermName = kw("enum") + final val EXTENDSkw: TermName = kw("extends") + final val FINALkw: TermName = kw("final") + final val FINALLYkw: TermName = kw("finally") + final val FLOATkw: TermName = kw("float") + final val FORkw: TermName = kw("for") + final val IFkw: TermName = kw("if") + final val GOTOkw: TermName = kw("goto") + final val IMPLEMENTSkw: TermName = kw("implements") + final val IMPORTkw: TermName = kw("import") + final val INSTANCEOFkw: TermName = kw("instanceof") + final val INTkw: TermName = kw("int") + final val INTERFACEkw: TermName = kw("interface") + final val LONGkw: TermName = kw("long") + final val NATIVEkw: TermName = kw("native") + final val NEWkw: TermName = kw("new") + final val PACKAGEkw: TermName = kw("package") + final val PRIVATEkw: TermName = kw("private") + final val PROTECTEDkw: TermName = kw("protected") + final val PUBLICkw: TermName = kw("public") + final val RETURNkw: TermName = kw("return") + final val SHORTkw: TermName = kw("short") + final val STATICkw: TermName = kw("static") + final val STRICTFPkw: TermName = kw("strictfp") + final val SUPERkw: TermName = kw("super") + final val SWITCHkw: TermName = kw("switch") + final val SYNCHRONIZEDkw: TermName = kw("synchronized") + final val THISkw: TermName = kw("this") + final val THROWkw: TermName = kw("throw") + final val THROWSkw: TermName = kw("throws") + final val TRANSIENTkw: TermName = kw("transient") + final val TRYkw: TermName = kw("try") + final val VOIDkw: TermName = kw("void") + final val VOLATILEkw: TermName = kw("volatile") + final val WHILEkw: TermName = kw("while") + + final val keywords = { + val result = kws.toSet + kws = null + result + } + } + private abstract class JavaNames extends SymbolNames { final val BoxedBoolean: TypeName = "java.lang.Boolean" final val BoxedByte: TypeName = "java.lang.Byte" diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index b4a31d4d9c..f64af26b1c 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -1759,7 +1759,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => if (isFlatAdjusted) { if (flatname == null) { assert(rawowner.isClass, "fatal: %s has non-class owner %s after flatten.".format(rawname, rawowner)) - flatname = newTermName(compactify(rawowner.name + "$" + rawname)) + flatname = nme.flattenedName(rawowner.name, rawname) } flatname } else rawname @@ -1963,7 +1963,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => if (needsFlatClasses) { if (flatname == null) { assert(rawowner.isClass, "fatal: %s has owner %s, but a class owner is required".format(rawname+idString, rawowner)) - flatname = newTypeName(compactify(rawowner.name + "$" + rawname)) + flatname = tpnme.flattenedName(rawowner.name, rawname) } flatname } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index ba182f7058..da261bb6bf 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -9,6 +9,7 @@ package classfile import java.lang.Float.floatToIntBits import java.lang.Double.doubleToLongBits +import scala.io.Codec import reflect.generic.{ PickleBuffer, PickleFormat } import scala.collection.mutable.LinkedHashMap import PickleFormat._ @@ -498,7 +499,9 @@ abstract class Pickler extends SubComponent { /** Write a name in UTF8 format. */ private def writeName(name: Name) { ensureCapacity(name.length * 3) - writeIndex = name.copyUTF8(bytes, writeIndex) + val utfBytes = Codec fromUTF8 name.toString + compat.Platform.arraycopy(utfBytes, 0, bytes, writeIndex, utfBytes.length) + writeIndex += utfBytes.length } /** Write an annotation */ -- cgit v1.2.3