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
This commit is contained in:
parent
1b2fcb0c1e
commit
d6ef73c9a2
|
@ -245,6 +245,7 @@ INITIALISATION
|
|||
<pathelement location="${lib.starr.jar}"/>
|
||||
<pathelement location="${comp.starr.jar}"/>
|
||||
<pathelement location="${lib.dir}/fjbg.jar"/>
|
||||
<pathelement location="${lib.dir}/msil.jar"/>
|
||||
<pathelement location="${ant.jar}"/>
|
||||
</path>
|
||||
<taskdef resource="scala/tools/ant/sabbus/antlib.xml" classpathref="starr.classpath"/>
|
||||
|
@ -371,6 +372,7 @@ LOCAL REFERENCE BUILD (LOCKER)
|
|||
<pathelement location="${build-locker.dir}/classes/library"/>
|
||||
<pathelement location="${build-locker.dir}/classes/compiler"/>
|
||||
<pathelement location="${lib.dir}/fjbg.jar"/>
|
||||
<pathelement location="${lib.dir}/msil.jar"/>
|
||||
<pathelement location="${ant.jar}"/>
|
||||
</path>
|
||||
</target>
|
||||
|
@ -688,6 +690,7 @@ QUICK BUILD (QUICK)
|
|||
<pathelement location="${build-quick.dir}/classes/compiler"/>
|
||||
<pathelement location="${build-quick.dir}/classes/scalap"/>
|
||||
<pathelement location="${fjbg.jar}"/>
|
||||
<pathelement location="${msil.jar}"/>
|
||||
<pathelement location="${jline.jar}"/>
|
||||
</path>
|
||||
<taskdef name="quick-bin" classname="scala.tools.ant.ScalaTool" classpathref="quick.bin.classpath"/>
|
||||
|
@ -730,6 +733,7 @@ QUICK BUILD (QUICK)
|
|||
<pathelement location="${build-quick.dir}/classes/library"/>
|
||||
<pathelement location="${build-quick.dir}/classes/compiler"/>
|
||||
<pathelement location="${fjbg.jar}"/>
|
||||
<pathelement location="${msil.jar}"/>
|
||||
<pathelement location="${ant.jar}"/>
|
||||
</path>
|
||||
</target>
|
||||
|
|
|
@ -52,11 +52,15 @@ 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()
|
||||
if (compTarget.isDefined && compTarget.get == "msil")
|
||||
mapper.setTo("*.msil")
|
||||
else
|
||||
mapper.setTo("*.class")
|
||||
mapper.setFrom("*.scala")
|
||||
val includedFiles: Array[File] =
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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@ "$@@"
|
||||
|
|
|
@ -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%
|
||||
|
|
|
@ -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,23 +252,15 @@ 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) {
|
||||
|
@ -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 = new SymbolLoaders {
|
||||
val global: Global.this.type = Global.this
|
||||
}
|
||||
|
||||
lazy val loaders : SymbolLoaders { val global : Global.this.type } = new {
|
||||
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 -------------------------------------------}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 "."
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
def addMarker() {
|
||||
val markerSymtab = new Array[Byte](4)
|
||||
markerSymtab(0) = 1.toByte
|
||||
tBuilder.SetCustomAttribute(SYMTAB_ATTRIBUTE_EMPTY_CONSTRUCTOR, markerSymtab)
|
||||
}
|
||||
|
||||
// both conditions are needed (why exactly..?)
|
||||
if (tBuilder.Name.endsWith("$") || sym.isModuleClass) {
|
||||
addMarker()
|
||||
} else {
|
||||
currentRun.symData.get(sym) match {
|
||||
case Some(pickle) =>
|
||||
val symtab: Array[Byte] = new Array[Byte](pickle.writeIndex + 8)
|
||||
var size = pickle.writeIndex
|
||||
val symtab = new Array[Byte](size + 8)
|
||||
symtab(0) = 1.toByte
|
||||
var size:Int = pickle.writeIndex
|
||||
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)
|
||||
|
||||
currentRun.symData -= sym
|
||||
currentRun.symData -= sym.linkedSym
|
||||
//log("Generated ScalaSig Attr for " + sym)//debug
|
||||
|
||||
case _ =>
|
||||
log("Could not find pickle information for " + sym)
|
||||
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)
|
||||
|
@ -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)
|
||||
|
@ -549,9 +540,9 @@ abstract class GenMSIL extends SubComponent {
|
|||
computeLocalVarsIndex(m)
|
||||
|
||||
if (m.symbol.isClassConstructor) {
|
||||
mcode = constructors(m.symbol.asInstanceOf[clrTypes.global.Symbol]).asInstanceOf[ConstructorBuilder].GetILGenerator()
|
||||
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()
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 + "$"
|
||||
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] =
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -2091,7 +2086,7 @@ abstract class GenMSIL extends SubComponent {
|
|||
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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
abstract class SymbolLoader extends LazyType {
|
||||
|
||||
/** Load source or class file for `root', return */
|
||||
protected def doComplete(root: Symbol): Unit
|
||||
|
||||
/** The kind of file that's processed by this loader */
|
||||
protected def kindString: String
|
||||
protected def sourcefile: Option[AbstractFile] = None
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
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
|
||||
protected def newPackageLoader(pkg: ClassPath[AbstractFile]) =
|
||||
new JavaPackageLoader(pkg)
|
||||
}
|
||||
|
||||
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))
|
||||
// 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
|
||||
}
|
||||
|
||||
val pkgModule = root.info.decl(nme.PACKAGEkw)
|
||||
if (pkgModule.isModule && !pkgModule.rawInfo.isInstanceOf[SourcefileLoader])
|
||||
openPackageModule(pkgModule)
|
||||
}
|
||||
} // NamespaceLoader
|
||||
protected def newClassLoader(bin: MSILType) =
|
||||
new MSILTypeLoader(bin)
|
||||
|
||||
protected def newPackageLoader(pkg: ClassPath[MSILType]) =
|
||||
new NamespaceLoader(pkg)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 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)
|
||||
}
|
||||
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()
|
||||
protected def description = "class file "+ classfile.toString
|
||||
|
||||
protected def doComplete(root: Symbol) {
|
||||
classfileParser.parse(classfile, root)
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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,14 +2249,12 @@ 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) = {
|
||||
|
@ -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
|
||||
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,19 +776,6 @@ 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
|
||||
case nme.AnnotationDefaultATTR =>
|
||||
sym.addAnnotation(AnnotationInfo(definitions.AnnotationDefaultAttr.tpe, List(), List(), NoPosition))
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
case _ =>
|
||||
log("Could not find: " + cls)
|
||||
}
|
||||
|
||||
(staticCode, instanceCode)
|
||||
}
|
||||
|
|
|
@ -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 _ =>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 _ =>
|
||||
|
|
|
@ -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) =>
|
||||
|
|
|
@ -11,19 +11,24 @@ 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}
|
||||
|
||||
|
||||
/** <p>
|
||||
* 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]
|
||||
* </p>
|
||||
*
|
||||
* @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 */
|
||||
|
@ -41,299 +46,390 @@ object ClassPath {
|
|||
}
|
||||
|
||||
/** 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)
|
||||
|
||||
}
|
||||
|
||||
/** <p>
|
||||
* Richer classpath abstraction than files.
|
||||
* </p>
|
||||
* <p>
|
||||
* Roughly based on Eclipse's classpath abstractions.
|
||||
* </p>
|
||||
*
|
||||
* @author Sean McDirmid
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
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) "<none>" 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) "<none>"
|
||||
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) "<none>"
|
||||
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 =
|
||||
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)
|
||||
}
|
||||
|
||||
class Build {
|
||||
val entries = new ArrayBuffer[Entry]
|
||||
|
||||
def root = new Context(entries.toList)
|
||||
|
||||
def this(classpath: String) {
|
||||
this()
|
||||
addFilesInPath(classpath)
|
||||
res
|
||||
}
|
||||
|
||||
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
|
||||
* A represents classes which can be loaded with a ClassfileLoader/MSILTypeLoader
|
||||
* and / or a SourcefileLoader.
|
||||
*/
|
||||
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
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param classes where the class files come from and are written to
|
||||
* @param sources where the source files come from
|
||||
* Represents a package which contains classes and other packages
|
||||
*/
|
||||
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()
|
||||
}
|
||||
abstract class ClassPath[T] {
|
||||
/**
|
||||
* @param classes where the class files come from
|
||||
* @param sources optional source file attachment, otherwise null
|
||||
* The short name of the package (without prefix)
|
||||
*/
|
||||
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
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Library0 extends Library(location) {
|
||||
override def sourceFile = sourceFile0
|
||||
/**
|
||||
* 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))
|
||||
}
|
||||
entries += new Library0()
|
||||
cls.toList
|
||||
}
|
||||
|
||||
private def addFilesInPath(path: String) {
|
||||
for (fileName <- ClassPath.expandPath(path)) {
|
||||
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) entries += (new Library(file))
|
||||
if (file ne null) etr += ctr(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))
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
// 3. User classpath
|
||||
addFilesInPath(user, true)
|
||||
|
||||
private val urlSeparator = " "
|
||||
private def addURLsInPath(codebase: String) {
|
||||
val strtok = new StringTokenizer(codebase, urlSeparator)
|
||||
while (strtok.hasMoreTokens()) {
|
||||
try {
|
||||
val url = new URL(strtok.nextToken())
|
||||
// 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) entries += (new Library(archive))
|
||||
if (archive ne null) etr += new DirectoryClassPath(archive)
|
||||
}
|
||||
catch {
|
||||
case e =>
|
||||
Console.println("error in addURLsInPath: " + e.getMessage)//debug
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
override def toString() =
|
||||
entries.toList.mkString("", File.pathSeparator, "")
|
||||
} // class Build
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -90,6 +90,8 @@ object Test {
|
|||
settings.Xexperimental.value = true
|
||||
settings.selfInAnnots.value = true
|
||||
settings.deprecation.value = true
|
||||
// when running that compiler, give it a scala-library to the classpath
|
||||
settings.classpath.value = System.getProperty("java.class.path")
|
||||
|
||||
val interp = new Interpreter(settings)
|
||||
|
||||
|
|
|
@ -113,6 +113,8 @@ object Foo2 {
|
|||
var reporter: ConsoleReporter = _
|
||||
def process(args: Array[String]) {
|
||||
val docSettings = new scala.tools.nsc.doc.Settings(error)
|
||||
// when running that compiler, give it a scala-library to the classpath
|
||||
docSettings.classpath.value = System.getProperty("java.class.path")
|
||||
reporter = new ConsoleReporter(docSettings)
|
||||
val command = new CompilerCommand(args.toList, docSettings, error, false)
|
||||
try {
|
||||
|
|
|
@ -332,7 +332,7 @@ object LispAny extends Lisp {
|
|||
val result = eval1(x, env);
|
||||
if (trace) {
|
||||
indent -= 1;
|
||||
for (val x <- range(1, indent)) Console.print(" ");
|
||||
for (x <- range(1, indent)) Console.print(" ");
|
||||
Console.println("<=== " + result);
|
||||
}
|
||||
curexp = prevexp;
|
||||
|
|
|
@ -20,6 +20,8 @@ object Test {
|
|||
|
||||
val tool = new Interpreter(new Settings())
|
||||
val global = tool.compiler
|
||||
// when running that compiler, give it a scala-library to the classpath
|
||||
global.settings.classpath.value = System.getProperty("java.class.path")
|
||||
|
||||
import global._
|
||||
import definitions._
|
||||
|
|
|
@ -31,6 +31,9 @@ object Test {
|
|||
|
||||
val tool = new Interpreter(new Settings())
|
||||
val global = tool.compiler
|
||||
// when running that compiler, give it a scala-library to the classpath
|
||||
global.settings.classpath.value = System.getProperty("java.class.path")
|
||||
|
||||
|
||||
import global._
|
||||
import definitions._
|
||||
|
|
Loading…
Reference in New Issue