From d6ef73c9a2f327a095cc269575ffe6e950d55495 Mon Sep 17 00:00:00 2001 From: rytz Date: Mon, 26 Oct 2009 09:56:33 +0000 Subject: [PATCH] new classpaths. cleaned up scopes. removed scope kinds. cleaned up symbol loading, integrated msil types, fix separate compilation for msil. Symbol.sourceFile only set for classes which are being compiled. git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@19285 5e8d7ff9-d8ef-0310-90f0-a4852d11357a --- build.xml | 4 + .../scala/tools/ant/sabbus/ScalacFork.scala | 6 +- .../scala/tools/ant/sabbus/Settings.scala | 6 + .../scala/tools/ant/templates/tool-unix.tmpl | 2 +- .../tools/ant/templates/tool-windows.tmpl | 2 +- src/compiler/scala/tools/nsc/Global.scala | 52 +- .../scala/tools/nsc/MainGenericRunner.scala | 9 +- src/compiler/scala/tools/nsc/Settings.scala | 10 +- .../scala/tools/nsc/ast/TreeInfo.scala | 11 +- .../tools/nsc/backend/icode/GenICode.scala | 2 +- .../tools/nsc/backend/msil/GenMSIL.scala | 189 +++-- .../scala/tools/nsc/interactive/Global.scala | 2 +- .../scala/tools/nsc/symtab/Definitions.scala | 10 +- .../scala/tools/nsc/symtab/Scopes.scala | 123 +--- .../tools/nsc/symtab/SymbolLoaders.scala | 305 ++++---- .../scala/tools/nsc/symtab/SymbolTable.scala | 6 - .../scala/tools/nsc/symtab/Symbols.scala | 1 - .../scala/tools/nsc/symtab/Types.scala | 35 +- .../symtab/classfile/ClassfileParser.scala | 34 +- .../nsc/symtab/classfile/ICodeReader.scala | 23 +- .../nsc/symtab/classfile/MetaParser.scala | 4 +- .../tools/nsc/symtab/classfile/Pickler.scala | 9 - .../nsc/symtab/classfile/UnPickler.scala | 16 +- .../scala/tools/nsc/symtab/clr/CLRTypes.scala | 138 +--- .../tools/nsc/symtab/clr/TypeParser.scala | 14 +- .../tools/nsc/transform/AddInterfaces.scala | 2 +- .../scala/tools/nsc/transform/Erasure.scala | 2 +- .../tools/nsc/transform/ExplicitOuter.scala | 4 +- .../scala/tools/nsc/transform/Flatten.scala | 2 +- .../scala/tools/nsc/transform/Mixin.scala | 6 +- .../tools/nsc/transform/OverridingPairs.scala | 2 +- .../tools/nsc/transform/SpecializeTypes.scala | 8 +- .../scala/tools/nsc/transform/UnCurry.scala | 2 +- .../tools/nsc/typechecker/Contexts.scala | 6 +- .../tools/nsc/typechecker/DeVirtualize.scala | 6 +- .../scala/tools/nsc/typechecker/Namers.scala | 33 +- .../tools/nsc/typechecker/NamesDefaults.scala | 2 +- .../tools/nsc/typechecker/RefChecks.scala | 4 +- .../scala/tools/nsc/typechecker/Typers.scala | 37 +- .../scala/tools/nsc/util/ClassPath.scala | 686 ++++++++++-------- src/library/scala/xml/factory/XMLLoader.scala | 7 +- .../tools/partest/nest/ReflectiveRunner.scala | 3 +- src/scalap/scala/tools/scalap/Main.scala | 36 +- test/files/jvm/interpreter.scala | 7 +- .../neg/plugin-after-terminal/lib/plugins.jar | Bin 4203 -> 4128 bytes .../neg/plugin-before-parser/lib/plugins.jar | Bin 4280 -> 4211 bytes .../plugin-cyclic-dependency/lib/plugins.jar | Bin 5646 -> 5563 bytes .../plugin-rafter-before-1/lib/plugins.jar | Bin 4238 -> 4170 bytes .../lib/plugins.jar | Bin 4210 -> 4168 bytes test/files/run/constrained-types.scala | 2 + test/files/run/docgenerator.scala | 2 + test/files/run/lisp.scala | 2 +- test/files/run/t1500.scala | 2 + test/files/run/t1501.scala | 3 + 54 files changed, 829 insertions(+), 1050 deletions(-) diff --git a/build.xml b/build.xml index 0986633ae..e529e29c1 100644 --- a/build.xml +++ b/build.xml @@ -245,6 +245,7 @@ INITIALISATION + @@ -371,6 +372,7 @@ LOCAL REFERENCE BUILD (LOCKER) + @@ -688,6 +690,7 @@ QUICK BUILD (QUICK) + @@ -730,6 +733,7 @@ QUICK BUILD (QUICK) + diff --git a/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala b/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala index e68304d2f..c3d232b16 100644 --- a/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala +++ b/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala @@ -52,12 +52,16 @@ class ScalacFork extends MatchingTask with TaskArgs { if (!compTarget.isEmpty) settings.target = compTarget.get if (!compilationPath.isEmpty) settings.classpath = compilationPath.get if (!sourcePath.isEmpty) settings.sourcepath = sourcePath.get + if (compTarget.isDefined && compTarget.get == "msil") settings.sourcedir = sourceDir.get if (!params.isEmpty) settings.more = params.get // not yet used: compilerPath, sourcedir (used in mapper), failonerror, timeout val mapper = new GlobPatternMapper() - mapper.setTo("*.class") + if (compTarget.isDefined && compTarget.get == "msil") + mapper.setTo("*.msil") + else + mapper.setTo("*.class") mapper.setFrom("*.scala") val includedFiles: Array[File] = new SourceFileScanner(this).restrict( diff --git a/src/compiler/scala/tools/ant/sabbus/Settings.scala b/src/compiler/scala/tools/ant/sabbus/Settings.scala index 574d90cec..8c970da81 100644 --- a/src/compiler/scala/tools/ant/sabbus/Settings.scala +++ b/src/compiler/scala/tools/ant/sabbus/Settings.scala @@ -33,6 +33,10 @@ class Settings { def sourcepath = sourcepathBf.get def sourcepath_=(p: Path): this.type = { sourcepathBf = Some(p); this } + private var sourcedirBf: Option[File] = None + def sourcedir = sourcedirBf.get + def sourcedir_=(p: File): this.type = { sourcedirBf = Some(p); this } + private var bootclasspathBf: Option[Path] = None def bootclasspath = bootclasspathBf.get def bootclasspath_=(p: Path): this.type = { bootclasspathBf = Some(p); this } @@ -66,6 +70,7 @@ class Settings { (if (uncheckedBf) "-unchecked" :: Nil else Nil) ::: (if (!classpathBf.isEmpty) "-classpath" :: classpath.toString :: Nil else Nil) ::: (if (!sourcepathBf.isEmpty) "-sourcepath" :: sourcepath.toString :: Nil else Nil) ::: + (if (!sourcedirBf.isEmpty) "-Xsourcedir" :: sourcedir.toString :: Nil else Nil) ::: (if (!bootclasspathBf.isEmpty) "-bootclasspath" :: bootclasspath.toString :: Nil else Nil) ::: (if (!extdirsBf.isEmpty) "-extdirs" :: extdirs.toString :: Nil else Nil) ::: (if (!dBf.isEmpty) "-d" :: d.getAbsolutePath :: Nil else Nil) ::: @@ -80,6 +85,7 @@ class Settings { this.uncheckedBf == cs.uncheckedBf && this.classpathBf == cs.classpathBf && this.sourcepathBf == cs.sourcepathBf && + this.sourcedirBf == cs.sourcedirBf && this.bootclasspathBf == cs.bootclasspathBf && this.extdirsBf == cs.extdirsBf && this.dBf == cs.dBf && diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl index 2d7f49001..3e22fa6e1 100644 --- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl @@ -67,4 +67,4 @@ if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then JAVACMD="$JAVA_HOME/bin/java" fi -exec "${JAVACMD:=java}" $JAVA_OPTS -cp "$TOOL_CLASSPATH" -Dscala.home="$SCALA_HOME" -Denv.classpath="$CLASSPATH" -Denv.emacs="$EMACS" @properties@ @class@ @toolflags@ "$@@" +exec "${JAVACMD:=java}" $JAVA_OPTS -cp "$TOOL_CLASSPATH" -Dscala.home="$SCALA_HOME" -Denv.emacs="$EMACS" @properties@ @class@ @toolflags@ "$@@" diff --git a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl index 9cd7cc96a..4bdb6adcc 100644 --- a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl @@ -47,7 +47,7 @@ if "%_TOOL_CLASSPATH%"=="" ( ) ) -set _PROPS=-Dscala.home="%_SCALA_HOME%" -Denv.classpath="%CLASSPATH%" -Denv.emacs="%EMACS%" @properties@ +set _PROPS=-Dscala.home="%_SCALA_HOME%" -Denv.emacs="%EMACS%" @properties@ rem echo "%_JAVACMD%" %_JAVA_OPTS% %_PROPS% -cp "%_TOOL_CLASSPATH%" @class@ @toolflags@ %_ARGS% "%_JAVACMD%" %_JAVA_OPTS% %_PROPS% -cp "%_TOOL_CLASSPATH%" @class@ @toolflags@ %_ARGS% diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index b43b8cf09..14d1c4514 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -12,7 +12,7 @@ import java.nio.charset._ import compat.Platform.currentTime import scala.tools.nsc.io.{SourceReader, AbstractFile} import scala.tools.nsc.reporters._ -import scala.tools.nsc.util.{ClassPath, SourceFile, BatchSourceFile, OffsetPosition, RangePosition} +import scala.tools.nsc.util.{ClassPath, MsilClassPath, JavaClassPath, SourceFile, BatchSourceFile, OffsetPosition, RangePosition} import scala.collection.mutable.{HashSet, HashMap, ListBuffer} @@ -252,25 +252,17 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable } } - lazy val classPath0 = new ClassPath(false && onlyPresentation) - - lazy val classPath = + lazy val classPath = { + ClassPath.XO = settings.XO.value if (forMSIL) - new classPath0.Build(settings.sourcepath.value, settings.outdir.value) + new MsilClassPath(settings.assemextdirs.value, settings.assemrefs.value, + settings.sourcepath.value) else - new classPath0.Build(settings.classpath.value, settings.sourcepath.value, - settings.outdir.value, settings.bootclasspath.value, - settings.extdirs.value, settings.Xcodebase.value) - /* .NET's equivalent of a classpath */ - lazy val assemrefs = { - import java.util.{StringTokenizer} - val set = new HashSet[File] - val assems = new StringTokenizer(settings.assemrefs.value, File.pathSeparator) - while (assems.hasMoreTokens()) - set += new java.io.File(assems.nextToken()) - set + new JavaClassPath(settings.bootclasspath.value, settings.extdirs.value, + settings.classpath.value, settings.sourcepath.value, + settings.Xcodebase.value) } - + if (settings.verbose.value) { inform("[Classpath = " + classPath + "]") if (forMSIL) inform("[AssemRefs = " + settings.assemrefs.value + "]") @@ -286,20 +278,13 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable getSourceFile(f) } - def getSourceFile(clazz: Symbol): SourceFile = { - val ret = classPath.root.find(clazz.fullNameString(File.separatorChar), false) - if (!ret.isSourceFile) throw new FileNotFoundException( - "source file for " + clazz + " could not be found") - getSourceFile(ret.sourceFile) - } - - lazy val loaders : SymbolLoaders { val global : Global.this.type } = new { + lazy val loaders = new SymbolLoaders { val global: Global.this.type = Global.this - } with SymbolLoaders + } def rootLoader: LazyType = - if (forMSIL) new loaders.NamespaceLoader(classPath.root) - else new loaders.PackageLoader(classPath.root /* getRoot() */) + if (forMSIL) new loaders.NamespaceLoader(classPath.asInstanceOf[MsilClassPath]) + else new loaders.JavaPackageLoader(classPath.asInstanceOf[JavaClassPath]) // ------------ Phases -------------------------------------------} @@ -574,7 +559,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable object icodeChecker extends checkers.ICodeChecker() object typer extends analyzer.Typer( - analyzer.NoContext.make(EmptyTree, Global.this.definitions.RootClass, newScope)) + analyzer.NoContext.make(EmptyTree, Global.this.definitions.RootClass, new Scope)) /* Add the internal compiler phases to the phases set */ @@ -905,8 +890,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable " was found\n(This file cannot be loaded as a source file)" inform(msg) throw new FatalError(msg) - } - else if (!(fileset contains file)) { + } else if (!(fileset contains file)) { compileLate(new CompilationUnit(getSourceFile(file))) } } @@ -963,7 +947,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable inform("" + sym.name + ":" +(if (module) sym.tpe.typeSymbol.info else sym.info)) } - /** Returns the file with the given suffix for the given class. */ + /** Returns the file with the given suffix for the given class. Used for icode writing. */ def getFile(clazz: Symbol, suffix: String): File = { val outdirname = settings.outputDirs.outputDirFor(clazz.sourceFile) var outdir = new File(if (outdirname.path == "") "." else outdirname.path) @@ -1002,8 +986,4 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable def forJVM : Boolean = settings.target.value startsWith "jvm" def forMSIL: Boolean = settings.target.value == "msil" def onlyPresentation = false - private val unpickleIDEHook0 : (( => Type) => Type) = f => f - def unpickleIDEHook : (( => Type) => Type) = unpickleIDEHook0 - - def doPickleHash = false } diff --git a/src/compiler/scala/tools/nsc/MainGenericRunner.scala b/src/compiler/scala/tools/nsc/MainGenericRunner.scala index a4f5a0014..e6c714dc4 100644 --- a/src/compiler/scala/tools/nsc/MainGenericRunner.scala +++ b/src/compiler/scala/tools/nsc/MainGenericRunner.scala @@ -39,7 +39,14 @@ object MainGenericRunner { lazy val jarsInLib = listDir("lib") filter (_.getName endsWith ".jar") lazy val dirsInClasses = listDir("classes") filter (_.isDirectory) val cpScala = - if (scalaHome == null) Nil + if (scalaHome == null) { + // this is to make the interpreter work when running without the scala script + // (e.g. from eclipse). Before, "java.class.path" was added to the user classpath + // in Settings; this was changed to match the behavior of Sun's javac. + val javacp = System.getProperty("java.class.path") + if (javacp == null) Nil + else ClassPath.expandPath(javacp) + } else (jarsInLib ::: dirsInClasses) map (_.toString) // either prepend existing classpath or append "." diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 1486f44da..d81a95a4a 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -17,6 +17,7 @@ class Settings(errorFn: String => Unit) extends ScalacSettings { // optionizes a system property private def syspropopt(name: String): Option[String] = onull(System.getProperty(name)) + private def sysenvopt(name: String): Option[String] = onull(System.getenv(name)) // given any number of possible path segments, flattens down to a // :-separated style path @@ -24,7 +25,7 @@ class Settings(errorFn: String => Unit) extends ScalacSettings { segments.toList.flatMap(x => x) mkString File.pathSeparator protected def classpathDefault = - syspropopt("env.classpath") orElse syspropopt("java.class.path") getOrElse "" + sysenvopt("CLASSPATH") getOrElse "." protected def bootclasspathDefault = concatPath(syspropopt("sun.boot.class.path"), guessedScalaBootClassPath) @@ -36,6 +37,9 @@ class Settings(errorFn: String => Unit) extends ScalacSettings { protected def extdirsDefault = concatPath(syspropopt("java.ext.dirs"), guessedScalaExtDirs) + protected def assemExtdirsDefault = + concatPath(guessedScalaExtDirs) + protected def pluginsDirDefault = guess(List("misc", "scala-devel", "plugins"), _.isDirectory) getOrElse "" @@ -759,8 +763,10 @@ trait ScalacSettings { * -X "Advanced" settings */ val Xhelp = BooleanSetting ("-X", "Print a synopsis of advanced options") - val assemname = StringSetting ("-Xassem", "file", "Name of the output assembly (only relevant with -target:msil)", "").dependsOn(target, "msil") + val assemname = StringSetting ("-Xassem-name", "file", "Name of the output assembly (only relevant with -target:msil)", "").dependsOn(target, "msil") val assemrefs = StringSetting ("-Xassem-path", "path", "List of assemblies referenced by the program (only relevant with -target:msil)", ".").dependsOn(target, "msil") + val assemextdirs = StringSetting ("-Xassem-extdirs", "dirs", "List of directories containing assemblies, defaults to `lib'", assemExtdirsDefault).dependsOn(target, "msil") + val sourcedir = StringSetting ("-Xsourcedir", "directory", "When -target:msil, the source folder structure is mirrored in output directory.", ".").dependsOn(target, "msil") val checkInit = BooleanSetting ("-Xcheckinit", "Add runtime checks on field accessors. Uninitialized accesses result in an exception being thrown.") val noassertions = BooleanSetting ("-Xdisable-assertions", "Generate no assertions and assumptions") val elideLevel = IntSetting ("-Xelide-level", "Generate calls to @elidable-marked methods only method priority is greater than argument.", diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index 2183c9a50..d6803aa71 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -337,14 +337,15 @@ abstract class TreeInfo { /** Compilation unit is the predef object */ def isPredefUnit(tree: Tree): Boolean = tree match { - case PackageDef(Ident(nme.scala_), List(obj)) => isPredefObj(obj) + case PackageDef(Ident(nme.scala_), defs) => isPredefObj(defs) case _ => false } - private def isPredefObj(tree: Tree): Boolean = tree match { - case ModuleDef(_, nme.Predef, _) => true - case DocDef(_, tree1) => isPredefObj(tree1) - case Annotated(_, tree1) => isPredefObj(tree1) + private def isPredefObj(trees: List[Tree]): Boolean = trees match { + case Import(_, _) :: xs => isPredefObj(xs) + case ModuleDef(_, nme.Predef, _) :: Nil => true + case DocDef(_, tree1) :: Nil => isPredefObj(List(tree1)) + case Annotated(_, tree1) :: Nil => isPredefObj(List(tree1)) case _ => false } diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 97e253b57..7287ea223 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -54,7 +54,7 @@ abstract class GenICode extends SubComponent { val SCALA_ALLREF = REFERENCE(definitions.NullClass) val THROWABLE = REFERENCE(ThrowableClass) - val BoxesRunTime_equals = + lazy val BoxesRunTime_equals = if (!forMSIL) definitions.getMember(definitions.BoxesRunTimeClass, nme.equals_) else diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index c12d183da..0bf41b515 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -18,8 +18,6 @@ import scala.tools.nsc.util.Position import ch.epfl.lamp.compiler.msil.{Type => MsilType, _} import ch.epfl.lamp.compiler.msil.emit._ -/** - */ abstract class GenMSIL extends SubComponent { import global._ import loaders.clrTypes @@ -75,7 +73,7 @@ abstract class GenMSIL extends SubComponent { import clrTypes.{VOID => MVOID, BOOLEAN => MBOOL, UBYTE => MBYTE, SHORT => MSHORT, CHAR => MCHAR, INT => MINT, LONG => MLONG, FLOAT => MFLOAT, DOUBLE => MDOUBLE, OBJECT => MOBJECT, STRING => MSTRING, - STRING_ARRAY => MSTRING_ARRAY, SCALA_SYMTAB_ATTR => SYMTAB_ATTRIBUTE, + STRING_ARRAY => MSTRING_ARRAY, SYMTAB_CONSTR => SYMTAB_ATTRIBUTE_CONSTRUCTOR, SYMTAB_DEFAULT_CONSTR => SYMTAB_ATTRIBUTE_EMPTY_CONSTRUCTOR} @@ -118,7 +116,7 @@ abstract class GenMSIL extends SubComponent { val toDouble: MethodInfo = SystemConvert.GetMethod("ToDouble", objParam) //val boxedUnit: FieldInfo = msilType(definitions.BoxedUnitModule.info).GetField("UNIT") - val boxedUnit: FieldInfo = fields(definitions.BoxedUnit_UNIT.asInstanceOf[clrTypes.global.Symbol]) + val boxedUnit: FieldInfo = fields(definitions.BoxedUnit_UNIT) // Scala attributes // symtab.Definitions -> object (singleton..) @@ -133,8 +131,8 @@ abstract class GenMSIL extends SubComponent { val dynToStatMapped: HashSet[Symbol] = new HashSet() initMappings() - // ******************************************************************** - // Create the mappings + + /** Create the mappings between java and .net classes and methods */ private def initMappings() { mapType(definitions.AnyClass, MOBJECT) mapType(definitions.AnyRefClass, MOBJECT) @@ -231,7 +229,7 @@ abstract class GenMSIL extends SubComponent { assemName = assemName.substring(0, assemName.length() - 1) } else { // assuming filename of first source file - assert(firstSourceName.endsWith(".scala"), "Source file doesn't end with .scala") + assert(firstSourceName.endsWith(".scala"), firstSourceName) assemName = firstSourceName.substring(0, firstSourceName.length() - 6) } } else { @@ -245,7 +243,7 @@ abstract class GenMSIL extends SubComponent { outDir = new File(settings.outdir.value) - srcPath = new File(settings.sourcepath.value) + srcPath = new File(settings.sourcedir.value) val assemblyName = new AssemblyName() assemblyName.Name = assemName @@ -263,35 +261,44 @@ abstract class GenMSIL extends SubComponent { * Form of the custom Attribute parameter (Ecma-335.pdf) * - p. 163 for CustomAttrib Form, * - p. 164 for FixedArg Form (Array and Element) (if array or not is known!) - * !! least significant *byte* first if values longer than one byte !! + * !! least significant byte first if values longer than one byte !! * * 1: Prolog (unsigned int16, value 0x0001) -> symtab[0] = 0x01, symtab[1] = 0x00 * 2: FixedArgs (directly the data, get number and types from related constructor) - * 2.1: length of the array (unsigned int32, take care on order of the 4 bytes) + * 2.1: length of the array (unsigned int32, 4 bytes, least significant first) * 2.2: the byte array data * 3: NumNamed (unsigned int16, number of named fields and properties, 0x0000) - * - **/ + */ def addSymtabAttribute(sym: Symbol, tBuilder: TypeBuilder) { - currentRun.symData.get(sym) match { - case Some(pickle) => - val symtab: Array[Byte] = new Array[Byte](pickle.writeIndex + 8) - symtab(0) = 1.toByte - var size:Int = pickle.writeIndex - for (i <- 2 until 6) { - symtab(i) = (size & 0xff).toByte - size = size >> 8 - } + def addMarker() { + val markerSymtab = new Array[Byte](4) + markerSymtab(0) = 1.toByte + tBuilder.SetCustomAttribute(SYMTAB_ATTRIBUTE_EMPTY_CONSTRUCTOR, markerSymtab) + } - System.arraycopy(pickle.bytes, 0, symtab, 6, pickle.writeIndex) + // both conditions are needed (why exactly..?) + if (tBuilder.Name.endsWith("$") || sym.isModuleClass) { + addMarker() + } else { + currentRun.symData.get(sym) match { + case Some(pickle) => + var size = pickle.writeIndex + val symtab = new Array[Byte](size + 8) + symtab(0) = 1.toByte + for (i <- 2 until 6) { + symtab(i) = (size & 0xff).toByte + size = size >> 8 + } + System.arraycopy(pickle.bytes, 0, symtab, 6, pickle.writeIndex) - tBuilder.SetCustomAttribute(SYMTAB_ATTRIBUTE_CONSTRUCTOR, symtab) + tBuilder.SetCustomAttribute(SYMTAB_ATTRIBUTE_CONSTRUCTOR, symtab) - currentRun.symData -= sym - currentRun.symData -= sym.linkedSym - //log("Generated ScalaSig Attr for " + sym)//debug - case _ => - log("Could not find pickle information for " + sym) + currentRun.symData -= sym + currentRun.symData -= sym.linkedSym + + case _ => + addMarker() + } } } @@ -437,8 +444,8 @@ abstract class GenMSIL extends SubComponent { def writeAssembly() { if (entryPoint != null) { - assert(entryPoint.enclClass.isModuleClass, "main-method not defined in a module") - val mainMethod = methods(entryPoint.asInstanceOf[clrTypes.global.Symbol]) + assert(entryPoint.enclClass.isModuleClass, entryPoint.enclClass) + val mainMethod = methods(entryPoint) val stringArrayTypes: Array[MsilType] = Array(MSTRING_ARRAY) val globalMain = mmodule.DefineGlobalMethod( "Main", MethodAttributes.Public | MethodAttributes.Static, @@ -466,7 +473,7 @@ abstract class GenMSIL extends SubComponent { private def createTypes() { for (sym <- classes.keysIterator) { val iclass = classes(sym) - val tBuilder = types(sym.asInstanceOf[clrTypes.global.Symbol]).asInstanceOf[TypeBuilder] + val tBuilder = types(sym).asInstanceOf[TypeBuilder] if (settings.debug.value) log("Calling CreatType for " + sym + ", " + tBuilder.toString) @@ -483,7 +490,7 @@ abstract class GenMSIL extends SubComponent { clasz = iclass val tBuilder = getType(sym).asInstanceOf[TypeBuilder] - if (isCloneable(sym)){ + if (isCloneable(sym)) { // FIXME: why there's no nme.clone_ ? // "Clone": if the code is non-portable, "Clone" is defined, not "clone" // TODO: improve condition (should override AnyRef.clone) @@ -508,30 +515,14 @@ abstract class GenMSIL extends SubComponent { tBuilder.setPosition(line, iclass.cunit.source.file.name) if (isTopLevelModule(sym)) { - if (settings.debug.value) - log("TopLevelModule: " + sym) - if (sym.linkedClassOfModule == NoSymbol) { - if (settings.debug.value) - log(" no linked class: " + sym) + if (sym.linkedClassOfModule == NoSymbol) dumpMirrorClass(sym) - } else if (!currentRun.compiles(sym.linkedClassOfModule)) { - if (settings.debug.value) - log(" not compiling linked class: " + sym) - dumpMirrorClass(sym) - } - } - - // the pickling info is not written to the module class, but to it's - // linked class (the mirror class eventually dumped) - if (!(tBuilder.Name.endsWith("$") && sym.isModuleClass)){ - // think the if inside could be removed, because in this case, addSymtabAttribute is - // called in the dumpMirrorClass method - addSymtabAttribute(if (isTopLevelModule(sym)) sym.sourceModule else sym, tBuilder) - - // TODO: remove; check the above think: - assert(!isTopLevelModule(sym), "can't remove the 'if'") + else + log("No mirror class for module with linked class: " + + sym.fullNameString) } + addSymtabAttribute(sym, tBuilder) addAttributes(tBuilder, sym.annotations) if (iclass.symbol != definitions.ArrayClass) @@ -548,10 +539,10 @@ abstract class GenMSIL extends SubComponent { localBuilders.clear computeLocalVarsIndex(m) - if (m.symbol.isClassConstructor){ - mcode = constructors(m.symbol.asInstanceOf[clrTypes.global.Symbol]).asInstanceOf[ConstructorBuilder].GetILGenerator() + if (m.symbol.isClassConstructor) { + mcode = constructors(m.symbol).asInstanceOf[ConstructorBuilder].GetILGenerator() } else { - val mBuilder = methods(m.symbol.asInstanceOf[clrTypes.global.Symbol]).asInstanceOf[MethodBuilder] + val mBuilder = methods(m.symbol).asInstanceOf[MethodBuilder] if (!mBuilder.IsAbstract()) try { mcode = mBuilder.GetILGenerator() @@ -984,7 +975,7 @@ abstract class GenMSIL extends SubComponent { var affectedHandlers: List[ExceptionHandler] = Nil untreatedHandlers.foreach( (h) => { - if (h.covers(x)){ + if (h.covers(x)) { affectedHandlers = h :: affectedHandlers } }) @@ -1083,7 +1074,7 @@ abstract class GenMSIL extends SubComponent { if (settings.debug.value) log("adding exhinstr: " + b + " -> " + ehi) - if (bb2exHInstructions.contains(b)){ + if (bb2exHInstructions.contains(b)) { bb2exHInstructions(b) = ehi :: bb2exHInstructions(b) } else { bb2exHInstructions(b) = List(ehi) @@ -1146,7 +1137,7 @@ abstract class GenMSIL extends SubComponent { }) - if (settings.debug.value){ + if (settings.debug.value) { log("after: " + orderedBlocks) log(" exhInstr: " + bb2exHInstructions) } @@ -1181,7 +1172,7 @@ abstract class GenMSIL extends SubComponent { } } - if (bb2exHInstructions.contains(b)){ + if (bb2exHInstructions.contains(b)) { bb2exHInstructions(b).foreach((i) => i match { case BeginExceptionBlock(handler) => if (settings.debug.value) log("begin ex blk: " + handler) @@ -1287,11 +1278,11 @@ abstract class GenMSIL extends SubComponent { log("LOAD_FIELD with owner: " + field.owner + " flags: " + Flags.flagsToString(field.owner.flags)) - var fieldInfo: FieldInfo = fields.get(field.asInstanceOf[clrTypes.global.Symbol]) match { + var fieldInfo: FieldInfo = fields.get(field) match { case Some(fInfo) => fInfo case None => val fInfo = getType(field.owner).GetField(msilName(field)) - fields(field.asInstanceOf[clrTypes.global.Symbol]) = fInfo + fields(field) = fInfo fInfo } mcode.Emit(if (isStatic) OpCodes.Ldsfld else OpCodes.Ldfld, fieldInfo) @@ -1350,11 +1341,11 @@ abstract class GenMSIL extends SubComponent { mcode.Emit(OpCodes.Starg_S, 0) case STORE_FIELD(field, isStatic) => - val fieldInfo: FieldInfo = fields.get(field.asInstanceOf[clrTypes.global.Symbol]) match { + val fieldInfo: FieldInfo = fields.get(field) match { case Some(fInfo) => fInfo case None => val fInfo = getType(field.owner).GetField(msilName(field)) - fields(field.asInstanceOf[clrTypes.global.Symbol]) = fInfo + fields(field) = fInfo fInfo } mcode.Emit(if (isStatic) OpCodes.Stsfld else OpCodes.Stfld, fieldInfo) @@ -1399,7 +1390,7 @@ abstract class GenMSIL extends SubComponent { } var doEmit: Boolean = true - types.get(msym.owner.asInstanceOf[clrTypes.global.Symbol]) match { + types.get(msym.owner) match { case Some(typ) if (typ.IsEnum) => { def negBool = { mcode.Emit(OpCodes.Ldc_I4_0) @@ -1423,7 +1414,7 @@ abstract class GenMSIL extends SubComponent { } // method: implicit view(FunctionX[PType0, PType1, ...,PTypeN, ResType]):DelegateType - val (isDelegateView, paramType, resType) = atPhase(currentRun.typerPhase){ + val (isDelegateView, paramType, resType) = atPhase(currentRun.typerPhase) { msym.tpe match { case MethodType(params, resultType) if (params.length == 1 && msym.name == nme.view_) => @@ -1605,7 +1596,7 @@ abstract class GenMSIL extends SubComponent { lastBlock = b // this way, saveResult knows lastBlock - if (bb2exHInstructions.contains(b)){ + if (bb2exHInstructions.contains(b)) { bb2exHInstructions(b).foreach((i) => i match { case BeginExceptionBlock(handler) => () case BeginCatchBlock(handler, exType) => () @@ -1882,9 +1873,9 @@ abstract class GenMSIL extends SubComponent { mf = mf | FieldAttributes.Static else { mf = mf | MethodAttributes.Virtual - if (sym.isFinal && !types(sym.owner.asInstanceOf[clrTypes.global.Symbol]).IsInterface) + if (sym.isFinal && !types(sym.owner).IsInterface) mf = mf | MethodAttributes.Final - if (sym.hasFlag(Flags.DEFERRED) || types(sym.owner.asInstanceOf[clrTypes.global.Symbol]).IsInterface) + if (sym.hasFlag(Flags.DEFERRED) || types(sym.owner).IsInterface) mf = mf | MethodAttributes.Abstract } } @@ -1934,7 +1925,7 @@ abstract class GenMSIL extends SubComponent { if (sym.tpe.paramTypes.length == 1) { toTypeKind(sym.tpe.paramTypes(0)) match { case ARRAY(elem) => - if (elem.toType.typeSymbol == definitions.StringClass){ + if (elem.toType.typeSymbol == definitions.StringClass) { return true } case _ => () @@ -1977,35 +1968,39 @@ abstract class GenMSIL extends SubComponent { sym.tpe.paramTypes.map(msilType).toArray } - def getType(sym: Symbol): MsilType = types.get(sym.asInstanceOf[clrTypes.global.Symbol]) match { + def getType(sym: Symbol): MsilType = types.get(sym) match { case Some(typ) => typ case None => - val name = if (sym.isModuleClass && !sym.isTrait) sym.fullNameString + "$" - else sym.fullNameString + def typeString(sym: Symbol): String = { + val s = if (sym.isNestedClass) typeString(sym.owner) +"+"+ sym.simpleName + else sym.fullNameString + if (sym.isModuleClass && !sym.isTrait) s + "$" else s + } + val name = typeString(sym) val typ = clrTypes.getType(name) if (typ == null) throw new Error(showsym(sym) + " with name " + name) else { - clrTypes.types(sym.asInstanceOf[clrTypes.global.Symbol]) = typ + clrTypes.types(sym) = typ typ } } def mapType(sym: Symbol, mType: MsilType) { assert(mType != null, showsym(sym)) - types(sym.asInstanceOf[clrTypes.global.Symbol]) = mType + types(sym) = mType } def createTypeBuilder(iclass: IClass) { def msilTypeFromSym(sym: Symbol): MsilType = { - types.get(sym.asInstanceOf[clrTypes.global.Symbol]) match { + types.get(sym) match { case Some(mtype) => mtype - case None => createTypeBuilder(classes(sym)); types(sym.asInstanceOf[clrTypes.global.Symbol]) + case None => createTypeBuilder(classes(sym)); types(sym) } } val sym = iclass.symbol - if (types contains sym.asInstanceOf[clrTypes.global.Symbol]) return + if (types contains sym) return def isInterface(s: Symbol) = s.isTrait && !s.isImplClass val parents: List[Type] = @@ -2019,9 +2014,9 @@ abstract class GenMSIL extends SubComponent { val interfaces: Array[MsilType] = parents.tail.map(p => msilTypeFromSym(p.typeSymbol)).toArray if (parents.length > 1) { - if (settings.debug.value){ + if (settings.debug.value) { log("interfaces:") - for (i <- 0.until(interfaces.length)){ + for (i <- 0.until(interfaces.length)) { log(" type: " + parents(i + 1).typeSymbol + ", msil type: " + interfaces(i)) } } @@ -2060,7 +2055,7 @@ abstract class GenMSIL extends SubComponent { var attributes = msilFieldFlags(sym) val fBuilder = mtype.DefineField(msilName(sym), msilType(sym.tpe), attributes) - fields(sym.asInstanceOf[clrTypes.global.Symbol]) = fBuilder + fields(sym) = fBuilder addAttributes(fBuilder, sym.annotations) } @@ -2088,10 +2083,10 @@ abstract class GenMSIL extends SubComponent { var resType = msilType(m.returnType) val method = ownerType.DefineMethod(getMethodName(sym), attr, resType, paramTypes) - for (i <- 0.until(paramTypes.length)){ + for (i <- 0.until(paramTypes.length)) { method.DefineParameter(i, ParameterAttributes.None, msilName(m.params(i).sym)) } - if (!methods.contains(sym.asInstanceOf[clrTypes.global.Symbol])) + if (!methods.contains(sym)) mapMethod(sym, method) addAttributes(method, sym.annotations) if (settings.debug.value) @@ -2137,7 +2132,7 @@ abstract class GenMSIL extends SubComponent { (FieldAttributes.Public | //FieldAttributes.InitOnly | FieldAttributes.Static).toShort) - fields(sym.asInstanceOf[clrTypes.global.Symbol]) = fb + fields(sym) = fb } @@ -2152,20 +2147,25 @@ abstract class GenMSIL extends SubComponent { // TODO: get module field for modules not defined in the // source currently compiling (e.g. Console) - fields get moduleClassSym.asInstanceOf[clrTypes.global.Symbol] match { + fields get moduleClassSym match { case Some(sym) => sym case None => //val mclass = types(moduleClassSym) val mClass = clrTypes.getType(moduleClassSym.fullNameString + "$") val mfield = mClass.GetField("MODULE$") assert(mfield ne null, "module not found " + showsym(moduleClassSym)) - fields(moduleClassSym.asInstanceOf[clrTypes.global.Symbol]) = mfield + fields(moduleClassSym) = mfield mfield } //fields(moduleClassSym) } + /** Adds a static initializer which creates an instance of the module + * class (calls the primary constructor). A special primary constructor + * will be generated (notInitializedModules) which stores the new intance + * in the MODULE$ field right after the super call. + */ private def addStaticInit(sym: Symbol) { val tBuilder = getType(sym).asInstanceOf[TypeBuilder] @@ -2176,7 +2176,7 @@ abstract class GenMSIL extends SubComponent { val sicode = staticInit.GetILGenerator() - val instanceConstructor = constructors(sym.primaryConstructor.asInstanceOf[clrTypes.global.Symbol]) + val instanceConstructor = constructors(sym.primaryConstructor) // there are no constructor parameters. assuming the constructor takes no parameter // is fine: we call (in the static constructor) the constructor of the module class, @@ -2199,7 +2199,6 @@ abstract class GenMSIL extends SubComponent { TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed, - //FIXME: an object may have a super-type (a class, not an object) -> not in mirror class? MOBJECT, MsilType.EmptyTypes) @@ -2328,7 +2327,7 @@ abstract class GenMSIL extends SubComponent { // ##################################################################### // get and create methods / constructors - def getConstructor(sym: Symbol): ConstructorInfo = constructors.get(sym.asInstanceOf[clrTypes.global.Symbol]) match { + def getConstructor(sym: Symbol): ConstructorInfo = constructors.get(sym) match { case Some(constr) => constr case None => val mClass = getType(sym.owner) @@ -2345,7 +2344,7 @@ abstract class GenMSIL extends SubComponent { } def mapConstructor(sym: Symbol, cInfo: ConstructorInfo) = { - constructors(sym.asInstanceOf[clrTypes.global.Symbol]) = cInfo + constructors(sym) = cInfo } private def getMethod(sym: Symbol): MethodInfo = { @@ -2360,7 +2359,7 @@ abstract class GenMSIL extends SubComponent { // case SRToShort => toShort // case _ => - methods.get(sym.asInstanceOf[clrTypes.global.Symbol]) match { + methods.get(sym) match { case Some(method) => method case None => val mClass = getType(sym.owner) @@ -2391,7 +2390,7 @@ abstract class GenMSIL extends SubComponent { */ private def mapMethod(sym: Symbol, mInfo: MethodInfo) { assert (mInfo != null, mInfo) - methods(sym.asInstanceOf[clrTypes.global.Symbol]) = mInfo + methods(sym) = mInfo } /* @@ -2463,12 +2462,12 @@ abstract class GenMSIL extends SubComponent { alternatives.find(s => { var i: Int = 0 var typesOK: Boolean = true - if (paramTypes.length == s.tpe.paramTypes.length){ - while(i < paramTypes.length){ + if (paramTypes.length == s.tpe.paramTypes.length) { + while(i < paramTypes.length) { if (paramTypes(i) != s.tpe.paramTypes(i)) typesOK = false i += 1 - } + } } else { typesOK = false } diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index e8d2faad4..b7e946c8c 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -392,7 +392,7 @@ self => println("typeMembers at "+tree+" "+tree.tpe) val context = doLocateContext(pos) val superAccess = tree.isInstanceOf[Super] - val scope = newScope + val scope = new Scope val members = new LinkedHashMap[Symbol, TypeMember] def addTypeMember(sym: Symbol, pre: Type, inherited: Boolean, viaView: Symbol) { val symtpe = pre.memberType(sym) diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 37de6ae8a..c2b55f800 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -156,7 +156,7 @@ trait Definitions { ) lazy val EqualsPatternClass = { val clazz = newClass(ScalaPackageClass, nme.EQUALS_PATTERN_NAME, Nil) - clazz setInfo PolyType(List(newTypeParam(clazz, 0)), ClassInfoType(anyparam, newClassScope(clazz), clazz)) + clazz setInfo PolyType(List(newTypeParam(clazz, 0)), ClassInfoType(anyparam, new Scope, clazz)) clazz } @@ -460,7 +460,7 @@ trait Definitions { private def newClass(owner: Symbol, name: Name, parents: List[Type]): Symbol = { val clazz = owner.newClass(NoPosition, name.toTypeName) - clazz.setInfo(ClassInfoType(parents, newClassScope(clazz), clazz)) + clazz.setInfo(ClassInfoType(parents, new Scope, clazz)) owner.info.decls.enter(clazz) clazz } @@ -478,7 +478,7 @@ trait Definitions { clazz.setInfo( PolyType( List(tparam), - ClassInfoType(List(AnyRefClass.tpe, p), newClassScope(clazz), clazz))) + ClassInfoType(List(AnyRefClass.tpe, p), new Scope, clazz))) } private def newAlias(owner: Symbol, name: Name, alias: Type): Symbol = { @@ -553,7 +553,7 @@ trait Definitions { val module = ScalaPackageClass.newModule(NoPosition, name) ScalaPackageClass.info.decls.enter(module) val mclass = module.moduleClass - mclass.setInfo(ClassInfoType(List(), newClassScope(mclass), mclass)) + mclass.setInfo(ClassInfoType(List(), new Scope, mclass)) module.setInfo(mclass.tpe) val box = newMethod(mclass, nme.box, List(clazz.typeConstructor), @@ -720,7 +720,7 @@ trait Definitions { if (isInitialized) return isInitialized = true - EmptyPackageClass.setInfo(ClassInfoType(List(), newClassScope(EmptyPackageClass), EmptyPackageClass)) + EmptyPackageClass.setInfo(ClassInfoType(List(), new Scope, EmptyPackageClass)) EmptyPackage.setInfo(EmptyPackageClass.tpe) RootClass.info.decls.enter(EmptyPackage) RootClass.info.decls.enter(RootPackage) diff --git a/src/compiler/scala/tools/nsc/symtab/Scopes.scala b/src/compiler/scala/tools/nsc/symtab/Scopes.scala index 3f17a8887..38016a4c8 100644 --- a/src/compiler/scala/tools/nsc/symtab/Scopes.scala +++ b/src/compiler/scala/tools/nsc/symtab/Scopes.scala @@ -16,9 +16,6 @@ package symtab // done for performance (and could be reviewed). // Another addition is a lookupAll method that returns all symbols with // a name in a scopein an iterator. -// I still have to remove all the cruft about PackageScope's and the like -// that's a leftover from the old Eclipse plugin days. -// trait Scopes { self: SymbolTable => @@ -40,92 +37,14 @@ trait Scopes { * @param owner ... * @return ... */ - def newScopeEntry(sym: Symbol, owner: Scope): ScopeEntry = { + private def newScopeEntry(sym: Symbol, owner: Scope): ScopeEntry = { val e = new ScopeEntry(sym, owner) e.next = owner.elems owner.elems = e e } - // Martin: This code contains a lot of stuff for the old Eclipse plugin. - // Now it's just needless complexity, which should be eleminated. - // We should make the elems list doubly-linked, - // and have scopes inherit from LinearSeq, - // that way, we need to do way fewer toList than before. - - /** - * @param initElems ... - * @return ... - */ - def newScope(initElems: ScopeEntry): Scope = new NormalScope(initElems) - - final def newScope: Scope = newScope(null: ScopeEntry) - - trait PackageScopeDependMap { - def createDepend(from : Symbol, name : Name) : Unit - } - - def newPackageScope(depends0 : PackageScopeDependMap) : PackageScope = { - object MyPackageScope extends NormalScope(null : ScopeEntry) with PackageScope { - val depends = depends0 - } - MyPackageScope - } - - def newTempScope = newScope(null : ScopeEntry) - class ScopeKind(name : String) { override def toString = name } - def allocateScopeKind(name : String) = new ScopeKind(name) - lazy val Constructor0ScopeKind : ScopeKind = allocateScopeKind("constructors0") - lazy val Constructor1ScopeKind : ScopeKind = allocateScopeKind("constructors1") - lazy val InnerScopeKind : ScopeKind = allocateScopeKind("inner") - lazy val FinishWithScopeKind : ScopeKind = allocateScopeKind("finishWith") - lazy val TypeSigScopeKind : ScopeKind = allocateScopeKind("typeSig") - lazy val PolyTypeCompleterScopeKind : ScopeKind = allocateScopeKind("polyType") - lazy val CompoundTreeScopeKind : ScopeKind = allocateScopeKind("compoundTree") - lazy val FreshArgScopeKind : ScopeKind = allocateScopeKind("freshArgs") - lazy val LabelScopeKind : ScopeKind = allocateScopeKind("label") - lazy val TypedCasesScopeKind : ScopeKind = allocateScopeKind("typedCases") - lazy val TypedDefScopeKind : ScopeKind = allocateScopeKind("typedDef") - //lazy val ParentTypesScopeKind : ScopeKind = allocateScopeKind("parentType") - lazy val TypedScopeKind : ScopeKind = allocateScopeKind("typed") - // have to sometimes use constructor depth unfortunately. - case class ParentTypesScopeKind(clazz : Symbol) extends ScopeKind("parentType") { override def toString = super.toString + "-" + clazz } - case class BlockScopeKind(depth : Int) extends ScopeKind("block") { override def toString = super.toString + "-" + depth } - - def newClassScope(clazz : Symbol) = newScope // for use in ClassInfoType creation - def scopeFor( tree : Tree, kind : ScopeKind) : Scope = newScope - def scopeFor(old : Scope, tree : Tree, kind : ScopeKind) : Scope = newScope(old) - - final def newScope(base: Scope) : Scope = newScope(base.elems) - final def newScope(decls: List[Symbol]) : Scope = { - val ret = newScope - decls foreach ret.enter - ret - } - def newThrowAwayScope(decls : List[Symbol]) : Scope = newScope(decls) - // for symbols that don't exist in scopes! - def recycle(sym : Symbol) : Symbol = sym - def newLocalDummy(clazz : Symbol, pos : util.Position) = clazz.newLocalDummy(pos) - - private class NormalScope(initElems: ScopeEntry) extends Scope(initElems) - - trait PackageScope extends Scope { - val depends : PackageScopeDependMap - override def lookupEntryWithContext(name : Name)(from : Symbol) = { - if (from != NoSymbol && depends != null) { - depends.createDepend(from,name) - } - super.lookupEntryWithContext(name)(from) - } - override def lookupWithContext(name : Name)(from : Symbol) = { - if (from != NoSymbol && depends != null) { - depends.createDepend(from,name) - } - super.lookupWithContext(name)(from) - } - } - - abstract class Scope(initElems: ScopeEntry) extends Iterable[Symbol] { + class Scope(initElems: ScopeEntry) extends Iterable[Symbol] { var elems: ScopeEntry = initElems @@ -167,17 +86,10 @@ trait Scopes { /** Returns a new scope with the same content as this one. */ def cloneScope: Scope = { - val clone = newScope + val clone = new Scope() this.toList foreach (clone enter _) clone } - /* clear the contents of this scope */ - def clear = { - elems = null - elemsCache = null - hashtable = null - } - /** is the scope empty? */ override def isEmpty: Boolean = elems eq null @@ -212,7 +124,7 @@ trait Scopes { * * @param sym ... */ - def enter(sym: Symbol) : Symbol = { enter(newScopeEntry(sym, this)); sym } + def enter(sym: Symbol): Symbol = { enter(newScopeEntry(sym, this)); sym } /** enter a symbol, asserting that no symbol with same name exists in scope * @@ -314,11 +226,6 @@ trait Scopes { def next: Symbol = { val r = e.sym; e = lookupNextEntry(e); r } } - /** Can lookup symbols and trace who the client is. - */ - def lookupEntryWithContext(name : Name)(from : Symbol) : ScopeEntry = lookupEntry(name) - def lookupWithContext(name : Name)(from : Symbol) : Symbol = lookup(name) - /** lookup a symbol entry matching given name. * @note from Martin: I believe this is a hotspot or will be one * in future versions of the type system. I have reverted the previous @@ -375,7 +282,7 @@ trait Scopes { override def foreach[U](p: Symbol => U): Unit = toList foreach p override def filter(p: Symbol => Boolean): Scope = - if (!(toList forall p)) newScope(toList filter p) else this + if (!(toList forall p)) new Scope(toList filter p) else this override def mkString(start: String, sep: String, end: String) = toList.map(_.defString).mkString(start, sep, end) @@ -385,8 +292,6 @@ trait Scopes { /** Return the nesting level of this scope, i.e. the number of times this scope * was nested in another */ def nestingLevel = nestinglevel - - def invalidate(name : Name) = {} } /** The empty scope (immutable). @@ -399,22 +304,6 @@ trait Scopes { /** The error scope. */ - class ErrorScope(owner: Symbol) extends Scope(null: ScopeEntry) { - /* The following method was intended to be here, - * but it was written (in two different iterations!) so that - * it was actually a no-op. That's why I am leaving it comment-out - * for now. - override def lookupEntry(name: Name): ScopeEntry = { - def errorSym = - if (name.isTermName) owner newErrorValue name - else owner newErrorClass name - - super.lookupEntry(name) match { - case null => enter(errorSym); lookupEntry(name) - case e => e - } - } - */ - } + class ErrorScope(owner: Symbol) extends Scope(null: ScopeEntry) } diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index fa10a2577..d785721fe 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -14,7 +14,7 @@ import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute} import scala.collection.mutable.{HashMap, HashSet} import scala.compat.Platform.currentTime import scala.tools.nsc.io.AbstractFile -import scala.tools.nsc.util.{Position, NoPosition} +import scala.tools.nsc.util.{Position, NoPosition, ClassPath, ClassRep, JavaClassPath, MsilClassPath} import classfile.ClassfileParser import Flags._ @@ -27,38 +27,42 @@ abstract class SymbolLoaders { val global: Global import global._ - /** A lazy type that completes itself by calling parameter doComplete. - * Any linked modules/classes or module classes are also initialized. - * - * @param doComplete The type completion procedure to be run. - * It takes symbol to compkete as parameter and returns - * name of file loaded for completion as a result. - * Can throw an IOException on error. + /** + * A lazy type that completes itself by calling parameter doComplete. + * Any linked modules/classes or module classes are also initialized. */ abstract class SymbolLoader extends LazyType { /** Load source or class file for `root', return */ protected def doComplete(root: Symbol): Unit + + protected def sourcefile: Option[AbstractFile] = None - /** The kind of file that's processed by this loader */ - protected def kindString: String + /** + * Description of the resource (ClassPath, AbstractFile, MSILType) + * being processed by this loader + */ + protected def description: String private var ok = false - def sourceFile: AbstractFile = null - protected def sourceString: String - + private def setSource(sym: Symbol) { + sourcefile map (sf => sym match { + case cls: ClassSymbol => cls.sourceFile = sf + case mod: ModuleSymbol => mod.moduleClass.sourceFile = sf + case _ => () + }) + } override def complete(root: Symbol) : Unit = { try { val start = currentTime val currentphase = phase doComplete(root) phase = currentphase - def source = kindString + " " + sourceString - informTime("loaded " + source, start) - //if (root.rawInfo == this && root.linkedSym.rawInfo == this) - // throw new TypeError(source + " does not define " + root) + informTime("loaded " + description, start) ok = true + setSource(root) + setSource(root.linkedSym) // module -> class, class -> module } catch { case ex: IOException => ok = false @@ -84,115 +88,84 @@ abstract class SymbolLoaders { } } - /** Load contents of a package + /** + * Load contents of a package */ - class PackageLoader(val directory: global.classPath0.Context) extends SymbolLoader { + abstract class PackageLoader[T](classpath: ClassPath[T]) extends SymbolLoader { + protected def description = "package loader "+ classpath.name - // XXX: for IDE. - protected def sourceString = directory.toString() - - protected def kindString: String = "directory path" - - protected def newPackageLoader(dir: global.classPath0.Context): PackageLoader = - new PackageLoader(dir) - - protected def checkSource(name: String, source: AbstractFile): Boolean = source ne null - - var root: Symbol = _ - - def enterPackage(name: String, completer: SymbolLoader) { + def enterPackage(root: Symbol, name: String, completer: SymbolLoader) { val preExisting = root.info.decls.lookup(newTermName(name)) if (preExisting != NoSymbol) throw new TypeError( root+" contains object and package with same name: "+name+"\none of them needs to be removed from classpath") - val pkg = root.newPackage(NoPosition, newTermName(name)) pkg.moduleClass.setInfo(completer) pkg.setInfo(pkg.moduleClass.tpe) root.info.decls.enter(pkg) } - // @return - the symbol of the class - def enterClassAndModule(name: String, completer: SymbolLoader): Symbol = { + + def enterClassAndModule(root: Symbol, name: String, completer: SymbolLoader) { val owner = if (root.isRoot) definitions.EmptyPackageClass else root val className = newTermName(name) assert(owner.info.decls.lookup(name) == NoSymbol, owner.fullNameString + "." + name) - var clazz = owner.newClass(NoPosition, name.toTypeName) - var module = owner.newModule(NoPosition, name) + val clazz = owner.newClass(NoPosition, name.toTypeName) + val module = owner.newModule(NoPosition, name) clazz setInfo completer module setInfo completer module.moduleClass setInfo moduleClassLoader - clazz = (owner.info.decls enter clazz).asInstanceOf[ClassSymbol] - module = (owner.info.decls enter module).asInstanceOf[ModuleSymbol] + owner.info.decls enter clazz + owner.info.decls enter module assert(clazz.linkedModuleOfClass == module, module) assert(module.linkedClassOfModule == clazz, clazz) - clazz } - def checkAdd(name0 : String) = { - var name = name0 - while ((name indexOf '$') != -1) { - name = name.substring(0, name indexOf '$') - } - } - lazy val scope = newPackageScope(computeDepends(this)) + + /** + * Tells wether a class with both a binary and a source representation + * (found in classpath and in sourcepath) should be re-compiled. Behaves + * similar to javac, i.e. if the source file is newer than the classfile, + * a re-compile is triggered. + */ + protected def needCompile(bin: T, src: AbstractFile): Boolean + + /** + * Tells wether a class should be loaded and entered into the package + * scope. On .NET, this method returns `false' for all synthetic classes + * (anonymous classes, implementation classes, module classes), their + * symtab is encoded in the pickle of another class. + */ + protected def doLoad(cls: ClassRep[T]): Boolean + + protected def newClassLoader(bin: T): SymbolLoader + + protected def newPackageLoader(pkg: ClassPath[T]): SymbolLoader + protected def doComplete(root: Symbol) { assert(root.isPackageClass, root) - this.root = root - root.setInfo(new PackageClassInfoType(scope, root, this)) - refresh() - } - def refresh() { - /** Is the given name a valid input file base name? */ - def isValid(name: String): Boolean = - name.length() > 0 && (!name.endsWith("$class") || settings.XO.value) + root.setInfo(new PackageClassInfoType(new Scope(), root)) - val classes = new HashMap[String, global.classPath0.Context] - val packages = new HashMap[String, global.classPath0.Context] - - def recordClass(file: AbstractFile, extension: String, classOK: global.classPath0.Context => Boolean) { - if (!file.isDirectory && file.name.endsWith(extension)) { - val name = file.name.substring(0, file.name.length - extension.length) - if (isValid(name) && !classes.isDefinedAt(name)) { - val clazz = directory.find(name, false) - if ((clazz ne null) && classOK(clazz)) classes(name) = clazz - } + val sourcepaths = classpath.sourcepaths + for (classRep <- classpath.classes if doLoad(classRep)) { + if (classRep.binary.isDefined && classRep.source.isDefined) { + val (bin, src) = (classRep.binary.get, classRep.source.get) + val loader = if (needCompile(bin, src)) new SourcefileLoader(src) + else newClassLoader(bin) + enterClassAndModule(root, classRep.name, loader) + } else if (classRep.binary.isDefined) { + enterClassAndModule(root, classRep.name, newClassLoader(classRep.binary.get)) + } else if (classRep.source.isDefined) { + enterClassAndModule(root, classRep.name, new SourcefileLoader(classRep.source.get)) } } - for (dir <- directory.entries) if ((dir.location ne null) && dir.location.isDirectory) { - for (file <- dir.location) { - if (file.isDirectory && directory.validPackage(file.name) && !packages.isDefinedAt(file.name)) - packages(file.name) = directory.find(file.name, true); - else if (!global.forMSIL) - recordClass(file, ".class", source => true) - } + for (pkg <- classpath.packages) { + enterPackage(root, pkg.name, newPackageLoader(pkg)) } - for (dir <- directory.entries) if (dir.source ne null) { - for (file <- dir.source.location) { - if (file.isDirectory && directory.validPackage(file.name) && !packages.isDefinedAt(file.name)) - packages(file.name) = directory.find(file.name, true) - else if (dir.source.compile) - recordClass(file, ".scala", source => checkSource(file.name, source.sourceFile)) - } - } - - // do classes first - for ((name, file) <- classes.iterator) { - val loader = if (!file.isSourceFile) { - new ClassfileLoader(file.classFile, file.sourceFile, file.sourcePath) - } else { - assert(file.sourceFile ne null) - new SourcefileLoader(file.sourceFile) - } - enterClassAndModule(name, loader) - } - - // packages second - for ((name, file) <- packages.iterator) - enterPackage(name, newPackageLoader(file)) // if there's a $member object, enter its members as well. val pkgModule = root.info.decl(nme.PACKAGEkw) - if (pkgModule.isModule && !pkgModule.rawInfo.isInstanceOf[SourcefileLoader]) + if (pkgModule.isModule && !(pkgModule.rawInfo.isInstanceOf[SourcefileLoader] && + classpath.name == "scala")) openPackageModule(pkgModule) } } @@ -210,120 +183,88 @@ abstract class SymbolLoaders { } } - class NamespaceLoader(directory: global.classPath0.Context) extends PackageLoader(directory) { + class JavaPackageLoader(classpath: ClassPath[AbstractFile]) extends PackageLoader(classpath) { + protected def needCompile(bin: AbstractFile, src: AbstractFile) = + (src.lastModified >= bin.lastModified) - override protected def kindString: String = "namespace " + namespace + protected def doLoad(cls: ClassRep[AbstractFile]) = true - override protected def sourceString = "" + protected def newClassLoader(bin: AbstractFile) = + new ClassfileLoader(bin) - override def newPackageLoader(dir: global.classPath0.Context): PackageLoader = - new NamespaceLoader(dir) + protected def newPackageLoader(pkg: ClassPath[AbstractFile]) = + new JavaPackageLoader(pkg) + } - val types = new HashMap[String, MSILType]() - - val namespaces = new HashSet[String]() - - def namespace: String = if (root.isRoot) "" else root.fullNameString - - // TODO: Add check whether the source is newer than the assembly - override protected def checkSource(name: String, source: AbstractFile): Boolean = { - val result = (source ne null) && !types.contains(name) - if (!result && settings.debug.value) - Console.println("Skipping source file " + source) - result - } - - override protected def doComplete(root: Symbol) { - clrTypes.collectMembers(root, types, namespaces) - - super.doComplete(root) - - for (namespace <- namespaces.iterator) { - val oldPkg = root.info.decls lookup newTermName(namespace) - if (oldPkg == NoSymbol) - enterPackage(namespace, new NamespaceLoader(new classPath0.Context(List()))) - //else System.out.println("PackageLoader: package already in scope: " + oldPkg.fullNameString) - } - - // import the CLR types contained in the package (namespace) - for ((name, typ) <- types.iterator) { - assert(namespace == typ.Namespace, typ.FullName) + class NamespaceLoader(classpath: ClassPath[MSILType]) extends PackageLoader(classpath) { + protected def needCompile(bin: MSILType, src: AbstractFile) = + (!src.name.endsWith(".java")) + protected def doLoad(cls: ClassRep[MSILType]) = { + if (cls.binary.isDefined) { + val typ = cls.binary.get if (typ.IsDefined(clrTypes.SCALA_SYMTAB_ATTR, false)) { val attrs = typ.GetCustomAttributes(clrTypes.SCALA_SYMTAB_ATTR, false) assert (attrs.length == 1, attrs.length) val a = attrs(0).asInstanceOf[MSILAttribute] - if (a.getConstructor() == clrTypes.SYMTAB_CONSTR) - enterClassAndModule(name, new MSILTypeLoader(typ)) - } - else - enterClassAndModule(name, new MSILTypeLoader(typ)) - } - - val pkgModule = root.info.decl(nme.PACKAGEkw) - if (pkgModule.isModule && !pkgModule.rawInfo.isInstanceOf[SourcefileLoader]) - openPackageModule(pkgModule) + // symtab_constr takes a byte array argument (the pickle), i.e. typ has a pickle. + // otherwise, symtab_default_constr was used, which marks typ as scala-synthetic. + a.getConstructor() == clrTypes.SYMTAB_CONSTR + } else true // always load non-scala types + } else true // always load source } - } // NamespaceLoader - class MSILTypeLoader(typ: MSILType) extends SymbolLoader { - private object typeParser extends clr.TypeParser { - val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global - } - protected def doComplete(root: Symbol) { - typeParser.parse(typ, root.asInstanceOf[typeParser.global.loaders.clrTypes.global.Symbol]) // don't check this - } - protected def kindString: String = typ.FullName - protected def sourceString = typ.Assembly.FullName - } - // IDE hook. - protected def completeClassfile(root : Symbol, loader : ClassfileLoader)(f : => Unit) : Unit = f - // incremental builder hook - protected def computeDepends(loader : PackageLoader) : PackageScopeDependMap = { - null + protected def newClassLoader(bin: MSILType) = + new MSILTypeLoader(bin) + + protected def newPackageLoader(pkg: ClassPath[MSILType]) = + new NamespaceLoader(pkg) + } - class ClassfileLoader(val classFile: AbstractFile, override val sourceFile: AbstractFile, sourcePath0: AbstractFile) extends SymbolLoader { + class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader { + + /** + * @FIXME: iulian, + * there should not be a new ClassfileParser for every loaded classfile, this object + * should be outside the class ClassfileLoader! This was changed by Sean in r5494. + * + * However, when pulling it out, loading "java.lang.Object" breaks with: + * "illegal class file dependency between java.lang.Object and java.lang.Class" + */ private object classfileParser extends ClassfileParser { val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global - override def sourcePath = sourcePath0 /* could be null */ } + + protected def description = "class file "+ classfile.toString + protected def doComplete(root: Symbol) { - completeClassfile(root, this) { - classfileParser.parse(classFile, root) - } - root match { - case clazz: ClassSymbol => - if ((sourceFile ne null) && (clazz.sourceFile eq null)) - clazz.sourceFile = sourceFile - case module: ModuleSymbol if module.moduleClass.isInstanceOf[ClassSymbol] => - val clazz = module.moduleClass.asInstanceOf[ClassSymbol] - if ((sourceFile ne null) && (clazz.sourceFile eq null)) - clazz.sourceFile = sourceFile - case _ => - } - if (root.sourceFile ne null) - prepareReset(root, this) + classfileParser.parse(classfile, root) } - protected def kindString: String = "class file" - protected def sourceString = classFile.toString() } - class SourcefileLoader(override val sourceFile: AbstractFile) extends SymbolLoader { - protected def doComplete(root: Symbol): Unit = global.currentRun.compileLate(sourceFile) - protected def kindString: String = "source file" - protected def sourceString = sourceFile.toString() + class MSILTypeLoader(typ: MSILType) extends SymbolLoader { + protected def description = "MSILType "+ typ.FullName + ", assembly "+ typ.Assembly.FullName + protected def doComplete(root: Symbol) { typeParser.parse(typ, root) } + } + + class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader { + protected def description = "source file "+ srcfile.toString + override protected def sourcefile = Some(srcfile) + protected def doComplete(root: Symbol): Unit = global.currentRun.compileLate(srcfile) } object moduleClassLoader extends SymbolLoader { + protected def description = "module class loader" protected def doComplete(root: Symbol) { root.sourceModule.initialize } - protected def kindString: String = "" - protected def sourceString = "" + } + + private object typeParser extends clr.TypeParser { + val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global } object clrTypes extends clr.CLRTypes { val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global if (global.forMSIL) init() } - } diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala index bcf899d17..5a4139aa0 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala @@ -42,12 +42,6 @@ abstract class SymbolTable extends Names } def notifyImport(what : Name, container : Type, from : Name, to : Name) : Unit = {} def sanitize(tree : Tree) : Tree = tree - def attachSource(symbol : ClassSymbol, file : io.AbstractFile) : Unit = { - assert(symbol != null) - } - def prepareReset(symbol : Symbol, tpe : LazyType) : Unit = { - assert(symbol != null) - } /** A period is an ordinal number for a phase in a run. * Phases in later runs have higher periods than phases in earlier runs. diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index b7dae2a97..8402ff85c 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -1822,7 +1822,6 @@ trait Symbols { if (owner.isPackageClass) source else super.sourceFile override def sourceFile_=(f: AbstractFile) { //System.err.println("set source file of " + this + ": " + f); - attachSource(this, f) source = f } override def isFromClassFile = { diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index c7cf6df20..39389d6da 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -756,7 +756,7 @@ trait Types { while (!bcs.isEmpty) { val decls = bcs.head.info.decls var entry = - if (name == nme.ANYNAME) decls.elems else decls.lookupEntryWithContext(name)(from) + if (name == nme.ANYNAME) decls.elems else decls.lookupEntry(name) while (entry ne null) { val sym = entry.sym if (sym.getFlag(requiredFlags) == requiredFlags) { @@ -779,10 +779,10 @@ trait Types { if (self eq null) self = this.narrow; (self.memberType(member) matches self.memberType(sym)) })) { - members = newThrowAwayScope(List(member, sym)) + members = new Scope(List(member, sym)) } } else { - var prevEntry = members.lookupEntryWithContext(sym.name)(from) + var prevEntry = members.lookupEntry(sym.name) while ((prevEntry ne null) && !(prevEntry.sym == sym || prevEntry.sym.owner != sym.owner && @@ -1422,10 +1422,8 @@ trait Types { override def kind = "ClassInfoType" } - class PackageClassInfoType(decls: Scope, clazz: Symbol, val lazyLoader : LazyType) - extends ClassInfoType(List(), decls, clazz) { - def reset = clazz.setInfo(lazyLoader) - } + class PackageClassInfoType(decls: Scope, clazz: Symbol) + extends ClassInfoType(List(), decls, clazz) /** A class representing a constant type. * @@ -2230,8 +2228,7 @@ A type's typeSymbol should never be inspected directly. /** The canonical creator for this-types */ def mkThisType(sym: Symbol): Type = { - class UniqueThisType extends ThisType(sym) with UniqueType - if (phase.erasedTypes) sym.tpe else unique(new UniqueThisType) + if (phase.erasedTypes) sym.tpe else unique(new ThisType(sym) with UniqueType) } /** The canonical creator for single-types */ @@ -2244,9 +2241,7 @@ A type's typeSymbol should never be inspected directly. var sym1 = rebind(pre, sym) val pre1 = removeSuper(pre, sym1) if (pre1 ne pre) sym1 = rebind(pre1, sym1) - - class UniqueSingleType extends SingleType(pre1, sym1) with UniqueType - unique(new UniqueSingleType) + unique(new SingleType(pre1, sym1) with UniqueType) } } @@ -2254,18 +2249,16 @@ A type's typeSymbol should never be inspected directly. def mkSuperType(thistp: Type, supertp: Type): Type = if (phase.erasedTypes) supertp else { - class UniqueSuperType extends SuperType(thistp, supertp) with UniqueType - unique(new UniqueSuperType) + unique(new SuperType(thistp, supertp) with UniqueType) } /** The canonical creator for type bounds */ def mkTypeBounds(lo: Type, hi: Type): TypeBounds = { - class UniqueTypeBounds extends TypeBounds(lo, hi) with UniqueType - unique(new UniqueTypeBounds) + unique(new TypeBounds(lo, hi) with UniqueType) } def refinementOfClass(clazz: Symbol, parents: List[Type], decls: Scope) = { - class RefinementOfClass extends RefinedType(parents, decls) { + class RefinementOfClass extends RefinedType(parents, decls) { override def typeSymbol: Symbol = clazz } new RefinementOfClass @@ -2280,7 +2273,7 @@ A type's typeSymbol should never be inspected directly. else { // having $anonfun as owner causes the pickler to break upon unpickling; see ticket #2323 val nonAnonOwner = (owner.ownerChain dropWhile (_.isAnonymousFunction)).headOption getOrElse NoSymbol - val clazz = recycle(nonAnonOwner.newRefinementClass(NoPosition)) + val clazz = nonAnonOwner.newRefinementClass(NoPosition) val result = refinementOfClass(clazz, parents, decls) clazz.setInfo(result) result @@ -2294,7 +2287,7 @@ A type's typeSymbol should never be inspected directly. * @return ... */ def refinedType(parents: List[Type], owner: Symbol): Type = - refinedType(parents, owner, newTempScope, owner.pos) + refinedType(parents, owner, new Scope, owner.pos) def copyRefinedType(original: RefinedType, parents: List[Type], decls: Scope) = if ((parents eq original.parents) && (decls eq original.decls)) original @@ -2750,7 +2743,7 @@ A type's typeSymbol should never be inspected directly. val elems = scope.toList val elems1 = mapOver(elems) if (elems1 eq elems) scope - else newScope(elems1) + else new Scope(elems1) } /** Map this function over given list of symbols */ @@ -4578,7 +4571,7 @@ A type's typeSymbol should never be inspected directly. else { def lubBounds(bnds: List[TypeBounds]): TypeBounds = mkTypeBounds(glb(bnds map (_.lo), decr(depth)), lub(bnds map (_.hi), decr(depth))) - recycle(lubRefined.typeSymbol.newAbstractType(proto.pos, proto.name)) + lubRefined.typeSymbol.newAbstractType(proto.pos, proto.name) .setInfo(lubBounds(symtypes map (_.bounds))) } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index c975a0256..203c34c9c 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -14,7 +14,7 @@ import java.lang.Integer.toHexString import scala.collection.immutable.{Map, ListMap} import scala.collection.mutable.{ListBuffer, ArrayBuffer} import scala.tools.nsc.io.AbstractFile -import scala.tools.nsc.util.{Position, NoPosition} +import scala.tools.nsc.util.{Position, NoPosition, ClassRep} import scala.annotation.switch /** This abstract class implements a class file parser. @@ -23,8 +23,6 @@ import scala.annotation.switch * @version 1.0 */ abstract class ClassfileParser { - def sourcePath : AbstractFile = null - val global: Global import global._ @@ -416,7 +414,7 @@ abstract class ClassfileParser { } addEnclosingTParams(clazz) - parseInnerClasses() + parseInnerClasses() // also sets the isScala / isScalaRaw / hasMeta flags, see r15956 val superType = if (isAnnotation) { in.nextChar; definitions.AnnotationClass.tpe } else pool.getSuperClass(in.nextChar).tpe val ifaceCount = in.nextChar @@ -424,8 +422,8 @@ abstract class ClassfileParser { if (isAnnotation) ifaces = definitions.ClassfileAnnotationClass.tpe :: ifaces val parents = superType :: ifaces // get the class file parser to reuse scopes. - instanceDefs = newClassScope(clazz) - staticDefs = newClassScope(statics) + instanceDefs = new Scope + staticDefs = new Scope val classInfo = ClassInfoType(parents, instanceDefs, clazz) val staticInfo = ClassInfoType(List(), staticDefs, statics) @@ -778,20 +776,7 @@ abstract class ClassfileParser { val meta = pool.getName(in.nextChar).toString().trim() metaParser.parse(meta, sym, symtype) this.hasMeta = true - case nme.SourceFileATTR => - assert(attrLen == 2) - val source = pool.getName(in.nextChar) - if (sourcePath ne null) { - val sourceFile0 = sourcePath.lookupPath(source.toString(), false) - if ((sourceFile0 ne null) && (clazz.sourceFile eq null)) { - clazz.sourceFile = sourceFile0 - } - // XXX: removing only in IDE test. Also needs to be tested in the build compiler. - if (staticModule.moduleClass != NoSymbol) { - staticModule.moduleClass.sourceFile = clazz.sourceFile - } - } - // Attribute on methods of java annotation classes when that method has a default + // Attribute on methods of java annotation classes when that method has a default case nme.AnnotationDefaultATTR => sym.addAnnotation(AnnotationInfo(definitions.AnnotationDefaultAttr.tpe, List(), List(), NoPosition)) in.skip(attrLen) @@ -926,10 +911,11 @@ abstract class ClassfileParser { for (entry <- innerClasses.valuesIterator) { // create a new class member for immediate inner classes if (entry.outerName == externalName) { - val file = global.classPath.lookupPath( - entry.externalName.replace('.', java.io.File.separatorChar).toString, false) - assert(file ne null, entry.externalName) - enterClassAndModule(entry, new global.loaders.ClassfileLoader(file, null, null), entry.jflags) + val file = global.classPath.findClass(entry.externalName.toString) match { + case Some(ClassRep(Some(binary: AbstractFile), _)) => binary + case _ => throw new AssertionError(entry.externalName) + } + enterClassAndModule(entry, new global.loaders.ClassfileLoader(file), entry.jflags) } } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index f8b8a67b0..2b78a3cca 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -14,7 +14,7 @@ import scala.collection.mutable._ import scala.tools.nsc._ import scala.tools.nsc.backend.icode._ import scala.tools.nsc.io._ -import scala.tools.nsc.util.{Position,NoPosition} +import scala.tools.nsc.util.{Position, NoPosition, ClassRep} import ClassfileConstants._ import Flags._ @@ -49,19 +49,20 @@ abstract class ICodeReader extends ClassfileParser { isScalaModule = cls.isModule && !cls.hasFlag(JAVA) log("Reading class: " + cls + " isScalaModule?: " + isScalaModule) - val name = cls.fullNameString(java.io.File.separatorChar) + (if (sym.hasFlag(MODULE)) "$" else "") - val entry = classPath.root.find(name, false) - if (entry ne null) { - classFile = entry.classFile + val name = cls.fullNameString('.') + (if (sym.hasFlag(MODULE)) "$" else "") + classPath.findClass(name) match { + case Some(ClassRep(bin, _)) => + assert(bin.isDefined, "No classfile for " + cls) + classFile = bin.get.asInstanceOf[AbstractFile] // if (isScalaModule) // sym = cls.linkedClassOfModule - assert(classFile ne null, "No classfile for " + cls) -// for (s <- cls.info.members) -// Console.println("" + s + ": " + s.tpe) - parse(classFile, sym) - } else - log("Could not find: " + cls) +// for (s <- cls.info.members) +// Console.println("" + s + ": " + s.tpe) + parse(classFile, sym) + case _ => + log("Could not find: " + cls) + } (staticCode, instanceCode) } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala index 6b1e15d3c..b8329f486 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala @@ -110,7 +110,7 @@ abstract class MetaParser{ } protected def parseClass() { - locals = newScope + locals = new Scope def parse(): Type = { nextToken() if (token == "[") { @@ -132,7 +132,7 @@ abstract class MetaParser{ protected def parseMethod() { val globals = locals - locals = if (locals eq null) newScope else newScope(locals) + locals = if (locals eq null) new Scope else new Scope(locals) def parse(): Type = { nextToken(); if (token == "[") PolyType(parseTypeParams(), parse()) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index b5c959f61..8ee7c5b44 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -51,15 +51,6 @@ abstract class Pickler extends SubComponent { add(sym, pickle) add(sym.linkedSym, pickle) pickle.finish - // pickleHash is used to track changes in a signature (-> IDE) - val doPickleHash = global.doPickleHash - if (doPickleHash) { - var i = 0 - while (i < pickle.writeIndex) { - unit.pickleHash += pickle.bytes(i).toLong // toLong needed to work around bug - i += 1 - } - } case _ => } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala index af454a017..396208f80 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -89,16 +89,10 @@ abstract class UnPickler { } /** The `decls' scope associated with given symbol */ - private def symScope(sym: Symbol, isTemp : Boolean) = symScopes.get(sym) match { - case None => - val s = if (isTemp) newTempScope - else if (sym.isClass || sym.isModuleClass || sym.isModule) newClassScope(sym); - else newScope - - symScopes(sym) = s; s + private def symScope(sym: Symbol) = symScopes.get(sym) match { + case None => val s = new Scope; symScopes(sym) = s; s case Some(s) => s } - private def symScope(sym : Symbol) : Scope = symScope(sym, false) /** Does entry represent an (internal) symbol */ private def isSymbolEntry(i: Int): Boolean = { @@ -302,7 +296,7 @@ abstract class UnPickler { val dcls = symScope(clazz) new RefinedType(ps, dcls) { override def symbol = clazz } */ - new RefinedType(until(end, readTypeRef), symScope(clazz, true)) { + new RefinedType(until(end, readTypeRef), symScope(clazz)) { override def typeSymbol = clazz } case CLASSINFOtpe => @@ -816,10 +810,8 @@ abstract class UnPickler { private class LazyTypeRef(i: Int) extends LazyType { private val definedAtRunId = currentRunId private val p = phase - // In IDE, captures class files dependencies so they can be reloaded when their dependencies change. - private val ideHook = unpickleIDEHook override def complete(sym: Symbol) : Unit = { - val tp = ideHook(at(i, readType)) + val tp = at(i, readType) if (p != phase) atPhase(p) (sym setInfo tp) else sym setInfo tp if (currentRunId != definedAtRunId) sym.setInfo(adaptToNewRunMap(tp)) diff --git a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala index 91572ce33..64450db23 100644 --- a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala +++ b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala @@ -63,20 +63,11 @@ abstract class CLRTypes { val fields: Map[Symbol, FieldInfo] = new HashMap val sym2type: Map[Type,Symbol] = new HashMap - private var alltypes: Array[Type] = _ def init() = try { // initialize -/* - val assems = new StringTokenizer(global.settings.assemrefs.value, File.pathSeparator) - while (assems.hasMoreTokens()) { - assemrefs += new File(assems.nextToken()) - } - */ - - val mscorlib = findAssembly("mscorlib.dll") - Type.initMSCORLIB(mscorlib) - findAssembly("scalaruntime.dll") - findAllAssemblies() + // the MsilClasspath (nsc/util/Classpath.scala) initializes the msil-library by calling + // Assembly.LoadFrom("mscorlib.dll"), so this type should be found + Type.initMSCORLIB(getTypeSafe("System.String").Assembly) BYTE = getTypeSafe("System.SByte") UBYTE = getTypeSafe("System.Byte") @@ -104,38 +95,20 @@ abstract class CLRTypes { SYMTAB_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(bytearray) SYMTAB_DEFAULT_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(Type.EmptyTypes) - //assert(SCALA_SYMTAB_ATTR != null) - val delegate: Type = getTypeSafe("System.Delegate") val dargs: Array[Type] = Array(delegate, delegate) DELEGATE_COMBINE = delegate.GetMethod("Combine", dargs) DELEGATE_REMOVE = delegate.GetMethod("Remove", dargs) - //assert(DELEGATE_COMBINE != null) - //assert(DELEGATE_REMOVE != null) - - - var alltypes: Array[Type] = Type.EmptyTypes - for (assem <- assemblies) { - val atypes = assem.GetTypes().filter((typ: Type) => typ.DeclaringType == null) - alltypes = Array.concat(alltypes, atypes) - } - - Sorting.stableSort(alltypes, (t1: Type, t2: Type) => (t1.FullName compareTo t2.FullName) < 0) - this.alltypes = alltypes } catch { case e: RuntimeException => Console.println(e.getMessage) - // no bloody exits! exit(1) + throw e } //########################################################################## // type mapping and lookup -// private class MyHashMap[A, B <: AnyRef] extends HashMap[A, B] { -// override def default(key: A): B = null; -// } - def getType(name: String): Type = Type.GetType(name) def getTypeSafe(name: String): Type = { @@ -147,107 +120,4 @@ abstract class CLRTypes { def mkArrayType(elemType: Type): Type = getType(elemType.FullName + "[]") def isDelegateType(t: Type): Boolean = { t.BaseType() == DELEGATE } - - //########################################################################## - // assembly loading methods - - // a list of all loaded assemblies - private var assemblies: ListBuffer[Assembly] = new ListBuffer() - - // a set of all directories and assembly files - //private var assemrefs: Set[File] = new HashSet() - - //def assembly(file : File) = assemrefs += file - - /** Load the assembly with the given name - */ - private def findAssembly(name: String): Assembly = { - // see if the assembly is referenced directly - for (file <- global.assemrefs.iterator if file.getName() == name) { - val assem = Assembly.LoadFrom(file.getPath()) - if (assem != null) { - global.assemrefs -= file - assemblies += assem - return assem - } - } - // look in directories specified with the '-r' option - for (dir <- global.assemrefs.iterator if dir.isDirectory()) { - val file = new File(dir, name) - if (file.exists()) { - val assem = Assembly.LoadFrom(file.getPath()) - if (assem != null) { - assemblies += assem - return assem - } - } - } - // try in the current directory - val file = new File(".", name) - if (file.exists()) { - val assem = Assembly.LoadFrom(file.getPath()) - if (assem != null) { - assemblies += assem - return assem - } - } - throw new RuntimeException( - "cannot find assembly " + name + "; use the -Xassem-path option to specify its location") - } - - /** Load the rest of the assemblies specified with the '-r' option - */ - private def findAllAssemblies() { - for (file <- global.assemrefs.iterator) { - if (file.isFile()) { - //System.out.println("Loading assembly " + file) - val assem = Assembly.LoadFrom(file.getPath()) - if (assem != null) { - assemblies += assem - } - } - } - global.assemrefs.clear - } - - //########################################################################## - // collect the members contained in a given namespace - - /** Find the position of the first type whose name starts with - * the given prefix; return the length of the types array if no match - * is found so the result canbe used to terminate loop conditions - */ - private def findFirst(prefix: String): Int = { - var m = 0 - var n = alltypes.length - 1 - while (m < n) { - val l = (m + n) / 2 - val res = alltypes(l).FullName.compareTo(prefix) - if (res < 0) m = l + 1 - else n = l - } - if (alltypes(m).FullName.startsWith(prefix)) m else alltypes.length - } - - /** Collects the members contained in the given Scala package (namespace) - */ - def collectMembers(pakage: Symbol, typesMap: Map[String,Type], namespacesSet: Set[String]) = { - val namespace = if (pakage.isRoot) "" else pakage.fullNameString + "." - val nl = namespace.length() - var i = findFirst(namespace) - while (i < alltypes.length && alltypes(i).FullName.startsWith(namespace)) { - val typ = alltypes(i) - if (typ.FullName != "java.lang.Object" && typ.FullName != "java.lang.String") { - val k = typ.FullName.indexOf(".", nl) - if (k < 0) { - typesMap.update(typ.Name, typ) - } else { - namespacesSet += (typ.Namespace.substring(nl, k)) - } - } - i += 1 - } - } - - //########################################################################## } // CLRTypes diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala index 92ad08fad..d12ade1ab 100644 --- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala @@ -22,8 +22,9 @@ import classfile.UnPickler abstract class TypeParser { val global: Global - import global.loaders.clrTypes - import clrTypes.global._ + + import global._ + import loaders.clrTypes //########################################################################## @@ -76,8 +77,7 @@ abstract class TypeParser { val a = attrs(0).asInstanceOf[MSILAttribute]; assert (a.getConstructor() == clrTypes.SYMTAB_CONSTR); val symtab = a.getConstructorArguments()(0).asInstanceOf[Array[Byte]] - unpickler.unpickle(symtab, 0, clazz.asInstanceOf[unpickler.global.Symbol], - staticModule.asInstanceOf[unpickler.global.Symbol], typ.FullName); + unpickler.unpickle(symtab, 0, clazz, staticModule, typ.FullName); val mClass = clrTypes.getType(typ.FullName + "$"); if (mClass != null) { clrTypes.types(statics) = mClass; @@ -93,8 +93,8 @@ abstract class TypeParser { else if (typ.IsInterface()) definitions.ObjectClass.tpe else definitions.AnyClass.tpe; // this is System.Object val parents = superType :: ifaces.map(getCLRType).toList - instanceDefs = newClassScope(clazz) - staticDefs = newClassScope(staticModule) + instanceDefs = new Scope + staticDefs = new Scope val classInfo = ClassInfoType(parents, instanceDefs, clazz) val staticInfo = ClassInfoType(List(), staticDefs, statics) @@ -112,7 +112,7 @@ abstract class TypeParser { || ntype.IsNestedFamANDAssem) || ntype.IsInterface) { - val loader = new global.loaders.MSILTypeLoader(ntype) + val loader = new loaders.MSILTypeLoader(ntype) val nclazz = statics.newClass(NoPosition, ntype.Name.toTypeName) val nmodule = statics.newModule(NoPosition, ntype.Name) nclazz.setInfo(loader) diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index e2be776d7..009ae003d 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -134,7 +134,7 @@ abstract class AddInterfaces extends InfoTransform { * @return ... */ private def implDecls(implClass: Symbol, ifaceDecls: Scope): Scope = { - val decls = newScope + val decls = new Scope if ((ifaceDecls lookup nme.MIXIN_CONSTRUCTOR) == NoSymbol) decls enter (implClass.newMethod(implClass.pos, nme.MIXIN_CONSTRUCTOR) setInfo MethodType(List(), UnitClass.tpe)) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 8cb405c1e..07f988013 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -774,7 +774,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast. //println("computing bridges for " + owner)//DEBUG assert(phase == currentRun.erasurePhase) val site = owner.thisType - val bridgesScope = newScope + val bridgesScope = new Scope val bridgeTarget = new HashMap[Symbol, Symbol] var bridges: List[Tree] = List() val opc = atPhase(currentRun.explicitOuterPhase) { diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index c89f1485f..d9b81a4bf 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -122,7 +122,7 @@ abstract class ExplicitOuter extends InfoTransform case ClassInfoType(parents, decls, clazz) => var decls1 = decls if (isInner(clazz) && !(clazz hasFlag INTERFACE)) { - decls1 = newScope(decls.toList) + decls1 = new Scope(decls.toList) val outerAcc = clazz.newMethod(clazz.pos, nme.OUTER) // 3 outerAcc expandName clazz @@ -141,7 +141,7 @@ abstract class ExplicitOuter extends InfoTransform for (mc <- clazz.mixinClasses) { val mixinOuterAcc: Symbol = atPhase(phase.next)(outerAccessor(mc)) if (mixinOuterAcc != NoSymbol) { - if (decls1 eq decls) decls1 = newScope(decls.toList) + if (decls1 eq decls) decls1 = new Scope(decls.toList) val newAcc = mixinOuterAcc.cloneSymbol(clazz) newAcc resetFlag DEFERRED setInfo (clazz.thisType memberType mixinOuterAcc) decls1 enter newAcc diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index 3a35ae5b8..408ee551b 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -39,7 +39,7 @@ abstract class Flatten extends InfoTransform { typeRef(sym.toplevelClass.owner.thisType, sym, args) case ClassInfoType(parents, decls, clazz) => var parents1 = parents - val decls1 = newScope + val decls1 = new Scope if (clazz.isPackageClass) { atPhase(phase.next)(decls.toList foreach (sym => decls1 enter sym)) } else { diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 9833ca8b5..2a4f84d70 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -342,12 +342,12 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { sourceModule setInfo sym.tpe assert(clazz.sourceModule != NoSymbol)//debug parents1 = List() - decls1 = newScope(decls.toList filter isImplementedStatically) + decls1 = new Scope(decls.toList filter isImplementedStatically) } else if (!parents.isEmpty) { parents1 = parents.head :: (parents.tail map toInterface) } } - //decls1 = atPhase(phase.next)(newScope(decls1.toList))//debug + //decls1 = atPhase(phase.next)(new Scope(decls1.toList))//debug if ((parents1 eq parents) && (decls1 eq decls)) tp else ClassInfoType(parents1, decls1, clazz) @@ -421,7 +421,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { /** The rootContext used for typing */ private val rootContext = - erasure.NoContext.make(EmptyTree, RootClass, newScope) + erasure.NoContext.make(EmptyTree, RootClass, new Scope) /** The typer */ private var localTyper: erasure.Typer = _ diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala index 29502b9c6..981b985f5 100644 --- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala +++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala @@ -77,7 +77,7 @@ abstract class OverridingPairs { } /** The symbols that can take part in an overriding pair */ - private val decls = newScope + private val decls = new Scope // fill `decls` with overriding shadowing overridden */ { def fillDecls(bcs: List[Symbol], deferredflag: Int) { diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 9134a5c1e..2bde17c38 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -373,7 +373,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { typeEnv(cls) = env this.specializedClass((clazz, env)) = cls - val decls1 = newScope + val decls1 = new Scope val specializedInfoType: Type = { val (_, unspecParams) = splitParams(clazz.info.typeParams) @@ -741,7 +741,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val parents1 = parents mapConserve (this); val decls1 = mapOver(decls.toList); if ((parents1 eq parents) && (decls1 eq decls)) tp - else ClassInfoType(parents1, newScope(decls1), clazz) + else ClassInfoType(parents1, new Scope(decls1), clazz) case AnnotatedType(annots, atp, selfsym) => val annots1 = mapOverAnnotations(annots) val atp1 = this(atp) @@ -778,12 +778,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val res = tpe match { case PolyType(targs, ClassInfoType(base, decls, clazz)) => val parents = base map specializedType - PolyType(targs, ClassInfoType(parents, newScope(specializeClass(clazz, typeEnv(clazz))), clazz)) + PolyType(targs, ClassInfoType(parents, new Scope(specializeClass(clazz, typeEnv(clazz))), clazz)) case ClassInfoType(base, decls, clazz) if !clazz.isPackageClass => // val parents = base map specializedType log("transformInfo " + clazz ) - val res = ClassInfoType(base map specializedType, newScope(specializeClass(clazz, typeEnv(clazz))), clazz) + val res = ClassInfoType(base map specializedType, new Scope(specializeClass(clazz, typeEnv(clazz))), clazz) res case _ => diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 1304d4fd6..9b219ff71 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -304,7 +304,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { val formals = fun.tpe.typeArgs.init val restpe = fun.tpe.typeArgs.last anonClass setInfo ClassInfoType( - List(ObjectClass.tpe, fun.tpe, ScalaObjectClass.tpe), newScope, anonClass); + List(ObjectClass.tpe, fun.tpe, ScalaObjectClass.tpe), new Scope, anonClass); val applyMethod = anonClass.newMethod(fun.pos, nme.apply).setFlag(FINAL) applyMethod.setInfo(MethodType(applyMethod.newSyntheticValueParams(formals), restpe)) anonClass.info.decls enter applyMethod; diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 237004524..452a945a2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -240,8 +240,8 @@ trait Contexts { self: Analyzer => make(unit, tree, owner, scope, imports) } - def makeNewScope(tree: Tree, owner: Symbol)(implicit kind : ScopeKind): Context = - make(tree, owner, scopeFor(scope, tree, kind)) + def makeNewScope(tree: Tree, owner: Symbol): Context = + make(tree, owner, new Scope(scope)) // IDE stuff: distinguish between scopes created for typing and scopes created for naming. def make(tree: Tree, owner: Symbol): Context = @@ -268,7 +268,7 @@ trait Contexts { self: Analyzer => //todo: find out why we need next line while (baseContext.tree.isInstanceOf[Template]) baseContext = baseContext.outer - val argContext = baseContext.makeNewScope(tree, owner)(Constructor0ScopeKind) + val argContext = baseContext.makeNewScope(tree, owner) argContext.reportGeneralErrors = this.reportGeneralErrors argContext.reportAmbiguousErrors = this.reportAmbiguousErrors def enterElems(c: Context) { diff --git a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala index 815fb59d2..b4818075f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala +++ b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala @@ -86,7 +86,7 @@ abstract class DeVirtualize extends InfoTransform with TypingTransformers { def enter(sym: Symbol) = // at next phase because names of worker traits change atPhase(ownPhase.next) { decls.enter(sym) } if (containsVirtuals(clazz)) { - decls = newScope + decls = new Scope for (m <- decls0.toList) { if (m.isVirtualClass) { m.setFlag(notDEFERRED | notFINAL | lateABSTRACT) @@ -100,7 +100,7 @@ abstract class DeVirtualize extends InfoTransform with TypingTransformers { if (clazz.isVirtualClass) { println("virtual class: "+clazz+clazz.locationString) transformOwnerInfo(clazz) - decls = newScope + decls = new Scope // add virtual fields for all primary constructor parameters for (row <- paramTypesAndIndices(clazz.primaryConstructor.tpe, 0)) @@ -335,7 +335,7 @@ abstract class DeVirtualize extends InfoTransform with TypingTransformers { val parents2 = removeDuplicates(parents1.flatMap(addOverriddenVirtuals)) .map(_.substSym(clazz.typeParams, factory.typeParams)) - sym setInfo ClassInfoType(parents2, newScope, cclazz) + sym setInfo ClassInfoType(parents2, new Scope, cclazz) } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 6ba11c26f..8af97d081 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -107,7 +107,7 @@ trait Namers { self: Analyzer => private var innerNamerCache: Namer = null protected def makeConstructorScope(classContext : Context) : Context = { val outerContext = classContext.outer.outer - outerContext.makeNewScope(outerContext.tree, outerContext.owner)(Constructor1ScopeKind) + outerContext.makeNewScope(outerContext.tree, outerContext.owner) } def namerOf(sym: Symbol): Namer = { @@ -116,7 +116,7 @@ trait Namers { self: Analyzer => if (innerNamerCache eq null) innerNamerCache = if (!isTemplateContext(context)) this - else newNamer(context.make(context.tree, context.owner, scopeFor(context.tree, InnerScopeKind))) + else newNamer(context.make(context.tree, context.owner, new Scope)) innerNamerCache } @@ -168,7 +168,7 @@ trait Namers { self: Analyzer => def enterInScope(sym: Symbol, scope: Scope): Symbol = { // allow for overloaded methods if (!(sym.isSourceMethod && sym.owner.isClass && !sym.owner.isPackageClass)) { - var prev = scope.lookupEntryWithContext(sym.name)(context.owner); + var prev = scope.lookupEntry(sym.name) if ((prev ne null) && prev.owner == scope && conflict(sym, prev.sym)) { doubleDefError(sym.pos, prev.sym) sym setInfo ErrorType @@ -185,10 +185,10 @@ trait Namers { self: Analyzer => case Select(qual: RefTree, name) => enterPackageSymbol(pos, qual, pkgOwner).moduleClass } - var pkg = owner.info.decls.lookupWithContext(pid.name)(owner) + var pkg = owner.info.decls.lookup(pid.name) if (!pkg.isPackage || owner != pkg.owner) { pkg = owner.newPackage(pos, pid.name) - pkg.moduleClass.setInfo(new PackageClassInfoType(newScope, pkg.moduleClass, null)) + pkg.moduleClass.setInfo(new PackageClassInfoType(new Scope, pkg.moduleClass)) pkg.setInfo(pkg.moduleClass.tpe) enterInScope(pkg, owner.info.decls) } @@ -196,7 +196,7 @@ trait Namers { self: Analyzer => } def enterClassSymbol(tree : ClassDef): Symbol = { - var c: Symbol = context.scope.lookupWithContext(tree.name)(context.owner); + var c: Symbol = context.scope.lookup(tree.name) if (c.isType && c.owner.isPackageClass && context.scope == c.owner.info.decls && !currentRun.compiles(c)) { updatePosFlags(c, tree.pos, tree.mods.flags) setPrivateWithin(tree, c, tree.mods) @@ -226,7 +226,7 @@ trait Namers { self: Analyzer => * or a class definition */ def enterModuleSymbol(tree : ModuleDef): Symbol = { // .pos, mods.flags | MODULE | FINAL, name - var m: Symbol = context.scope.lookupWithContext(tree.name)(context.owner) + var m: Symbol = context.scope.lookup(tree.name) val moduleFlags = tree.mods.flags | MODULE | FINAL if (m.isModule && !m.isPackage && inCurrentScope(m) && (!currentRun.compiles(m) || (m hasFlag SYNTHETIC))) { @@ -286,7 +286,7 @@ trait Namers { self: Analyzer => * @return the companion object symbol. */ def ensureCompanionObject(tree: ClassDef, creator: => Tree): Symbol = { - val m: Symbol = context.scope.lookupWithContext(tree.name.toTermName)(context.owner).filter(! _.isSourceMethod) + val m: Symbol = context.scope.lookup(tree.name.toTermName).filter(! _.isSourceMethod) if (m.isModule && inCurrentScope(m) && currentRun.compiles(m)) m else enterSyntheticSym(creator) } @@ -302,7 +302,7 @@ trait Namers { self: Analyzer => //@M e.g., in [A[x <: B], B], A and B are entered first as both are in scope in the definition of x //@M x is only in scope in `A[x <: B]' if(!sym.isAbstractType) //@M TODO: change to isTypeMember ? - newNamer(context.makeNewScope(tree, sym)(FinishWithScopeKind)).enterSyms(tparams) + newNamer(context.makeNewScope(tree, sym)).enterSyms(tparams) ltype = new PolyTypeCompleter(tparams, ltype, tree, sym, context) //@M if (sym.isTerm) skolemize(tparams) @@ -638,11 +638,11 @@ trait Namers { self: Analyzer => val parentTyper = if (earlyTypes.isEmpty) typer else { - val earlyContext = context.outer.makeNewScope(context.tree, context.outer.owner.newLocalDummy(templ.pos))(InnerScopeKind) + val earlyContext = context.outer.makeNewScope(context.tree, context.outer.owner.newLocalDummy(templ.pos)) newNamer(earlyContext).enterSyms(earlyTypes) newTyper(earlyContext).typedStats(earlyTypes, context.owner) - val parentContext = context.makeNewScope(context.tree, context.owner)(InnerScopeKind) + val parentContext = context.makeNewScope(context.tree, context.owner) for (etdef <- earlyTypes) parentContext.scope enter etdef.symbol newTyper(parentContext) } @@ -669,7 +669,7 @@ trait Namers { self: Analyzer => */ var parents = typer.parentTypes(templ) map checkParent enterSelf(templ.self) - val decls = newClassScope(clazz) + val decls = new Scope // for (etdef <- earlyTypes) decls enter etdef.symbol val templateNamer = newNamer(context.make(templ, clazz, decls)) .enterSyms(templ.body) @@ -790,7 +790,7 @@ trait Namers { self: Analyzer => case Ident(name) if (vparams contains tree.symbol) => val dtpe = debruijnFor(tree.symbol) val dsym = - newLocalDummy(context.owner, tree.symbol.pos) + context.owner.newLocalDummy(tree.symbol.pos) .newValue(tree.symbol.pos, name) dsym.setFlag(PARAM) @@ -1125,7 +1125,6 @@ trait Namers { self: Analyzer => annotated.deSkolemize.setAnnotations(ainfos) case _ => } - implicit val scopeKind = TypeSigScopeKind val result = try { tree match { @@ -1169,12 +1168,12 @@ trait Namers { self: Analyzer => if (!tree.symbol.hasFlag(SYNTHETIC) && !((expr1.symbol ne null) && expr1.symbol.isInterpreterWrapper) && base.member(from) != NoSymbol) { - val e = context.scope.lookupEntryWithContext(to)(context.owner) + val e = context.scope.lookupEntry(to) def warnRedundant(sym: Symbol) = context.unit.warning(pos, "imported `"+to+ "' is permanently hidden by definition of "+sym+ sym.locationString) - if ((e ne null) && e.owner == context.scope) { + if ((e ne null) && e.owner == context.scope && e.sym.exists) { warnRedundant(e.sym); return false } else if (context eq context.enclClass) { val defSym = context.prefix.member(to) filter ( @@ -1307,7 +1306,7 @@ trait Namers { self: Analyzer => override val tree = restp.tree override def complete(sym: Symbol) { if(ownerSym.isAbstractType) //@M an abstract type's type parameters are entered -- TODO: change to isTypeMember ? - newNamer(ctx.makeNewScope(owner, ownerSym)(PolyTypeCompleterScopeKind)).enterSyms(tparams) //@M + newNamer(ctx.makeNewScope(owner, ownerSym)).enterSyms(tparams) //@M restp.complete(sym) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 56aaa67da..6d44e72bb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -114,7 +114,7 @@ trait NamesDefaults { self: Analyzer => */ def baseFunBlock(baseFun: Tree): Tree = { val isConstr = baseFun.symbol.isConstructor - val blockTyper = newTyper(context.makeNewScope(tree, context.owner)(BlockScopeKind(context.depth))) + val blockTyper = newTyper(context.makeNewScope(tree, context.owner)) // baseFun1: extract the function from a potential TypeApply // funTargs: type arguments on baseFun, used to reconstruct TypeApply in blockWith(Out)Qualifier diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 2fb231bfb..ef04e963d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -576,7 +576,7 @@ abstract class RefChecks extends InfoTransform { // Forward reference checking --------------------------------------------------- class LevelInfo(val outer: LevelInfo) { - val scope: Scope = if (outer eq null) newScope else newScope(outer.scope) + val scope: Scope = if (outer eq null) new Scope else new Scope(outer.scope) var maxindex: Int = Math.MIN_INT var refpos: Position = _ var refsym: Symbol = _ @@ -601,7 +601,7 @@ abstract class RefChecks extends InfoTransform { case ClassDef(_, _, _, _) | DefDef(_, _, _, _, _, _) | ModuleDef(_, _, _) | ValDef(_, _, _, _) => assert(stat.symbol != NoSymbol, stat);//debug if (stat.symbol.isLocal) { - currentLevel.scope.enter(newScopeEntry(stat.symbol, currentLevel.scope)); + currentLevel.scope.enter(stat.symbol) symIndex(stat.symbol) = index; } case _ => diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index ec7914f58..1bc6ad9ed 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -454,7 +454,7 @@ trait Typers { self: Analyzer => o = o.owner if (o == sym.owner) addHidden(sym) } else if (sym.owner.isTerm && !sym.isTypeParameterOrSkolem) { - var e = scope.lookupEntryWithContext(sym.name)(context.owner) + var e = scope.lookupEntry(sym.name) var found = false while (!found && (e ne null) && e.owner == scope) { if (e.sym == sym) { @@ -525,7 +525,7 @@ trait Typers { self: Analyzer => */ def labelTyper(ldef: LabelDef): Typer = if (ldef.symbol == NoSymbol) { // labeldef is part of template - val typer1 = newTyper(context.makeNewScope(ldef, context.owner)(LabelScopeKind)) + val typer1 = newTyper(context.makeNewScope(ldef, context.owner)) typer1.enterLabelDef(ldef) typer1 } else this @@ -1111,7 +1111,7 @@ trait Typers { self: Analyzer => val outercontext = context.outer assert(clazz != NoSymbol) - val cscope = outercontext.makeNewScope(constr, outercontext.owner)(ParentTypesScopeKind(clazz)) + val cscope = outercontext.makeNewScope(constr, outercontext.owner) val cbody2 = newTyper(cscope) // called both during completion AND typing. .typePrimaryConstrBody(clazz, cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (_.map(_.duplicate))) @@ -1250,7 +1250,7 @@ trait Typers { self: Analyzer => assert(clazz != NoSymbol) reenterTypeParams(cdef.tparams) val tparams1 = cdef.tparams mapConserve (typedTypeDef) - val impl1 = newTyper(context.make(cdef.impl, clazz, scopeFor(cdef.impl, TypedDefScopeKind))) + val impl1 = newTyper(context.make(cdef.impl, clazz, new Scope)) .typedTemplate(cdef.impl, parentTypes(cdef.impl)) val impl2 = addSyntheticMethods(impl1, clazz, context) if ((clazz != ClassfileAnnotationClass) && @@ -1279,7 +1279,7 @@ trait Typers { self: Analyzer => val clazz = mdef.symbol.moduleClass val typedMods = removeAnnotations(mdef.mods) assert(clazz != NoSymbol) - val impl1 = newTyper(context.make(mdef.impl, clazz, scopeFor(mdef.impl, TypedDefScopeKind))) + val impl1 = newTyper(context.make(mdef.impl, clazz, new Scope)) .typedTemplate(mdef.impl, parentTypes(mdef.impl)) val impl2 = addSyntheticMethods(impl1, clazz, context) @@ -1416,7 +1416,7 @@ trait Typers { self: Analyzer => def typedTemplate(templ: Template, parents1: List[Tree]): Template = { val clazz = context.owner if (templ.symbol == NoSymbol) - templ setSymbol newLocalDummy(clazz, templ.pos) + templ setSymbol clazz.newLocalDummy(templ.pos) val self1 = templ.self match { case vd @ ValDef(mods, name, tpt, EmptyTree) => val tpt1 = checkNoEscaping.privates(clazz.thisSym, typedType(tpt)) @@ -1585,7 +1585,7 @@ trait Typers { self: Analyzer => var cx = context while (cx != NoContext) { val pre = cx.enclClass.prefix - val defEntry = cx.scope.lookupEntryWithContext(name)(context.owner) + val defEntry = cx.scope.lookupEntry(name) if ((defEntry ne null) && defEntry.sym.exists) return Some(defEntry.sym) @@ -1796,7 +1796,7 @@ trait Typers { self: Analyzer => def typedCases(tree: Tree, cases: List[CaseDef], pattp0: Type, pt: Type): List[CaseDef] = { var pattp = pattp0 cases mapConserve (cdef => - newTyper(context.makeNewScope(cdef, context.owner)(TypedCasesScopeKind)) + newTyper(context.makeNewScope(cdef, context.owner)) .typedCase(cdef, pattp, pt)) /* not yet! cdef.pat match { @@ -2310,7 +2310,7 @@ trait Typers { self: Analyzer => (ErrorType, List()) } val (unappFormal, freeVars) = freshArgType(unappType) - val context1 = context.makeNewScope(context.tree, context.owner)(FreshArgScopeKind) + val context1 = context.makeNewScope(context.tree, context.owner) freeVars foreach(sym => context1.scope.enter(sym)) val typer1 = newTyper(context1) arg.tpe = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe) @@ -2488,7 +2488,7 @@ trait Typers { self: Analyzer => else typedFun.tpe.params.iterator) val nvPairs = args map { case arg @ AssignOrNamedArg(Ident(name), rhs) => - val sym = if (isJava) annScope.lookupWithContext(name)(context.owner) + val sym = if (isJava) annScope.lookup(name) else typedFun.tpe.params.find(p => p.name == name).getOrElse(NoSymbol) if (sym == NoSymbol) { error(arg.pos, "unknown annotation argument name: " + name) @@ -2607,7 +2607,7 @@ trait Typers { self: Analyzer => val name = if (sym.isType) sym.name else newTypeName(sym.name+".type") val bound = sym.existentialBound val sowner = if (isRawParameter(sym)) context.owner else sym.owner - val quantified: Symbol = recycle(sowner.newAbstractType(sym.pos, name)) + val quantified: Symbol = sowner.newAbstractType(sym.pos, name) trackSetInfo(quantified setFlag EXISTENTIAL)(bound.cloneInfo(quantified)) } val typeParamTypes = typeParams map (_.tpe) // don't trackSetInfo here, since type already set! @@ -2778,7 +2778,7 @@ trait Typers { self: Analyzer => * (Note: -Yself-in-annots must be on to see the problem) **/ val sym = - newLocalDummy(context.owner, ann.pos) + context.owner.newLocalDummy(ann.pos) .newValue(ann.pos, nme.self) sym.setInfo(arg1.tpe.withoutAnnotations) sym @@ -2833,7 +2833,7 @@ trait Typers { self: Analyzer => val rawInfo = vble.rawInfo vble = if (vble.name == nme.WILDCARD.toTypeName) context.scope.enter(vble) else namer.enterInScope(vble) - trackSetInfo(vble)(rawInfo) // vble could have been recycled, detect changes in type + trackSetInfo(vble)(rawInfo) tree setSymbol vble setType vble.tpe } else { if (vble == NoSymbol) @@ -3384,7 +3384,7 @@ trait Typers { self: Analyzer => while (defSym == NoSymbol && cx != NoContext) { pre = cx.enclClass.prefix - defEntry = cx.scope.lookupEntryWithContext(name)(context.owner) + defEntry = cx.scope.lookupEntry(name) if ((defEntry ne null) && qualifies(defEntry.sym)) { defSym = defEntry.sym } @@ -3481,7 +3481,7 @@ trait Typers { self: Analyzer => val parents1 = templ.parents mapConserve (typedType(_, mode)) if (parents1 exists (_.tpe.isError)) tree setType ErrorType else { - val decls = scopeFor(tree, CompoundTreeScopeKind) + val decls = new Scope //Console.println("Owner: " + context.enclClass.owner + " " + context.enclClass.owner.id) val self = refinedType(parents1 map (_.tpe), context.enclClass.owner, decls, templ.pos) newTyper(context.make(templ, self.typeSymbol, decls)).typedRefinement(templ.body) @@ -3535,7 +3535,6 @@ trait Typers { self: Analyzer => } // begin typed1 - implicit val scopeKind = TypedScopeKind val sym: Symbol = tree.symbol if ((sym ne null) && (sym ne NoSymbol)) sym.initialize //if (settings.debug.value && tree.isDef) log("typing definition of "+sym);//DEBUG @@ -3577,7 +3576,7 @@ trait Typers { self: Analyzer => typedAnnotated(constr, typed(arg, mode, pt)) case tree @ Block(_, _) => - newTyper(context.makeNewScope(tree, context.owner)(BlockScopeKind(context.depth))) + newTyper(context.makeNewScope(tree, context.owner)) .typedBlock(tree, mode, pt) case Alternative(alts) => @@ -3603,8 +3602,8 @@ trait Typers { self: Analyzer => case tree @ Function(_, _) => if (tree.symbol == NoSymbol) - tree.symbol = recycle(context.owner.newValue(tree.pos, nme.ANON_FUN_NAME) - .setFlag(SYNTHETIC).setInfo(NoType)) + tree.symbol = context.owner.newValue(tree.pos, nme.ANON_FUN_NAME) + .setFlag(SYNTHETIC).setInfo(NoType) newTyper(context.makeNewScope(tree, tree.symbol)).typedFunction(tree, mode, pt) case Assign(lhs, rhs) => diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 51243be87..6e9c36833 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -11,329 +11,425 @@ package util import java.io.File import java.net.URL import java.util.StringTokenizer +import scala.util.Sorting -import scala.collection.mutable.ArrayBuffer +import scala.collection.mutable.{ListBuffer, ArrayBuffer, HashSet => MutHashSet} import scala.tools.nsc.io.AbstractFile +import ch.epfl.lamp.compiler.msil.{Type => MSILType, Assembly} + + /**

- * This module provides star expansion of '-classpath' option arguments. + * This module provides star expansion of '-classpath' option arguments, behaves the same as + * java, see [http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html] *

* * @author Stepan Koltsov */ object ClassPath { /** Expand single path entry */ - private def expandStar(pattern: String): List[String] = { + private def expandS(pattern: String): List[String] = { def nameMatchesStar(name: String) = name.toLowerCase().endsWith(".jar") - + /** Get all jars in directory */ def lsJars(f: File) = { val list = f.listFiles() if (list eq null) Nil else list.filter(f => f.isFile() && nameMatchesStar(f.getName())).map(_.getPath()).toList } - + val suffix = File.separator + "*" - + if (pattern == "*") lsJars(new File(".")) else if (pattern endsWith suffix) lsJars(new File(pattern.substring(0, pattern.length - suffix.length))) else pattern :: Nil } - + /** Split path using platform-dependent path separator */ - def splitPath(path: String): List[String] = + private def splitPath(path: String): List[String] = path split File.pathSeparator toList - - /** Expand path with expanding stars */ - def expandPath(path: String): List[String] = splitPath(path).flatMap(expandStar(_)) - - def expandPath(path: String, expandStar: Boolean): List[String] = - if (expandStar) expandPath(path) + + /** Expand path and possibly expanding stars */ + def expandPath(path: String, expandStar: Boolean = true): List[String] = + if (expandStar) splitPath(path).flatMap(expandS(_)) else splitPath(path) + + def validPackage(name: String) = + !(name.equals("META-INF") || name.startsWith(".")) + + def validSourceFile(name: String) = + (name.endsWith(".scala") || name.endsWith(".java")) + + var XO = false + def validClassFile(name: String) = + if (name.endsWith(".class")) { + val className = name.substring(0, name.length - 6) + (!className.endsWith("$class") || XO) + } else false + + + def collectTypes(assemFile: AbstractFile) = { + var res: Array[MSILType] = MSILType.EmptyTypes + val assem = Assembly.LoadFrom(assemFile.path) + if (assem != null) { + // DeclaringType == null: true for non-inner classes + res = assem.GetTypes().filter((typ: MSILType) => typ.DeclaringType == null) + Sorting.stableSort(res, (t1: MSILType, t2: MSILType) => (t1.FullName compareTo t2.FullName) < 0) + } + res + } } -/**

- * Richer classpath abstraction than files. - *

- *

- * Roughly based on Eclipse's classpath abstractions. - *

- * - * @author Sean McDirmid +/** + * A represents classes which can be loaded with a ClassfileLoader/MSILTypeLoader + * and / or a SourcefileLoader. */ -class ClassPath(onlyPresentation: Boolean) { - - def this() = this(false) - - class Source(val location: AbstractFile, val compile: Boolean) { - // assert(location != null, "cannot find source location") - // assert(location.getFile() != null, "cannot find source location " + " " + location + " " + location.getClass()) - override def toString(): String = "" + location + " " + compile +case class ClassRep[T](binary: Option[T], source: Option[AbstractFile]) { + def name = { + if (binary.isDefined) binary.get match { + case f: AbstractFile => + assert(f.name.endsWith(".class"), f.name) + f.name.substring(0, f.name.length - 6) + case t: MSILType => + t.Name + case c => + throw new FatalError("Unexpected binary class representation: "+ c) + } else { + assert(source.isDefined) + val nme = source.get.name + if (nme.endsWith(".scala")) + nme.substring(0, nme.length - 6) + else if (nme.endsWith(".java")) + nme.substring(0, nme.length - 5) + else + throw new FatalError("Unexpected source file ending: "+ nme) + } + } +} + +/** + * Represents a package which contains classes and other packages + */ +abstract class ClassPath[T] { + /** + * The short name of the package (without prefix) + */ + def name: String + def classes: List[ClassRep[T]] + def packages: List[ClassPath[T]] + def sourcepaths: List[AbstractFile] + + /** + * Find a ClassRep given a class name of the form "package.subpackage.ClassName". + * Does not support nested classes on .NET + */ + def findClass(name: String): Option[ClassRep[T]] = { + val i = name.indexOf('.') + if (i < 0) { + classes.find(c => c.name == name) + } else { + val pkg = name.substring(0, i) + val rest = name.substring(i + 1, name.length) + packages.find(p => p.name == pkg).flatMap(_.findClass(rest)) + } + } +} + +/** + * A Classpath containing source files + */ +class SourcePath[T](dir: AbstractFile) extends ClassPath[T] { + def name = dir.name + + def classes = { + val cls = new ListBuffer[ClassRep[T]] + for (f <- dir.iterator) { + if (!f.isDirectory && ClassPath.validSourceFile(f.name)) + cls += ClassRep[T](None, Some(f)) + } + cls.toList + } + + def packages = { + val pkg = new ListBuffer[SourcePath[T]] + for (f <- dir.iterator) { + if (f.isDirectory && ClassPath.validPackage(f.name)) + pkg += new SourcePath[T](f) + } + pkg.toList + } + + def sourcepaths: List[AbstractFile] = List(dir) + + override def toString() = "sourcepath: "+ dir.toString() +} + +/** + * A directory (or a .jar file) containing classfiles and packages + */ +class DirectoryClassPath(dir: AbstractFile) extends ClassPath[AbstractFile] { + def name = dir.name + + def classes = { + val cls = new ListBuffer[ClassRep[AbstractFile]] + for (f <- dir.iterator) { + if (!f.isDirectory && ClassPath.validClassFile(f.name)) + cls += ClassRep(Some(f), None) + } + cls.toList + } + + def packages = { + val pkg = new ListBuffer[DirectoryClassPath] + for (f <- dir.iterator) { + if (f.isDirectory && ClassPath.validPackage(f.name)) + pkg += new DirectoryClassPath(f) + } + pkg.toList + } + + def sourcepaths: List[AbstractFile] = Nil + + override def toString() = "directory classpath: "+ dir.toString() +} + + + +/** + * A assembly file (dll / exe) containing classes and namespaces + */ +class AssemblyClassPath(types: Array[MSILType], namespace: String) extends ClassPath[MSILType] { + def name = { + val i = namespace.lastIndexOf('.') + if (i < 0) namespace + else namespace.substring(i + 1, namespace.length) + } + + def this(assemFile: AbstractFile) { + this(ClassPath.collectTypes(assemFile), "") + } + + private lazy val first: Int = { + var m = 0 + var n = types.length - 1 + while (m < n) { + val l = (m + n) / 2 + val res = types(l).FullName.compareTo(namespace) + if (res < 0) m = l + 1 + else n = l + } + if (types(m).FullName.startsWith(namespace)) m else types.length + } + + def classes = { + val cls = new ListBuffer[ClassRep[MSILType]] + var i = first + while (i < types.length && types(i).Namespace.startsWith(namespace)) { + // CLRTypes used to exclude java.lang.Object and java.lang.String (no idea why..) + if (types(i).Namespace == namespace) + cls += ClassRep(Some(types(i)), None) + i += 1 + } + cls.toList + } + + def packages = { + val nsSet = new MutHashSet[String] + var i = first + while (i < types.length && types(i).Namespace.startsWith(namespace)) { + val subns = types(i).Namespace + if (subns.length > namespace.length) { + // example: namespace = "System", subns = "System.Reflection.Emit" + // => find second "." and "System.Reflection" to nsSet. + val end = subns.indexOf('.', namespace.length + 1) + nsSet += (if (end < 0) subns + else subns.substring(0, end)) + } + i += 1 + } + for (ns <- nsSet.toList) + yield new AssemblyClassPath(types, ns) + } + + def sourcepaths: List[AbstractFile] = Nil + + override def toString() = "assembly classpath "+ namespace +} + +/** + * A classpath unifying multiple class- and sourcepath entries. + */ +abstract class MergedClassPath[T] extends ClassPath[T] { + protected val entries: List[ClassPath[T]] + + def name = entries.head.name + + def classes: List[ClassRep[T]] = { + val cls = new ListBuffer[ClassRep[T]] + for (e <- entries; c <- e.classes) { + val name = c.name + val idx = cls.indexWhere(cl => cl.name == name) + if (idx >= 0) { + val existing = cls(idx) + if (existing.binary.isEmpty && c.binary.isDefined) + cls(idx) = existing.copy(binary = c.binary) + if (existing.source.isEmpty && c.source.isDefined) + cls(idx) = existing.copy(source = c.source) + } else { + cls += c + } + } + cls.toList + } + + def packages: List[ClassPath[T]] = { + val pkg = new ListBuffer[ClassPath[T]] + for (e <- entries; p <- e.packages) { + val name = p.name + val idx = pkg.indexWhere(pk => pk.name == name) + if (idx >= 0) { + pkg(idx) = addPackage(pkg(idx), p) + } else { + pkg += p + } + } + pkg.toList + } + + def sourcepaths: List[AbstractFile] = entries.flatMap(_.sourcepaths) + + private def addPackage(to: ClassPath[T], pkg: ClassPath[T]) = to match { + case cp: MergedClassPath[T] => + newMergedClassPath(cp.entries ::: List(pkg)) + case _ => + newMergedClassPath(List(to, pkg)) + } + + private def newMergedClassPath(entrs: List[ClassPath[T]]): MergedClassPath[T] = + new MergedClassPath[T] { + protected val entries = entrs + } + + override def toString() = "merged classpath "+ entries.mkString("(", "\n", ")") +} + +/** + * The classpath when compiling with target:jvm. Binary files (classfiles) are represented + * as AbstractFile. nsc.io.ZipArchive is used to view zip/jar archives as directories. + */ +class JavaClassPath(boot: String, ext: String, user: String, source: String, Xcodebase: String) +extends MergedClassPath[AbstractFile] { + + protected val entries: List[ClassPath[AbstractFile]] = assembleEntries() + private def assembleEntries(): List[ClassPath[AbstractFile]] = { + import ClassPath._ + val etr = new ListBuffer[ClassPath[AbstractFile]] + + def addFilesInPath(path: String, expand: Boolean, + ctr: AbstractFile => ClassPath[AbstractFile] = x => new DirectoryClassPath(x)) { + for (fileName <- expandPath(path, expandStar = expand)) { + val file = AbstractFile.getDirectory(fileName) + if (file ne null) etr += ctr(file) + } + } + + // 1. Boot classpath + addFilesInPath(boot, false) + + // 2. Ext classpath + for (fileName <- expandPath(ext, expandStar = false)) { + val dir = AbstractFile.getDirectory(fileName) + if (dir ne null) { + for (file <- dir) { + val name = file.name.toLowerCase + if (name.endsWith(".jar") || name.endsWith(".zip") || file.isDirectory) { + val archive = AbstractFile.getDirectory(new File(dir.file, name)) + if (archive ne null) etr += new DirectoryClassPath(archive) + } + } + } + } + + // 3. User classpath + addFilesInPath(user, true) + + // 4. Codebase entries (URLs) + { + val urlSeparator = " " + val urlStrtok = new StringTokenizer(Xcodebase, urlSeparator) + while (urlStrtok.hasMoreTokens()) try { + val url = new URL(urlStrtok.nextToken()) + val archive = AbstractFile.getURL(url) + if (archive ne null) etr += new DirectoryClassPath(archive) + } + catch { + case e => + Console.println("error adding classpath form URL: " + e.getMessage)//debug + throw e + } + } + + // 5. Source path + if (source != "") + addFilesInPath(source, false, x => new SourcePath[AbstractFile](x)) + + etr.toList + } +} + +/** + * The classpath when compiling with target:msil. Binary files are represented as + * MSILType values. + */ +class MsilClassPath(ext: String, user: String, source: String) extends MergedClassPath[MSILType] { + protected val entries: List[ClassPath[MSILType]] = assembleEntries() + + private def assembleEntries(): List[ClassPath[MSILType]] = { + import ClassPath._ + val etr = new ListBuffer[ClassPath[MSILType]] + val names = new MutHashSet[String] + + // 1. Assemblies from -Xassem-extdirs + for (dirName <- expandPath(ext, expandStar = false)) { + val dir = AbstractFile.getDirectory(dirName) + if (dir ne null) { + for (file <- dir) { + val name = file.name.toLowerCase + if (name.endsWith(".dll") || name.endsWith(".exe")) { + names += name + etr += new AssemblyClassPath(file) + } + } + } + } + + // 2. Assemblies from -Xassem-path + for (fileName <- expandPath(user, expandStar = false)) { + val file = AbstractFile.getFile(fileName) + if (file ne null) { + val name = file.name.toLowerCase + if (name.endsWith(".dll") || name.endsWith(".exe")) { + names += name + etr += new AssemblyClassPath(file) + } + } + } + + def check(n: String) { + if (!names.contains(n)) + throw new AssertionError("Cannot find assembly "+ n + + ". Use -Xassem-extdirs or -Xassem-path to specify its location") + } + check("mscorlib.dll") + check("scalaruntime.dll") + + // 3. Source path + for (dirName <- expandPath(source, expandStar = false)) { + val file = AbstractFile.getDirectory(dirName) + if (file ne null) etr += new SourcePath[MSILType](file) + } + + etr.toList } - - abstract class Entry(val location: AbstractFile) { - // assert(location != null, "cannot find classpath location") - // assert(location.getFile() != null, "cannot find classpath location " + " " + location + " " + location.getClass()) - def source: Source - override def toString() = - (if (location == null) "" else location.toString) + - (if (source == null) "" else " source=" + source) - } - - class Output(location0: AbstractFile, val sourceFile: AbstractFile) extends Entry(location0) { - def source = if (sourceFile ne null) new Source(sourceFile, true) else null - } - - class Library(location0: AbstractFile) extends Entry(location0) { - def doc: AbstractFile = null - def sourceFile: AbstractFile = null - def source = if (sourceFile eq null) null else new Source(sourceFile, false) - } - - class Context(val entries: List[Entry]) { - def find(name: String, isDir: Boolean): Context = if (isPackage) { - def find0(entries: List[Entry]): Context = { - if (entries.isEmpty) new Context(Nil) - else { - val ret = find0(entries.tail) - val head = entries.head; - val name0 = name + (if (!isDir) ".class" else "") - val clazz = if (head.location eq null) null - else head.location.lookupPath(name0, isDir) - - val source0 = - if (head.source eq null) null - else if ((clazz eq null) || isDir) { - val source1 = head.source.location.lookupPath( - name + (if (isDir) "" else ".scala"), isDir) - if ((source1 eq null) && !isDir && (clazz ne null)) head.source.location - else source1 - } - else head.source.location - - if ((clazz eq null) && (source0 eq null)) ret - else { - val entry = new Entry(clazz) { - override def source = - if (source0 eq null) null - else new Source(source0, head.source.compile) - } - try { - //Console.err.println("this=" + this + "\nclazz=" + clazz + "\nsource0=" + source0 + "\n") - - if (!isDir) new Context(entry :: Nil) - else new Context(entry :: ret.entries) - } catch { - case e: Error => - throw e - } - } - } - } - - val ret = find0(entries) - if (ret.entries.isEmpty) { - //Console.err.println("BAD_FILE: " + name + " in " + this) - null - } else ret - } else null - - def isPackage: Boolean = - if (entries.isEmpty) false - else if (entries.head.location ne null) entries.head.location.isDirectory - else entries.head.source.location.isDirectory - - def name = - if (entries.isEmpty) "" - else { - val head = entries.head - val name = if (head.location ne null) head.location.name - else head.source.location.name - if (isPackage) name - else name.substring(0, name.length() - (".class").length()) - } - - override def toString(): String = toString(entries) - - def toString(entry: Entry): String = - ((if (entry.location eq null) "" - else entry.location.toString()) + - (if (entry.source eq null) "" - else " with_source=" + entry.source.location.toString())) - - def toString(entries0: List[Entry]): String = - if (entries0.isEmpty) "" - else toString(entries0.head) + ":::" + toString(entries0.tail) - - def isSourceFile = { - def head = entries.head - def clazz = head.location - def source = if (head.source eq null) null else head.source.location - def isPredef = source.name.equals("Predef.scala") || - source.path.startsWith("scala/runtime") - - if (entries.isEmpty || entries.isEmpty || (source eq null)) false - else if (!onlyPresentation && !head.source.compile) false - else if (source.isDirectory) false - else if (clazz eq null) true - else if (onlyPresentation && !isPredef) true - else if (source.lastModified > clazz.lastModified) true - else false - } - - def sourceFile = if ((entries.head.source ne null) && !entries.head.source.location.isDirectory) - entries.head.source.location else null - - def classFile = if (!isSourceFile) entries.head.location else null - - def sourcePath = - if (!isSourceFile && !entries.isEmpty && (entries.head.source ne null)) { - val ret = entries.head.source.location - if ((ret ne null) && !ret.isDirectory) { - Console.err.println("source path " + ret + " is not a directory") - null - } else ret - } - else null - - def validPackage(name: String): Boolean = - ! (name.equals("META-INF") || name.startsWith(".")) - } - - class Build { - val entries = new ArrayBuffer[Entry] - - def root = new Context(entries.toList) - - def this(classpath: String) { - this() - addFilesInPath(classpath) - } - - def this(source: String, output: String) { - this() - addDirsInPath(source, output) - } - - def this(classpath: String, source: String, output: String, - boot: String, extdirs: String, codebase: String) { - this() - addFilesInPath(boot) - addArchivesInExtDirPath(extdirs) - addDirsInPath(source, output) - addFilesInPath(classpath) - addURLsInPath(codebase) - } - - /** - * Lookup the given path in this classpath. Returns null if not found. - * Does not work with absolute paths (starting with '/'). - * - * @param path Path to look up (if isDir is false, '.class' is appended!). - * @param isDir Whether to look for a directory or a file - * @return The abstract file or null if path was not found - */ - def lookupPath(path: String, isDir: Boolean): AbstractFile = { - val ctx = root.find(path, isDir) - if (ctx eq null) null - else if (ctx.entries.isEmpty) null - else if (ctx.entries.head eq null) null - else ctx.entries.head.location - } - - /** - * @param classes where the class files come from and are written to - * @param sources where the source files come from - */ - def output(classes : String, sources : String) = { - assert(classes ne null) - assert(sources ne null) - val location = AbstractFile.getDirectory(classes) - val sources0 = AbstractFile.getDirectory(sources) - class Output0 extends Output(location, sources0) - entries += new Output0() - } - /** - * @param classes where the class files come from - * @param sources optional source file attachment, otherwise null - */ - def library(classes: String, sources: String) { - assert(classes ne null) - val location = AbstractFile.getDirectory(classes) - var sourceFile0 = - if (sources ne null) AbstractFile.getDirectory(sources) - else null - if (sourceFile0 ne null) { - val file00 = sourceFile0.lookupPath("src", true) - if ((file00 ne null) && file00.isDirectory) { - sourceFile0 = file00 - } - } - - class Library0 extends Library(location) { - override def sourceFile = sourceFile0 - } - entries += new Library0() - } - - private def addFilesInPath(path: String) { - for (fileName <- ClassPath.expandPath(path)) { - val file = AbstractFile.getDirectory(fileName) - if (file ne null) entries += (new Library(file)) - } - } - - private def addArchivesInExtDirPath(path: String) { - for (fileName <- ClassPath.expandPath(path)) { - val file = AbstractFile.getDirectory(fileName) - if (file ne null) { - for (file0 <- file) { - val name = file0.name - if (name.endsWith(".jar") || name.endsWith(".zip") || file0.isDirectory) { - val archive = AbstractFile.getDirectory(new File(file.file, name)) - if (archive ne null) entries += (new Library(archive)) - } - } - } - } - } - - private def addDirsInPath(source: String, output: String) { - val clazzes = AbstractFile.getDirectory(output) - if (clazzes eq null) - throw new FatalError("Output location \"" + output + "\" not found") - val strtok = new StringTokenizer(source, File.pathSeparator) - if (!strtok.hasMoreTokens()) { - val output0 = (new Output(clazzes, null)) - entries += output0 - } - else while (strtok.hasMoreTokens()) { - val sources = AbstractFile.getDirectory(strtok.nextToken()) - val output0 = (new Output(clazzes, sources)) - entries += output0 - } - } - - private val urlSeparator = " " - private def addURLsInPath(codebase: String) { - val strtok = new StringTokenizer(codebase, urlSeparator) - while (strtok.hasMoreTokens()) { - try { - val url = new URL(strtok.nextToken()) - val archive = AbstractFile.getURL(url) - if (archive ne null) entries += (new Library(archive)) - } - catch { - case e => - Console.println("error in addURLsInPath: " + e.getMessage)//debug - throw e - } - } - } - - override def toString() = - entries.toList.mkString("", File.pathSeparator, "") - } // class Build - } diff --git a/src/library/scala/xml/factory/XMLLoader.scala b/src/library/scala/xml/factory/XMLLoader.scala index 95d523827..97fb5a9c8 100644 --- a/src/library/scala/xml/factory/XMLLoader.scala +++ b/src/library/scala/xml/factory/XMLLoader.scala @@ -36,13 +36,12 @@ trait XMLLoader[T <: Node] */ def loadXML(source: InputSource, parser: SAXParser): T = { val newAdapter = adapter - import newAdapter._ - scopeStack push TopScope + newAdapter.scopeStack push TopScope parser.parse(source, newAdapter) - scopeStack.pop + newAdapter.scopeStack.pop - rootElem.asInstanceOf[T] + newAdapter.rootElem.asInstanceOf[T] } /** Loads XML from the given file, file descriptor, or filename. */ diff --git a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala index 37ad9e42c..d7b48fa9f 100644 --- a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala +++ b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala @@ -57,11 +57,10 @@ class ReflectiveRunner extends RunnerUtils { val newClasspath = paths mkString pathSeparator syspropset("java.class.path", newClasspath) - syspropset("env.classpath", newClasspath) syspropset("scala.home", "") if (fileManager.debug) - for (prop <- List("java.class.path", "env.classpath", "sun.boot.class.path", "java.ext.dirs")) + for (prop <- List("java.class.path", "sun.boot.class.path", "java.ext.dirs")) println(prop + ": " + sysprop(prop)) try { diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala index 0453bf93a..1e6f5c5f2 100644 --- a/src/scalap/scala/tools/scalap/Main.scala +++ b/src/scalap/scala/tools/scalap/Main.scala @@ -11,8 +11,9 @@ package scala.tools.scalap import java.io.{File, PrintStream, OutputStreamWriter, ByteArrayOutputStream} -import scala.tools.nsc.util.ClassPath import scalax.rules.scalasig._ +import tools.nsc.io.AbstractFile +import tools.nsc.util.{ClassPath, JavaClassPath} /**The main object used to execute scalap on the command-line. * @@ -61,7 +62,7 @@ object Main { out.flush() } - def isPackageObjectFile(s: String) = s != null && (s.endsWith(File.separator + "package") || s == "package") + def isPackageObjectFile(s: String) = s != null && (s.endsWith(".package") || s == "package") def parseScalaSignature(scalaSig: ScalaSig, isPackageObject: Boolean) = { val baos = new ByteArrayOutputStream @@ -112,19 +113,20 @@ object Main { * @param path... * @param classname... */ - def process(args: Arguments, path: ClassPath#Build)(classname: String): Unit = { + def process(args: Arguments, path: ClassPath[AbstractFile])(classname: String): Unit = { // find the classfile - val filename = Names.encode( + val encName = Names.encode( if (classname == "scala.AnyRef") "java.lang.Object" - else classname).replace('.', File.separatorChar) - val cfile = path.lookupPath(filename, /*isDir*/ false) - if (cfile != null) { + else classname) + val cls = path.findClass(encName) + if (cls.isDefined && cls.get.binary.isDefined) { + val cfile = cls.get.binary.get if (verbose) { Console.println(Console.BOLD + "FILENAME" + Console.RESET + " = " + cfile.path) } val bytes = cfile.toByteArray if (isScalaFile(bytes)) { - decompileScala(bytes, isPackageObjectFile(filename)) + decompileScala(bytes, isPackageObjectFile(encName)) } else { // construct a reader for the classfile content val reader = new ByteArrayReader(cfile.toByteArray) @@ -261,13 +263,12 @@ object Main { verbose = arguments contains "-verbose" printPrivates = arguments contains "-private" // construct a custom class path - val classPath0 = new ClassPath(false) val path = arguments.getArgument("-classpath") match { case None => arguments.getArgument("-cp") match { - case None => new classPath0.Build() - case Some(path) => new classPath0.Build(path) + case None => EmptyClasspath + case Some(path) => new JavaClassPath("", "", path, "", "") } - case Some(path) => new classPath0.Build(path) + case Some(path) => new JavaClassPath("", "", path, "", "") } // print the classpath if output is verbose if (verbose) { @@ -277,4 +278,15 @@ object Main { arguments.getOthers.foreach(process(arguments, path)) } } + + object EmptyClasspath extends ClassPath[AbstractFile] { + import tools.nsc.util.ClassRep + /** + * The short name of the package (without prefix) + */ + def name: String = "" + def classes: List[ClassRep[AbstractFile]] = Nil + def packages: List[ClassPath[AbstractFile]] = Nil + def sourcepaths: List[AbstractFile] = Nil + } } diff --git a/test/files/jvm/interpreter.scala b/test/files/jvm/interpreter.scala index f8d0f7bc1..1437b97f7 100644 --- a/test/files/jvm/interpreter.scala +++ b/test/files/jvm/interpreter.scala @@ -175,10 +175,13 @@ def f(e: Exp) = e match {{ // non-exhaustive warning here val output = new PrintWriter( new Skip1Writer(new OutputStreamWriter(Console.out))) val repl = new InterpreterLoop(input, output) - repl.main(new Settings) + val settings = new Settings + // when running that compiler, give it a scala-library to the classpath + settings.classpath.value = System.getProperty("java.class.path") + repl.main(settings) println() - val interp = new Interpreter(new Settings) + val interp = new Interpreter(settings) interp.interpret("def plusOne(x: Int) = x + 1") interp.interpret("plusOne(5)") interp.reset() diff --git a/test/files/neg/plugin-after-terminal/lib/plugins.jar b/test/files/neg/plugin-after-terminal/lib/plugins.jar index 5f65bec32214ec40d137b30ccbdf3078681bb53b..e4665c52be302b9670c9ef372b6e6e437e6a8835 100644 GIT binary patch delta 3296 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 delta 3444 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 Xz{~=o`q^{ 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 RY|%B0B^?u)4CwsLzX9n;9-#mL diff --git a/test/files/neg/plugin-cyclic-dependency/lib/plugins.jar b/test/files/neg/plugin-cyclic-dependency/lib/plugins.jar index 36283b1abf376a5f45c8070704e161102c7cf6f5..93324ccabcaaea3c06900cb28017be11dacfad56 100644 GIT binary patch delta 4656 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 G(f?->aMf+|*7sW!0Au7iU>~dbD;)p;aC-bp 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 delta 3443 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 Cqw}x; delta 3430 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