summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsources/scala/tools/nsc/Global.scala460
-rwxr-xr-xsources/scala/tools/nsc/ast/TreeGen.scala1
-rw-r--r--sources/scala/tools/nsc/symtab/Flags.scala12
-rwxr-xr-xsources/scala/tools/nsc/symtab/Names.scala18
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala67
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala70
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala11
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/UnPickler.scala1
-rwxr-xr-xsources/scala/tools/nsc/transform/AddInterfaces.scala59
-rwxr-xr-xsources/scala/tools/nsc/transform/Constructors.scala26
-rwxr-xr-xsources/scala/tools/nsc/transform/Erasure.scala16
-rwxr-xr-xsources/scala/tools/nsc/transform/ExplicitOuter.scala9
-rwxr-xr-xsources/scala/tools/nsc/transform/Flatten.scala53
-rwxr-xr-xsources/scala/tools/nsc/transform/LambdaLift.scala52
-rwxr-xr-xsources/scala/tools/nsc/transform/Mixin.scala373
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala7
-rwxr-xr-xsources/scala/tools/nsc/typechecker/RefChecks.scala91
-rw-r--r--sources/scala/tools/nsc/typechecker/TreeCheckers.scala14
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala91
19 files changed, 1063 insertions, 368 deletions
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index 4fd39beb89..0a8151e2f4 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -61,6 +61,465 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
object checkers extends Checkers {
val global: Global.this.type = Global.this
}
+ val icodeChecker = new checkers.ICodeChecker();
+
+ val copy = new LazyTreeCopier();
+
+ type AttrInfo = Pair[Type, List[Any]];
+
+ /** A map from symbols to their attributes */
+ val attributes = new HashMap[Symbol, List[AttrInfo]];
+
+// reporting -------------------------------------------------------
+
+ def error(msg: String) = reporter.error(null, msg);
+ def warning(msg: String) = reporter.warning(null, msg);
+ private def inform(msg: String) = reporter.info(null, msg, true);
+
+ def informProgress(msg: String) =
+ if (settings.verbose.value) inform("[" + msg + "]");
+
+ def informTime(msg: String, start: long) =
+ informProgress(msg + " in " + (System.currentTimeMillis() - start) + "ms");
+
+ def log(msg: Object): unit =
+ if (settings.log contains phase.name) inform("[log " + phase + "] " + msg);
+
+ def abort(msg: String) = throw new Error(msg);
+
+// file interface -------------------------------------------------------
+
+ private val reader: SourceReader = {
+ def stdCharset: Charset = {
+ settings.encoding.value = "ISO-8859-1"; // A mandatory charset
+ Charset.forName(settings.encoding.value);
+ }
+ val charset =
+ try {
+ Charset.forName(settings.encoding.value);
+ } catch {
+ case _: IllegalCharsetNameException =>
+ error("illegal charset name '" + settings.encoding.value + "'");
+ stdCharset
+ case _: UnsupportedCharsetException =>
+ error("unsupported charset '" + settings.encoding.value + "'");
+ stdCharset
+ }
+ new SourceReader(charset.newDecoder());
+ }
+
+ val classPath = new ClassPath(
+ settings.classpath.value,
+ settings.sourcepath.value,
+ settings.bootclasspath.value,
+ settings.extdirs.value);
+
+ if (settings.verbose.value) {
+ System.out.println("classpath = " + classPath);
+ }
+
+ def getSourceFile(f: AbstractFile): SourceFile =
+ new SourceFile(f, reader.read(f));
+
+ def getSourceFile(name: String): SourceFile = {
+ val f = AbstractFile.getFile(name);
+ if (f == null) throw new FileNotFoundException(
+ "source file '" + name + "' could not be found");
+ getSourceFile(f)
+ }
+
+ def getSourceFile(clazz: Symbol): SourceFile = {
+ val f = classPath.getRoot().lookupPath(
+ clazz.fullNameString(File.separatorChar) + ".scala", false);
+ if (f == null) throw new FileNotFoundException(
+ "source file for " + clazz + " could not be found");
+ getSourceFile(f)
+ }
+
+ object loaders extends SymbolLoaders {
+ val global: Global.this.type = Global.this
+ }
+
+ def rootLoader: LazyType = new loaders.PackageLoader(classPath.getRoot());
+
+// Phases ------------------------------------------------------------
+
+ var globalPhase: Phase = NoPhase;
+
+ override def phase_=(p: Phase): unit = {
+ assert(p.id <= globalPhase.id + 1);
+ super.phase_=(p)
+ }
+
+ abstract class GlobalPhase(prev: Phase) extends Phase(prev) {
+ def run: unit = units foreach applyPhase;
+ def apply(unit: CompilationUnit): unit;
+ private val isErased = prev.name == "erasure" || prev.erasedTypes;
+ override def erasedTypes: boolean = isErased;
+ private val isFlat = prev.name == "flatten" || prev.flatClasses;
+ override def flatClasses: boolean = isFlat;
+ def applyPhase(unit: CompilationUnit): unit = {
+ if (settings.debug.value) inform("[running phase " + name + " on " + unit + "]");
+ apply(unit)
+ }
+ }
+
+ object syntaxAnalyzer extends SyntaxAnalyzer {
+ val global: Global.this.type = Global.this
+ }
+
+ object analyzer extends Analyzer {
+ val global: Global.this.type = Global.this;
+ }
+
+ object pickler extends Pickler {
+ val global: Global.this.type = Global.this
+ }
+
+ object syntheticMethods extends SyntheticMethods {
+ val global: Global.this.type = Global.this
+ }
+
+ object refchecks extends RefChecks {
+ val global: Global.this.type = Global.this;
+ }
+
+ object uncurry extends UnCurry {
+ val global: Global.this.type = Global.this;
+ }
+
+ object tailCalls extends TailCalls {
+ val global: Global.this.type = Global.this;
+ }
+
+ object transMatcher extends TransMatcher {
+ val global: Global.this.type = Global.this;
+ }
+
+ object explicitOuter extends ExplicitOuter {
+ val global: Global.this.type = Global.this;
+ }
+
+ object erasure extends Erasure {
+ val global: Global.this.type = Global.this;
+ }
+
+ object lambdaLift extends LambdaLift {
+ val global: Global.this.type = Global.this;
+ }
+
+ object flatten extends Flatten {
+ val global: Global.this.type = Global.this;
+ }
+
+ object constructors extends Constructors {
+ val global: Global.this.type = Global.this;
+ }
+
+ object mixin extends Mixin {
+ val global: Global.this.type = Global.this;
+ }
+
+ object sampleTransform extends SampleTransform {
+ val global: Global.this.type = Global.this;
+ }
+
+ object genicode extends GenICode {
+ val global: Global.this.type = Global.this;
+ }
+
+ object icodePrinter extends backend.icode.Printers {
+ val global: Global.this.type = Global.this;
+ }
+
+ object scalaPrimitives extends ScalaPrimitives {
+ val global: Global.this.type = Global.this;
+ }
+
+ def phaseDescriptors: List[SubComponent] = List(
+ analyzer.namerFactory, // needs to be first
+ analyzer.typerFactory, // needs to be second
+ pickler,
+ syntheticMethods,
+ refchecks,
+ uncurry,
+ tailCalls,
+ transMatcher,
+ explicitOuter,
+ erasure,
+ lambdaLift,
+ flatten,
+ constructors,
+ mixin,
+ if (settings.Xshowicode.value) genicode
+ else sampleTransform);
+
+ val parserPhase = syntaxAnalyzer.newPhase(NoPhase);
+ val firstPhase = parserPhase;
+ phase = parserPhase;
+ definitions.init; // needs firstPhase and phase to be defined != NoPhase,
+ // that's why it is placed here.
+
+ private var p = phase;
+ private var stopped = false;
+ for (val pd <- phaseDescriptors) {
+ if (!stopped) {
+ if (!(settings.skip contains pd.phaseName)) p = pd.newPhase(p);
+ stopped = settings.stop contains pd.phaseName;
+ }
+ }
+
+ val terminalPhase = new GlobalPhase(p) {
+ def name = "terminal";
+ def apply(unit: CompilationUnit): unit = {}
+ }
+
+ def phaseNamed(name: String): Phase = {
+ var p: Phase = firstPhase;
+ while (p.next != p && p.name != name) p = p.next;
+ if (p.name != name) NoPhase else p
+ }
+
+ val namerPhase = phaseNamed("namer");
+ val typerPhase = phaseNamed("typer");
+ val refchecksPhase = phaseNamed("refchecks");
+ val erasurePhase = phaseNamed("erasure");
+ val flattenPhase = phaseNamed("flatten");
+ val delegateMixins = phaseNamed("mixin") != NoPhase;
+
+ val typer = new analyzer.Typer(analyzer.NoContext.make(EmptyTree, definitions.RootClass, new Scope())) {
+ override def typed(tree: Tree, mode: int, pt: Type): Tree = {
+ if (settings.debug.value) log("typing [[" + tree + "]]");
+ val result = super.typed(tree, mode, pt);
+ if (settings.debug.value) log(" ==> " + result + ":" + result.tpe);
+ result
+ }
+ }
+ val infer = typer.infer;
+
+// Units and how to compile them -------------------------------------
+
+ private var unitbuf = new ListBuffer[CompilationUnit];
+ private var fileset = new HashSet[AbstractFile];
+
+ private def addUnit(unit: CompilationUnit): unit = {
+ unitbuf += unit;
+ fileset += unit.source.getFile();
+ }
+
+ def units: Iterator[CompilationUnit] = unitbuf.elements;
+
+ /** A map from compiled top-level symbols to their source files */
+ val symSource = new HashMap[Symbol, AbstractFile];
+
+ /** A map from compiled top-level symbols to their picklers */
+ val symData = new HashMap[Symbol, PickleBuffer];
+
+ def compileSources(sources: List[SourceFile]): unit = {
+ val startTime = System.currentTimeMillis();
+ unitbuf.clear;
+ fileset.clear;
+ symSource.clear;
+ symData.clear;
+ reporter.resetCounters();
+ for (val source <- sources)
+ addUnit(new CompilationUnit(source));
+
+ globalPhase = NoPhase.next;
+ while (globalPhase != terminalPhase && reporter.errors() == 0) {
+ val startTime = System.currentTimeMillis();
+ phase = globalPhase;
+ globalPhase.run;
+ if (settings.print contains globalPhase.name) treePrinter.printAll();
+ if (settings.browse contains globalPhase.name) treeBrowser.browse(units);
+ informTime(globalPhase.description, startTime);
+ globalPhase = globalPhase.next;
+ if (settings.check contains globalPhase.name) {
+ phase = globalPhase;
+ if (globalPhase.name == "terminal" && settings.Xshowicode.value)
+ icodeChecker.checkICodes;
+ else
+ checker.checkTrees;
+ }
+ }
+
+ if (settings.Xshowcls.value != "") showDef(newTermName(settings.Xshowcls.value), false);
+ if (settings.Xshowobj.value != "") showDef(newTermName(settings.Xshowobj.value), true);
+ if (settings.Xshowicode.value) printICode();
+
+ if (reporter.errors() == 0) {
+ for (val Pair(sym, pickled) <- symData.elements.toList) {
+ sym.pos = Position.NOPOS;
+ if (symData contains sym) {
+ symData -= sym;
+ symData -= sym.linkedSym;
+ writeSymblFile(sym, pickled)
+ }
+ }
+ } else {
+ for (val Pair(sym, file) <- symSource.elements) {
+ sym.reset(new loaders.SourcefileLoader(file));
+ if (sym.isTerm) sym.moduleClass.reset(loaders.errorLoader);
+ }
+ }
+ informTime("total", startTime);
+ informStatistics;
+ }
+
+ def compileLate(file: AbstractFile): unit =
+ if (fileset == null)
+ throw new FatalError("No symbol file for " + file + " was found\n(This file cannot be loaded as a source file)");
+ else if (!(fileset contains file)) {
+ val unit = new CompilationUnit(getSourceFile(file));
+ addUnit(unit);
+ var localPhase = parserPhase.asInstanceOf[GlobalPhase];
+ while (localPhase.id < globalPhase.id || localPhase.id <= parserPhase.next.id) {
+ atPhase(localPhase)(localPhase.applyPhase(unit));
+ localPhase = localPhase.next.asInstanceOf[GlobalPhase];
+ }
+ }
+
+ def compileFiles(files: List[AbstractFile]): unit =
+ try {
+ compileSources(files map getSourceFile)
+ } catch {
+ case ex: IOException => error(ex.getMessage());
+ }
+
+ def compile(filenames: List[String]): unit =
+ try {
+ compileSources(filenames map getSourceFile)
+ } catch {
+ case ex: IOException => error(ex.getMessage());
+ }
+
+ def showDef(name: Name, module: boolean): unit = {
+ def getSym(name: Name, module: boolean): Symbol = {
+ var i = name.length - 1;
+ while (i != 0 && name(i) != '#' && name(i) != '.') i = i - 1;
+ if (i == 0)
+ definitions.getModule(name)
+ else {
+ val root = getSym(name.subName(0, i), name(i) == '.');
+ var selector = name.subName(i+1, name.length);
+ if (module) selector = selector.toTypeName;
+ root.info.member(selector)
+ }
+ }
+ val sym = getSym(name, module);
+ System.err.println("" + sym.name + ":" +
+ (if (module) sym.tpe.symbol.info else sym.info))
+ }
+
+ /** Returns the file with the given suffix for the given class. */
+ private def getFile(clazz: Symbol, suffix: String) = {
+ val outdirname = settings.outdir.value;
+ var outdir = new File(if (outdirname == "") "." else outdirname);
+ val filename = clazz.fullNameString('.');
+ var start = 0;
+ var end = filename.indexOf('.', start);
+ while (end >= start) {
+ outdir = new File(outdir, filename.substring(start, end));
+ if (!outdir.exists()) outdir.mkdir();
+ start = end + 1;
+ end = filename.indexOf('.', start);
+ }
+ new File(outdir, filename.substring(start) + suffix)
+ }
+
+ private def writeSymblFile(clazz: Symbol, pickled: PickleBuffer) = {
+ val file = getFile(clazz, ".symbl");
+ try {
+ val stream = new FileOutputStream(file);
+ stream.write(pickled.bytes, 0, pickled.writeIndex);
+ stream.close();
+ informProgress("wrote " + file);
+ } catch {
+ case ex: IOException =>
+ if (settings.debug.value) ex.printStackTrace();
+ error("could not write file " + file);
+ }
+ }
+
+ private def printICode(): Unit = {
+ val printer = new icodePrinter.TextPrinter(new PrintWriter(System.out, true));
+ icodes.classes.foreach(printer.printClass);
+ }
+
+ private def informStatistics = {
+ inform("#identifiers : " + analyzer.idcnt);
+ inform("#selections : " + analyzer.selcnt);
+ inform("#applications: " + analyzer.appcnt);
+ inform("#implicits : " + analyzer.implcnt);
+ inform("#typecreates : " + accesses);
+ inform("#uniquetypes : " + uniques);
+ inform("#collisions : " + collisions);
+ }
+}
+=======
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc;
+
+import java.io._;
+import java.nio.charset._;
+import scala.tools.util._;
+import scala.collection.mutable.{HashSet,HashMap}
+
+import symtab._;
+import symtab.classfile.{PickleBuffer, Pickler};
+import util.ListBuffer;
+import ast._;
+import ast.parser._;
+import typechecker._;
+import matching.TransMatcher;
+import transform._;
+import backend.icode.{ICodes, GenICode, Checkers};
+import backend.ScalaPrimitives;
+
+class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
+ with Trees
+ with CompilationUnits
+{
+
+ // sub-components --------------------------------------------------
+
+ object treePrinters extends TreePrinters {
+ val global: Global.this.type = Global.this
+ }
+ val treePrinter = treePrinters.create();
+
+ object treeBrowsers extends TreeBrowsers {
+ val global: Global.this.type = Global.this
+ }
+ val treeBrowser = treeBrowsers.create();
+
+ object treeInfo extends TreeInfo {
+ val global: Global.this.type = Global.this
+ }
+
+ object gen extends TreeGen {
+ val global: Global.this.type = Global.this
+ }
+
+ object constfold extends ConstantFolder {
+ val global: Global.this.type = Global.this
+ }
+
+ object checker extends TreeCheckers {
+ val global: Global.this.type = Global.this
+ }
+
+ object icodes extends ICodes {
+ val global: Global.this.type = Global.this
+ }
+
+ object checkers extends Checkers {
+ val global: Global.this.type = Global.this
+ }
val copy = new LazyTreeCopier();
@@ -457,3 +916,4 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
inform("#collisions : " + collisions);
}
}
+
diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala
index 453ecced91..a2541d8e74 100755
--- a/sources/scala/tools/nsc/ast/TreeGen.scala
+++ b/sources/scala/tools/nsc/ast/TreeGen.scala
@@ -96,7 +96,6 @@ abstract class TreeGen {
result
}
-
/** Builds an instance test with given value and type. */
def mkIsInstanceOf(value: Tree, tpe: Type, erased: Boolean): Tree = {
val sym =
diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala
index c64936f62a..0cadf154a9 100644
--- a/sources/scala/tools/nsc/symtab/Flags.scala
+++ b/sources/scala/tools/nsc/symtab/Flags.scala
@@ -56,7 +56,8 @@ object Flags {
final val IS_ERROR = 0x100000000l; // symbol is an error symbol
final val OVERLOADED = 0x200000000l; // symbol is overloaded
- final val FLATTENED = 0x400000000l; // class has been lifted out to package level
+ final val LIFTED = 0x400000000l; // class has been lifted out to package level
+ // local value has been lifted out to class level
final val MIXEDIN = 0x800000000l; // member has been mixed in
final val EXPANDEDNAME = 0x1000000000l; // name has been expanded with class suffix
@@ -79,7 +80,11 @@ object Flags {
final val lateFINAL = (FINAL: long) << LateShift;
final val notPRIVATE = (PRIVATE: long) << AntiShift;
final val notPROTECTED = (PROTECTED: long) << AntiShift;
- final val notFINAL = (FINAL: long) << AntiShift;
+ final val notABSTRACT = (ABSTRACT: long) << AntiShift;
+ final val notOVERRIDE = (OVERRIDE: long) << AntiShift;
+
+ final val STATICMODULE = lateMODULE;
+ final val STATICMEMBER = notOVERRIDE;
// masks
/** This flags can be set when class or module symbol is first created. */
@@ -115,11 +120,14 @@ object Flags {
else if (flag == INTERFACE) "<interface>"
else if (flag == IS_ERROR) "<is-error>"
else if (flag == OVERLOADED) "<overloaded>"
+ else if (flag == LIFTED) "<lifted>"
else if (flag == TRANS_FLAG) "<trans-flag>"
else if (flag == MIXEDIN) "<mixedin>"
else if (flag == EXPANDEDNAME) "<expandedname>"
else if (flag == INITIALIZED) "<initialized>"
else if (flag == LOCKED) "<locked>"
+ else if (flag == STATICMODULE) "<staticobject>"
+ else if (flag == STATICMEMBER) "<staticmember>"
else flag.asInstanceOf[int] match {
case IMPLICIT => "implicit"
case FINAL => "final"
diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala
index d123fd2a31..3c15ad920f 100755
--- a/sources/scala/tools/nsc/symtab/Names.scala
+++ b/sources/scala/tools/nsc/symtab/Names.scala
@@ -203,6 +203,8 @@ class Names {
*/
final def lastPos(c: char): int = lastPos(c, len - 1);
+ final def lastPos(s: String): int = lastPos(s, len - s.length());
+
/** return the index of last occurrence of char c in this name from `start',
* -1 if not found
*/
@@ -212,6 +214,22 @@ class Names {
i
}
+ /** return the index of last occurrence of string s in this name from `start',
+ * -1 if not found
+ */
+ final def lastPos(s: String, start: int): int = {
+ var i = lastPos(s.charAt(0), start);
+ while (i >= 0) {
+ var j = 1;
+ while (s.charAt(j) == chrs(index + i + j)) {
+ j = j + 1;
+ if (j == s.length()) return i;
+ }
+ i = lastPos(s.charAt(0), i - 1)
+ }
+ -s.length()
+ }
+
/** does this name start with prefix?
*/
final def startsWith(prefix: Name): boolean = startsWith(prefix, 0);
diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala
index 995b1e0fda..2942e11473 100755
--- a/sources/scala/tools/nsc/symtab/StdNames.scala
+++ b/sources/scala/tools/nsc/symtab/StdNames.scala
@@ -62,56 +62,72 @@ abstract class StdNames: SymbolTable {
val HASHkw = newTermName("#");
val ATkw = newTermName("@");
- private val LOCAL_PREFIX_STRING = "local$";
- private val MIXIN_PREFIX_STRING = "mixin$";
- private val SUPER_PREFIX_STRING = "super$";
- private val ACCESS_PREFIX_STRING = "access$";
- private val TUPLE_FIELD_PREFIX_STRING = "_";
- private val TYPE_PREFIX_STRING = "type$";
-
- val LOCAL_PREFIX = newTermName(LOCAL_PREFIX_STRING);
-
- def LOCAL(clazz: Symbol) = newTermName(LOCAL_PREFIX_STRING + clazz.name);
+ val LOCALDUMMY_PREFIX_STRING = "local$";
+ val SUPER_PREFIX_STRING = "super$";
+ val EXPAND_SEPARATOR_STRING = "$$";
+ val TUPLE_FIELD_PREFIX_STRING = "_";
+ def LOCAL(clazz: Symbol) = newTermName(LOCALDUMMY_PREFIX_STRING + clazz.name);
def TUPLE_FIELD(index: int) = newTermName(TUPLE_FIELD_PREFIX_STRING + index);
- def isLocalName(name: Name) = originalName(name).endsWith(LOCAL_SUFFIX);
- def isSetterName(name: Name) = originalName(name).endsWith(_EQ);
+ val LOCAL_SUFFIX = newTermName(" ");
+ val SETTER_SUFFIX = encode("_=");
+ val IMPL_CLASS_SUFFIX = newTermName("$class");
+ val MODULE_SUFFIX = newTermName("$module");
+ val LOCALDUMMY_PREFIX = newTermName(LOCALDUMMY_PREFIX_STRING);
- def originalName(name: Name) = name.subName(0, name.pos("$$"));
+ def isLocalName(name: Name) = name.endsWith(LOCAL_SUFFIX);
+ def isSetterName(name: Name) = name.endsWith(SETTER_SUFFIX);
+ def isLocalDummyName(name: Name) = name.startsWith(LOCALDUMMY_PREFIX);
- private def applyToOriginal(name: Name, f: Name => Name): Name = {
- val oname = originalName(name);
- if (oname == name) f(name)
- else newTermName(f(oname).toString() + name.subName(oname.length, name.length))
+// def originalName(name: Name): Name = {
+ def originalName(name: Name): Name = {
+ var i = name.length;
+ while (i >= 2 && !(name(i - 1) == '$' && name(i - 2) == '$')) i = i - 1;
+ if (i >= 2) {
+ while (i >= 3 && name(i - 3) == '$') i = i - 1;
+ name.subName(i, name.length)
+ } else name
}
+// val result = originalName(name);
+// System.out.println("oroginal " + name + " = " + result);
+// result
+// }
def localToGetter(name: Name): Name = {
assert(isLocalName(name));//debug
- applyToOriginal(name, oname => oname.subName(0, oname.length - LOCAL_SUFFIX.length));
+ name.subName(0, name.length - LOCAL_SUFFIX.length);
}
def getterToLocal(name: Name): Name = {
assert(!isLocalName(name) && !isSetterName(name));//debug
- applyToOriginal(name, oname => newTermName(oname.toString() + LOCAL_SUFFIX));
+ newTermName(name.toString() + LOCAL_SUFFIX);
}
def getterToSetter(name: Name): Name = {
assert(!isLocalName(name) && !isSetterName(name));//debug
- applyToOriginal(name, oname => newTermName(oname.toString() + SETTER_SUFFIX));
+ newTermName(name.toString() + SETTER_SUFFIX);
}
def setterToGetter(name: Name): Name = {
- assert(isSetterName(name));//debug
- applyToOriginal(name, oname => oname.subName(0, oname.length - SETTER_SUFFIX.length));
+ name.subName(0, name.length - SETTER_SUFFIX.length);
}
def getterName(name: Name): Name =
if (isLocalName(name)) localToGetter(name) else name;
+ def isImplClassName(name: Name): boolean =
+ name endsWith IMPL_CLASS_SUFFIX;
+
def implClassName(name: Name): Name =
newTypeName(name.toString() + IMPL_CLASS_SUFFIX);
+ def moduleVarName(name: Name): Name =
+ newTermName(name.toString() + MODULE_SUFFIX);
+
+ def isModuleVarName(name: Name): boolean =
+ name.endsWith(MODULE_SUFFIX); //todo handle also local modules
+
def superName(name: Name) = newTermName("super$" + name);
val ERROR = newTermName("<error>");
@@ -133,14 +149,13 @@ abstract class StdNames: SymbolTable {
val ROOT = newTermName("<root>");
val REPEATED_PARAM_CLASS_NAME = newTermName("<repeated>");
val BYNAME_PARAM_CLASS_NAME = newTermName("<byname>");
- val SELF = newTermName("$self");
+ val SELF = newTermName("$this");
val CONSTRUCTOR = newTermName("<init>");
val MIXIN_CONSTRUCTOR = newTermName("$init$");
val INITIALIZER = newTermName("<init>");
val INLINED_INITIALIZER = newTermName("$init$");
- val _EQ = encode("_=");
val MINUS = encode("-");
val PLUS = encode("+");
val TILDE = encode("~");
@@ -291,10 +306,6 @@ abstract class StdNames: SymbolTable {
val JacoMetaATTR = newTermName("JacoMeta");
val ScalaSignatureATTR = newTermName("ScalaSignature");
val JavaInterfaceATTR = newTermName("JacoInterface");
-
- val LOCAL_SUFFIX = newTermName(" ");
- val SETTER_SUFFIX = _EQ;
- val IMPL_CLASS_SUFFIX = newTermName("$class");
}
def encode(str: String): Name = newTermName(NameTransformer.encode(str));
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index 789df61e80..bc4d4b79f1 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -97,10 +97,12 @@ abstract class Symbols: SymbolTable {
def isClass = false; //to be overridden
final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA));
- final def isVariable = isTerm && hasFlag(MUTABLE);
+ final def isVariable = isTerm && hasFlag(MUTABLE) && !isMethod;
+ final def isSetter = isTerm && hasFlag(ACCESSOR) && nme.isSetterName(name);
+ //todo: make independent of name, as this can be forged.
final def hasGetter = isTerm && nme.isLocalName(name);
final def isValueParameter = isTerm && hasFlag(PARAM);
- final def isLocalDummy = isTerm && (name startsWith nme.LOCAL_PREFIX);
+ final def isLocalDummy = isTerm && nme.isLocalDummyName(name);
final def isMethod = isTerm && hasFlag(METHOD);
final def isSourceMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD;
final def isLabel = isTerm && hasFlag(LABEL);
@@ -115,7 +117,8 @@ abstract class Symbols: SymbolTable {
final def isAliasType = isType && !isClass && !hasFlag(DEFERRED);
final def isAbstractType = isType && !isClass && hasFlag(DEFERRED);
final def isTypeParameter = isType && hasFlag(PARAM);
- final def isAnonymousClass = isClass && (name startsWith nme.ANON_CLASS_NAME); // startsWith necessary because name may grow when lifted and also because of anonymous function classes
+ final def isAnonymousClass = isClass && (originalName startsWith nme.ANON_CLASS_NAME);
+ // startsWith necessary because name may grow when lifted and also because of anonymous function classes
final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME.toTypeName; // no lifting for refinement classes
final def isModuleClass = isClass && hasFlag(MODULE);
final def isPackageClass = isClass && hasFlag(PACKAGE);
@@ -133,8 +136,13 @@ abstract class Symbols: SymbolTable {
isConstructor && owner.primaryConstructor == this;
/** Is this symbol an implementation class for a trait ? */
- final def isImplClass: boolean =
- name.endsWith(nme.IMPL_CLASS_SUFFIX);
+ final def isImplClass: boolean = isClass && nme.isImplClassName(name);
+
+ final def needsImplClass: boolean =
+ isTrait && (!hasFlag(INTERFACE) || hasFlag(lateINTERFACE)) && !isImplClass;
+
+ /** Is this symbol a module variable ? */
+ final def isModuleVar: boolean = isVariable && nme.isModuleVarName(name);
/** Is this symbol static (i.e. with no outer instance)? */
final def isStatic: boolean = hasFlag(STATIC) || isRoot || owner.isStaticOwner;
@@ -203,6 +211,8 @@ abstract class Symbols: SymbolTable {
def name: Name = rawname;
final def name_=(name: Name): unit = { rawname = name }
+ def originalName = nme.originalName(name);
+
final def flags = {
val fs = rawflags & phase.flagMask;
(fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift)
@@ -296,7 +306,7 @@ abstract class Symbols: SymbolTable {
phase = current;
limit = current;
}
- assert(infos != null/*, name.toString() + " " + limit + " " + phase*/);
+ assert(infos != null, name);
infos.info
} else {
var infos = this.infos;
@@ -454,11 +464,11 @@ abstract class Symbols: SymbolTable {
*/
final def accessed: Symbol = {
assert(hasFlag(ACCESSOR));
- //todo: make independent of name, as this can be forged.
- owner.info.decl(
- nme.getterToLocal(if (nme.isSetterName(name)) nme.setterToGetter(name) else name))
+ owner.info.decl(nme.getterToLocal(if (isSetter) nme.setterToGetter(name) else name))
}
+ final def implClass: Symbol = owner.info.decl(nme.implClassName(name));
+
/** For a paramaccessor: a superclass paramaccessor for which this symbol is
* an alias, NoSymbol for all others */
def alias: Symbol = NoSymbol;
@@ -492,6 +502,13 @@ abstract class Symbols: SymbolTable {
owner.info.decl(name.toTermName).suchThat(sym => sym.rawInfo != NoType)
else NoSymbol;
+ final def toInterface: Symbol =
+ if (isImplClass) {
+ val iface = tpe.parents.last.symbol;
+ assert(nme.implClassName(iface.name) == name, this);
+ iface
+ } else this;
+
/** The module corresponding to this module class (note that this
* is not updated when a module is cloned).
*/
@@ -525,17 +542,13 @@ abstract class Symbols: SymbolTable {
sym
}
- /** The superaccessor for this symbol in the definition of `base'. */
- final def superAccessor(base: Symbol): Symbol =
- base.info.decl(nme.superName(name)) suchThat (.alias.==(this));
-
/** The getter of this value definition in class `base', or NoSymbol if none exists */
final def getter(base: Symbol): Symbol =
- base.info.decl(nme.localToGetter(name)) filter (.hasFlag(ACCESSOR));
+ base.info.decl(nme.getterName(name)) filter (.hasFlag(ACCESSOR));
/** The setter of this value definition, or NoSymbol if none exists */
final def setter(base: Symbol): Symbol =
- base.info.decl(nme.getterToSetter(nme.localToGetter(name))) filter (.hasFlag(ACCESSOR));
+ base.info.decl(nme.getterToSetter(nme.getterName(name))) filter (.hasFlag(ACCESSOR));
/** Remove private modifier from symbol `sym's definition. If `sym' is a
* term symbol rename it by expanding its name to avoid name clashes
@@ -559,9 +572,12 @@ abstract class Symbols: SymbolTable {
getter(owner).expandName(base);
setter(owner).expandName(base);
}
- name = newTermName(name.toString() + "$$" + base.fullNameString('$'))
+ name = base.expandedName(name)
}
+ def expandedName(name: Name): Name =
+ newTermName(fullNameString('$') + nme.EXPAND_SEPARATOR_STRING + name);
+
/*
def referenced: Symbol =
throw new Error("referenced inapplicable for " + this);
@@ -709,9 +725,10 @@ abstract class Symbols: SymbolTable {
}
override def alias: Symbol =
- if (hasFlag(SUPERACCESSOR | PARAMACCESSOR)) referenced else NoSymbol;
+ if (hasFlag(SUPERACCESSOR | PARAMACCESSOR | MIXEDIN)) initialize.referenced else NoSymbol;
def setAlias(alias: Symbol): TermSymbol = {
+ assert(alias != NoSymbol);
assert(hasFlag(SUPERACCESSOR | PARAMACCESSOR | MIXEDIN));
referenced = alias;
this
@@ -738,12 +755,14 @@ abstract class Symbols: SymbolTable {
override def tpe: Type = {
assert(tpeCache != NoType, this);
if (tpePhase != phase) {
- if (isValid(tpePhase)) tpePhase = phase
- else {
+ if (isValid(tpePhase)) {
+ tpePhase = phase
+ } else {
if (hasFlag(INITIALIZED)) tpePhase = phase;
tpeCache = NoType;
- tpeCache = typeRef(if (isTypeParameter) NoPrefix else owner.thisType,
- this, unsafeTypeParams map (.tpe))
+ val targs = if (phase.erasedTypes && this != ArrayClass) List()
+ else unsafeTypeParams map (.tpe);
+ tpeCache = typeRef(if (isTypeParameter) NoPrefix else owner.thisType, this, targs)
}
}
assert(tpeCache != null/*, "" + this + " " + phase*/);//debug
@@ -803,12 +822,11 @@ abstract class Symbols: SymbolTable {
val p = thisTypePhase;
if (p != phase) {
thisTypePhase = phase;
- if (!isValid(p)) {
+ if (!(isValid(p) /*||
+ thisTypePhase != null && thisTypePhase.erasedTypes && phase.erasedTypes*/)) {
thisTypeCache =
- if (isModuleClass && !isRoot && !phase.erasedTypes) {
- assert(sourceModule != NoSymbol, this);
- singleType(owner.thisType, sourceModule);
- }
+ if (isModuleClass && !isRoot && !phase.erasedTypes)
+ singleType(owner.thisType, sourceModule);
else ThisType(this);
}
}
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 0c66540d66..cf8b9da1d7 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -166,14 +166,6 @@ abstract class Types: SymbolTable {
/** The type of `sym', seen as a memeber of this type. */
def memberType(sym: Symbol): Type = sym.tpe.asSeenFrom(this, sym.owner);
- /*
- def memberType(sym: Symbol): Type = {
- if (sym.nameString startsWith "PolyType")
- System.out.println("" + this + ".memberType(" + sym + ":" + sym.tpe + ") = " + memberType(sym) + ", owner = " + sym.owner);//debug
- memberType(sym)
- }
- */
-
/** Substitute types `to' for occurrences of references to symbols `from'
* in this type. */
def subst(from: List[Symbol], to: List[Type]): Type =
@@ -576,7 +568,6 @@ abstract class Types: SymbolTable {
override def narrow: Type = symbol.thisType;
override def toString(): String =
- "<" + symbol.toString() + ">" + //debug
parents.mkString("", " with ", "") +
(if (settings.debug.value || parents.isEmpty || decls.elems != null)
decls.mkString("{", "; ", "}") else "")
@@ -704,7 +695,7 @@ abstract class Types: SymbolTable {
*/
case class MethodType(override val paramTypes: List[Type],
override val resultType: Type) extends Type {
-
+ assert(paramTypes forall (pt => !pt.symbol.isImplClass));//debug
override def paramSectionCount: int = resultType.paramSectionCount + 1;
override def finalResultType: Type = resultType.finalResultType;
diff --git a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala
index 0a95ee5434..ea459829d4 100755
--- a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala
@@ -130,6 +130,7 @@ abstract class UnPickler {
}
sym.setFlag(flags);
if (readIndex != end) assert(sym hasFlag (SUPERACCESSOR | PARAMACCESSOR));
+ if (sym hasFlag SUPERACCESSOR) assert(readIndex != end);
sym.setInfo(
if (readIndex != end) new LazyTypeRefAndAlias(inforef, readNat())
else new LazyTypeRef(inforef));
diff --git a/sources/scala/tools/nsc/transform/AddInterfaces.scala b/sources/scala/tools/nsc/transform/AddInterfaces.scala
index 49db339b2c..bb6c6721ff 100755
--- a/sources/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/sources/scala/tools/nsc/transform/AddInterfaces.scala
@@ -15,7 +15,7 @@ abstract class AddInterfaces extends InfoTransform {
import definitions._; // standard classes and methods
import posAssigner.atPos; // for filling in tree positions
- override def phaseNewFlags: long = lateDEFERRED | lateINTERFACE | notFINAL;
+ override def phaseNewFlags: long = lateDEFERRED | lateINTERFACE;
// Type transformation
@@ -24,18 +24,15 @@ abstract class AddInterfaces extends InfoTransform {
private val implClassMap = new HashMap[Symbol, Symbol];
private val implMethodMap = new HashMap[Symbol, Symbol];
- private def needsImplClass(sym: Symbol): boolean =
- sym.isTrait && (!(sym hasFlag INTERFACE) || (sym hasFlag lateINTERFACE)) && !sym.isImplClass;
-
private def needsImplMethod(sym: Symbol): boolean =
sym.isMethod && isInterfaceMember(sym) &&
- (!(sym hasFlag DEFERRED) || (sym hasFlag lateDEFERRED));
+ (!(sym hasFlag (DEFERRED | SUPERACCESSOR)) || (sym hasFlag lateDEFERRED));
private def isInterfaceMember(sym: Symbol): boolean =
sym.isType ||
sym.isMethod && !(sym hasFlag (PRIVATE | BRIDGE | LABEL)) && !sym.isConstructor;
- private def implClass(iface: Symbol): Symbol = implClassMap.get(iface) match {
+ def implClass(iface: Symbol): Symbol = implClassMap.get(iface) match {
case Some(c) => c
case None =>
atPhase(erasurePhase) {
@@ -45,7 +42,9 @@ abstract class AddInterfaces extends InfoTransform {
impl.name = nme.implClassName(iface.name);
//includeInTypeOfThis(iface, impl);
//includeInTypeOfThis(impl, impl);
+ //todo: use implClassMap only for local impl classes
implClassMap(iface) = impl;
+ if (iface.owner.isClass) iface.owner.info.decls enter impl;
if (settings.debug.value) log("generating impl class " + impl);
impl
}
@@ -61,7 +60,7 @@ abstract class AddInterfaces extends InfoTransform {
val impl = sym.cloneSymbol(implClass).setInfo(sym.info);
if (!impl.isExternal) implMethodMap(sym) = impl;
decls enter impl;
- sym setFlag (lateDEFERRED | notFINAL)
+ sym setFlag lateDEFERRED
}
} else {
sym.owner = implClass;
@@ -74,7 +73,11 @@ abstract class AddInterfaces extends InfoTransform {
override def complete(sym: Symbol): unit = {
def implType(tp: Type): Type = tp match {
case ClassInfoType(parents, decls, _) =>
- ClassInfoType(traitToImplClass(parents) ::: List(iface.tpe), implDecls(sym, decls), sym)
+ //ClassInfoType(traitToImplClass(parents) ::: List(iface.tpe), implDecls(sym, decls), sym)
+ ClassInfoType(
+ ObjectClass.tpe :: (parents.tail map traitToImplClass) ::: List(iface.tpe),
+ implDecls(sym, decls),
+ sym)
case PolyType(tparams, restpe) =>
PolyType(tparams, implType(restpe))
}
@@ -85,36 +88,30 @@ abstract class AddInterfaces extends InfoTransform {
}
private def traitToImplClass(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args) if (needsImplClass(sym)) =>
+ case TypeRef(pre, sym, args) if (sym.needsImplClass) =>
typeRef(pre, implClass(sym), args)
case _ =>
tp
}
- private def traitToImplClass(parents: List[Type]): List[Type] =
- parents.head :: (parents.tail map traitToImplClass);
-
- private def addImplClasses(decls: Scope): Scope = {
- for (val sym <- decls.elements)
- if (needsImplClass(sym)) decls enter implClass(sym);
- decls
- }
-
def transformTraitInfo(tp: Type): Type = tp match {
case ClassInfoType(parents, decls, clazz) =>
- if (needsImplClass(clazz)) clazz setFlag lateINTERFACE;
- var parents1 =
+ if (clazz.needsImplClass) {
+ clazz setFlag lateINTERFACE;
+ implClass(clazz) // generate an impl class
+ }
+ val parents1 =
if (parents.isEmpty) List()
else {
- assert(!parents.head.symbol.isTrait);
+ assert(!parents.head.symbol.isTrait || clazz == RepeatedParamClass, clazz);
if (clazz hasFlag INTERFACE) erasedTypeRef(ObjectClass) :: parents.tail
else if (clazz.isImplClass || clazz == ArrayClass) parents
- else traitToImplClass(parents)
+ else parents map traitToImplClass
}
- val decls1 = addImplClasses(
- if (clazz hasFlag INTERFACE) new Scope(decls.toList filter isInterfaceMember)
- else new Scope(decls.toList));
- ClassInfoType(parents1, decls1, clazz)
+ val decls1 = if (clazz hasFlag INTERFACE) new Scope(decls.toList filter isInterfaceMember)
+ else decls;
+ if ((parents1 eq parents) && (decls1 eq decls)) tp
+ else ClassInfoType(parents1, decls1, clazz)
case _ =>
tp
}
@@ -170,7 +167,7 @@ abstract class AddInterfaces extends InfoTransform {
for (val tree <- trees)
tree match {
case ClassDef(_, _, _, _, impl) =>
- if (needsImplClass(tree.symbol))
+ if (tree.symbol.needsImplClass)
buf += {
val clazz = implClass(tree.symbol).initialize;
ClassDef(clazz, implTemplate(clazz, impl))
@@ -187,7 +184,7 @@ abstract class AddInterfaces extends InfoTransform {
override def transform(tree: Tree): Tree = {
val tree1 = tree match {
case ClassDef(mods, name, tparams, tpt, impl) =>
- if (needsImplClass(tree.symbol)) {
+ if (tree.symbol.needsImplClass) {
implClass(tree.symbol).initialize; // to force lateDEFERRED flags
copy.ClassDef(tree, mods | INTERFACE, name, tparams, tpt, ifaceTemplate(impl))
}
@@ -196,7 +193,7 @@ abstract class AddInterfaces extends InfoTransform {
val parents1 = tree.symbol.owner.info.parents map (t => TypeTree(t) setPos tree.pos);
copy.Template(tree, parents1, body)
case This(_) =>
- if (needsImplClass(tree.symbol)) {
+ if (tree.symbol.needsImplClass) {
val impl = implClass(tree.symbol);
var owner = currentOwner;
while (owner != tree.symbol && owner != impl) owner = owner.owner;
@@ -211,10 +208,10 @@ abstract class AddInterfaces extends InfoTransform {
tree.symbol.info.parents dropWhile (p => p.symbol.name != mix)
}
assert(!ps.isEmpty, tree);
- if (needsImplClass(ps.head.symbol)) implClass(ps.head.symbol).name
+ if (ps.head.symbol.needsImplClass) implClass(ps.head.symbol).name
else mix
}
- if (needsImplClass(tree.symbol)) Super(implClass(tree.symbol), mix1) setPos tree.pos
+ if (tree.symbol.needsImplClass) Super(implClass(tree.symbol), mix1) setPos tree.pos
else copy.Super(tree, qual, mix1)
case _ =>
tree
diff --git a/sources/scala/tools/nsc/transform/Constructors.scala b/sources/scala/tools/nsc/transform/Constructors.scala
index 1074fbb0a0..9d9230719c 100755
--- a/sources/scala/tools/nsc/transform/Constructors.scala
+++ b/sources/scala/tools/nsc/transform/Constructors.scala
@@ -43,8 +43,8 @@ abstract class Constructors extends Transform {
val paramAccessors = clazz.constrParamAccessors;
def parameter(acc: Symbol) = {
- val accname = nme.originalName(nme.getterName(acc.name));
- val ps = constrParams.filter { param => param.name == accname }
+ val accname = nme.getterName(acc.originalName);
+ val ps = constrParams.filter { param => accname == param.name }
if (ps.isEmpty) assert(false, "" + accname + " not in " + constrParams);
ps.head
}
@@ -79,12 +79,24 @@ abstract class Constructors extends Transform {
constrBody.stats foreach (constrStatBuf +=);
for (val stat <- stats) stat match {
- case DefDef(_, _, _, _, _, _) =>
- if (!stat.symbol.isPrimaryConstructor) defBuf += stat
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ stat.symbol.tpe match {
+ case MethodType(List(), tp @ ConstantType(c)) =>
+ defBuf += copy.DefDef(
+ stat, mods, name, tparams, vparamss, tpt,
+ Literal(c) setPos rhs.pos setType tp)
+ case _ =>
+ if (!stat.symbol.isPrimaryConstructor) defBuf += stat
+ }
case ValDef(mods, name, tpt, rhs) =>
- if (rhs != EmptyTree)
- constrStatBuf += mkAssign(stat.symbol, intoConstructor(stat.symbol, rhs));
- defBuf += copy.ValDef(stat, mods, name, tpt, EmptyTree)
+ if (stat.symbol.tpe.isInstanceOf[ConstantType])
+ assert(stat.symbol.getter != NoSymbol, stat)
+ else {
+ if (rhs != EmptyTree) {
+ constrStatBuf += mkAssign(stat.symbol, intoConstructor(stat.symbol, rhs));
+ }
+ defBuf += copy.ValDef(stat, mods, name, tpt, EmptyTree)
+ }
case _ =>
constrStatBuf += intoConstructor(impl.symbol, stat)
}
diff --git a/sources/scala/tools/nsc/transform/Erasure.scala b/sources/scala/tools/nsc/transform/Erasure.scala
index 96f3e3ebf3..b50edd055b 100755
--- a/sources/scala/tools/nsc/transform/Erasure.scala
+++ b/sources/scala/tools/nsc/transform/Erasure.scala
@@ -46,6 +46,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
*/
private val erasure = new TypeMap {
def apply(tp: Type): Type = tp match {
+ case ConstantType(_) =>
+ tp
case st: SubType =>
apply(st.supertype)
case TypeRef(pre, sym, args) =>
@@ -192,7 +194,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
/** Adapt `tree' to expected type `pt' */
private def adaptToType(tree: Tree, pt: Type): Tree = {
- if (settings.debug.value && pt != WildcardType) log("adapting " + tree + ":" + tree.tpe + " to " + pt);
+ //if (settings.debug.value && pt != WildcardType) log("adapting " + tree + ":" + tree.tpe + " to " + pt);//DEBUG
if (tree.tpe <:< pt)
tree
else if (isUnboxedClass(tree.tpe.symbol) && !isUnboxedClass(pt.symbol))
@@ -392,10 +394,14 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
atPhase(phase.next) {
atPos(bridge.pos) {
DefDef(bridge, vparamss =>
- ((Select(This(owner), bridgeTarget(bridge)): Tree) /: vparamss)
- ((fun, vparams) => Apply(fun, vparams map Ident)))
- } :: bridges;
- }
+ member.tpe match {
+ case MethodType(List(), ConstantType(c)) => Literal(c)
+ case _ =>
+ ((Select(This(owner), member): Tree) /: vparamss)
+ ((fun, vparams) => Apply(fun, vparams map Ident))
+ })
+ }
+ } :: bridges;
}
}
}
diff --git a/sources/scala/tools/nsc/transform/ExplicitOuter.scala b/sources/scala/tools/nsc/transform/ExplicitOuter.scala
index 44a64ffa69..469cabdcb7 100755
--- a/sources/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/sources/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -33,8 +33,9 @@ abstract class ExplicitOuter extends InfoTransform {
*/
def transformInfo(sym: Symbol, tp: Type): Type = tp match {
case MethodType(formals, restpe) =>
+ if (sym.owner.isTrait && (sym hasFlag PROTECTED)) sym setFlag notPROTECTED;
if (sym.isConstructor && !sym.owner.isStatic)
- MethodType(formals ::: List(sym.owner.owner.enclClass.thisType), restpe)
+ MethodType(formals ::: List(sym.owner.owner.enclClass.toInterface.thisType), restpe)
else tp;
case ClassInfoType(parents, decls, clazz) =>
var decls1 = decls;
@@ -67,7 +68,9 @@ abstract class ExplicitOuter extends InfoTransform {
private def outerMember(tp: Type): Symbol = {
var e = tp.decls.elems;
- while (!(e.sym.name.startsWith(nme.OUTER) && (e.sym hasFlag ACCESSOR))) e = e.next;
+ while (e != null && !(e.sym.originalName.startsWith(nme.OUTER) && (e.sym hasFlag ACCESSOR)))
+ e = e.next;
+ assert(e != null, tp);
e.sym
}
@@ -290,7 +293,7 @@ abstract class ExplicitOuter extends InfoTransform {
else rhs;
copy.DefDef(tree, mods, name, tparams, vparamss1, tpt, rhs1);
case This(qual) =>
- if (sym == currentOwner.enclClass || sym.isStatic) tree
+ if (sym == currentOwner.enclClass || (sym hasFlag MODULE) && sym.isStatic) tree
else atPos(tree.pos)(outerPath(outerValue, sym)); // (5)
case Select(qual @ Super(_, mix), name) =>
val qsym = qual.symbol;
diff --git a/sources/scala/tools/nsc/transform/Flatten.scala b/sources/scala/tools/nsc/transform/Flatten.scala
index 020f4c54ad..a94b0cf0e9 100755
--- a/sources/scala/tools/nsc/transform/Flatten.scala
+++ b/sources/scala/tools/nsc/transform/Flatten.scala
@@ -17,23 +17,44 @@ abstract class Flatten extends InfoTransform {
/** the following two members override abstract members in Transform */
val phaseName: String = "flatten";
+ private def liftClass(sym: Symbol): unit =
+ if (!(sym hasFlag LIFTED)) {
+ sym setFlag LIFTED;
+ atPhase(phase.next) {
+ if (settings.debug.value) log("re-enter " + sym + " in " + sym.owner);
+ assert(sym.owner.isPackageClass, sym);//debug
+ val scope = sym.owner.info.decls;
+ val old = scope lookup sym.name;
+ if (old != NoSymbol) scope unlink old;
+ scope enter sym;
+ }
+ }
+
private val flattened = new TypeMap {
def apply(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) if (pre.symbol.isClass && !pre.symbol.isPackageClass) =>
assert(args.isEmpty);
typeRef(sym.toplevelClass.owner.thisType, sym, args)
case ClassInfoType(parents, decls, clazz) =>
+ var parents1 = parents;
+ val decls1 = new Scope();
if (clazz.isPackageClass) {
- val decls1 = new Scope();
- for (val member <- decls.toList) {
- atPhase(phase.next)(decls1 enter member)
- }
- ClassInfoType(parents, decls1, clazz)
- } else {
- val parents1 = List.mapConserve(parents)(this);
- if (parents1 eq parents) tp
- else ClassInfoType(parents1, decls, clazz)
- }
+ atPhase(phase.next)(decls.toList foreach (decls1 enter))
+ } else {
+ atPhase(phase.next)(clazz.owner.info);
+ parents1 = List.mapConserve(parents)(this);
+ for (val sym <- decls.toList) {
+ if (sym.isTerm) decls1 enter sym
+ else if (sym.isClass) {
+ liftClass(sym);
+ if (sym.needsImplClass) liftClass(erasure.implClass(sym))
+ }
+ }
+ }
+ ClassInfoType(parents1, decls1, clazz)
+ case PolyType(tparams, restp) =>
+ val restp1 = apply(restp);
+ if (restp1 eq restp) tp else PolyType(tparams, restp1)
case _ =>
mapOver(tp)
}
@@ -73,15 +94,9 @@ abstract class Flatten extends InfoTransform {
tree
}
tree1 setType flattened(tree1.tpe);
- if (sym != null && sym.isNestedClass && !(sym hasFlag FLATTENED)) {
- sym setFlag FLATTENED;
- atPhase(phase.next) {
- if (settings.debug.value) log("re-enter " + sym + " in " + sym.owner);
- val scope = sym.owner.info.decls;
- val old = scope lookup sym.name;
- if (old != NoSymbol) scope unlink old;
- scope enter sym;
- }
+ if (sym != null && sym.isNestedClass && !(sym hasFlag LIFTED)) {
+ liftClass(sym);//todo: remove
+ if (sym.implClass != NoSymbol) liftClass(sym.implClass);
}
tree1
}
diff --git a/sources/scala/tools/nsc/transform/LambdaLift.scala b/sources/scala/tools/nsc/transform/LambdaLift.scala
index 353baf620b..e4647a41f2 100755
--- a/sources/scala/tools/nsc/transform/LambdaLift.scala
+++ b/sources/scala/tools/nsc/transform/LambdaLift.scala
@@ -13,8 +13,8 @@ import collection.mutable.HashMap;
abstract class LambdaLift extends InfoTransform {
import global._;
import definitions._;
- import typer.{typed}; // methods to type trees
- import posAssigner.atPos; // for filling in tree positions
+ import typer.{typed, typedOperator};
+ import posAssigner.atPos;
/** the following two members override abstract members in Transform */
val phaseName: String = "lambdalift";
@@ -127,15 +127,24 @@ abstract class LambdaLift extends InfoTransform {
liftedDefs(tree.symbol) = new ListBuffer;
if (sym.isLocal) renamable addEntry sym;
case DefDef(_, _, _, _, _, _) =>
- if (sym.isLocal) renamable addEntry sym;
- if (sym.isPrimaryConstructor) symSet(called, sym) addEntry sym.owner;
+ if (sym.isLocal) {
+ renamable addEntry sym;
+ sym setFlag (PRIVATE | LOCAL | FINAL)
+ } else if (sym.isPrimaryConstructor) {
+ symSet(called, sym) addEntry sym.owner
+ }
case Ident(name) =>
if (sym == NoSymbol) {
assert(name == nme.WILDCARD)
} else if (sym.isLocal) {
val owner = enclMethOrClass(currentOwner);
- if (owner.isMethod && sym.isMethod) symSet(called, owner) addEntry sym;
- else if (sym.isTerm) markFree(sym, owner)
+ if (sym.isTerm && !sym.isMethod) markFree(sym, owner)
+ else if (owner.isMethod && sym.isMethod) symSet(called, owner) addEntry sym;
+ }
+ case Select(_, _) =>
+ if (sym.isConstructor && sym.owner.isLocal) {
+ val owner = enclMethOrClass(currentOwner);
+ if (owner.isMethod) symSet(called, owner) addEntry sym;
}
case _ =>
}
@@ -203,14 +212,20 @@ abstract class LambdaLift extends InfoTransform {
else searchIn(currentOwner)
}
+ private def memberRef(sym: Symbol) = {
+ val clazz = sym.owner.enclClass;
+ val qual = if (clazz == currentOwner.enclClass) gen.This(clazz)
+ else {
+ sym resetFlag(LOCAL | PRIVATE);
+ if (clazz.isStaticOwner) gen.mkQualifier(clazz.thisType)
+ else outerPath(outerValue, clazz)
+ }
+ Select(qual, sym) setType sym.tpe
+ }
+
private def proxyRef(sym: Symbol) = {
val psym = proxy(sym);
- if (psym.isLocal) gen.Ident(psym)
- else if (psym.owner == currentOwner.enclClass) gen.mkRef(psym)
- else {
- psym resetFlag (PRIVATE | LOCAL);
- Select(outerPath(outerValue, psym.owner), psym) setType psym.tpe
- }
+ if (psym.isLocal) gen.Ident(psym) else memberRef(psym)
}
private def addFreeArgs(pos: int, sym: Symbol, args: List[Tree]) = {
@@ -237,10 +252,12 @@ abstract class LambdaLift extends InfoTransform {
private def liftDef(tree: Tree): Tree = {
val sym = tree.symbol;
- if (sym.isMethod) sym setFlag (PRIVATE | LOCAL);
sym.owner = sym.owner.enclClass;
+ if (sym.isClass) sym.owner = sym.owner.toInterface;
+ if (sym.isMethod) sym setFlag LIFTED;
liftedDefs(sym.owner) += tree;
sym.owner.info.decls enter sym;
+ if (settings.debug.value) log("lifted: " + sym + sym.locationString);
EmptyTree
}
@@ -281,9 +298,12 @@ abstract class LambdaLift extends InfoTransform {
copy.Assign(tree, qual, rhs)
case Ident(name) =>
val tree1 =
- if (sym != NoSymbol && sym.isLocal && sym.isTerm && !sym.isMethod &&
- enclMethOrClass(sym.owner) != enclMethOrClass(currentOwner))
- atPos(tree.pos)(proxyRef(sym))
+ if (sym != NoSymbol && sym.isTerm && !sym.isLabel)
+ if (sym.isMethod)
+ atPos(tree.pos)(memberRef(sym))
+ else if (sym.isLocal && enclMethOrClass(sym.owner) != enclMethOrClass(currentOwner))
+ atPos(tree.pos)(proxyRef(sym))
+ else tree
else tree;
if (sym hasFlag CAPTURED)
atPos(tree.pos) {
diff --git a/sources/scala/tools/nsc/transform/Mixin.scala b/sources/scala/tools/nsc/transform/Mixin.scala
index 4cf1ea4ff4..296f614f73 100755
--- a/sources/scala/tools/nsc/transform/Mixin.scala
+++ b/sources/scala/tools/nsc/transform/Mixin.scala
@@ -18,53 +18,20 @@ abstract class Mixin extends InfoTransform {
/** the following two members override abstract members in Transform */
val phaseName: String = "mixin";
- override def phaseNewFlags: long = lateMODULE;
+ override def phaseNewFlags: long = lateMODULE | notABSTRACT;
- def isForwarded(sym: Symbol) =
+ private def isForwarded(sym: Symbol) =
sym.owner.isImplClass && sym.isMethod && !(sym hasFlag (ACCESSOR | SUPERACCESSOR));
- def isStatic(sym: Symbol) = isForwarded(sym) && (sym.hasFlag(PRIVATE) || sym.isConstructor);
+ private def isStatic(sym: Symbol) = isForwarded(sym) && (sym.hasFlag(PRIVATE) || sym.isConstructor);
- def isSelfRef(tree: Tree) = tree match {
- case This(_) => true
- case Super(_, mix) => mix != nme.EMPTY.toTypeName
- case _ => false
- }
-/*
- def toImplClass(sym: Symbol): Symbol = {
- val impl = clazz.owner.info.decl(nme.IMPL_CLASS_NAME(clazz.name));
-
- }
-
- def toInterface(sym: Symbol): Symbol;
-*/
- def toInterface(tp: Type): Type =
- if (tp.symbol.isImplClass) {
- val iface = tp.parents.last;
- if (!tp.symbol.name.startsWith(iface.symbol.name)) assert(false, "bad interface: " + tp + " " + iface);
- iface
- } else tp;
-
- def makeUnique(decls: Scope, sym: Symbol): unit = {
- if ((sym hasFlag PRIVATE) && decls.lookup(sym.name) != NoSymbol) {
- val prefix = sym.name.toString() + "$";
- var index = 0;
- while (decls.lookup(newTermName(prefix + index)) != NoSymbol) index = index + 1;
- sym.name = newTermName(prefix + index)
- }
- }
-
- private def staticRef(sym: Symbol) = {
- System.out.println("static ref " + sym.owner + " . " + sym);//debug
- sym.owner.info;
- Select(gen.mkRef(sym.owner.sourceModule), sym);
- }
+ private def toInterface(tp: Type): Type = tp.symbol.toInterface.tpe;
private def rebindSuper(base: Symbol, member: Symbol, prevowner: Symbol): Symbol = {
var bcs = base.info.baseClasses.dropWhile(prevowner !=).tail;
var sym: Symbol = NoSymbol;
while (!bcs.isEmpty && sym == NoSymbol) {
- System.out.println("rebindsuper " + bcs.head + " " + bcs.head.info.nonPrivateDecl(member.name));//debug
+ if (settings.debug.value) log("rebindsuper " + bcs.head + " " + bcs.head.info.nonPrivateDecl(member.name));
sym = member.overridingSymbol(bcs.head).suchThat(sym => !sym.hasFlag(DEFERRED));
bcs = bcs.tail
}
@@ -72,78 +39,115 @@ abstract class Mixin extends InfoTransform {
sym
}
- private def implClass(iface: Symbol): Symbol =
- atPhase(flattenPhase)(iface.owner.info.decl(nme.implClassName(iface.name)));
+ private def implClass(iface: Symbol): Symbol = erasure.implClass(iface);
override def transformInfo(sym: Symbol, tp: Type): Type = tp match {
case ClassInfoType(parents, decls, clazz) =>
+ assert(sym == clazz, "not equal: " + sym + " " + clazz);
var parents1 = parents;
var decls1 = decls;
def addMember(member: Symbol): Symbol = {
if (decls1 eq decls) decls1 = new Scope(decls.toList);
- System.out.println("new member of " + clazz + ":" + member);//debug
+ if (settings.debug.value) log("new member of " + clazz + ":" + member.defString);//debug
decls1 enter member;
member
}
- def newGetter(field: Symbol): Symbol =
- clazz.newMethod(field.pos, nme.getterName(field.name))
- setFlag (field.flags & ~(PRIVATE | LOCAL | MUTABLE) | (ACCESSOR | DEFERRED | SYNTHETIC))
- setInfo MethodType(List(), field.info);
- def newSetter(field: Symbol): Symbol =
- clazz.newMethod(field.pos, nme.getterToSetter(nme.getterName(field.name)))
- setFlag (field.flags & ~(PRIVATE | LOCAL | MUTABLE) | (ACCESSOR | DEFERRED | SYNTHETIC))
- setInfo MethodType(List(field.info), UnitClass.tpe);
-
- if (clazz.isPackageClass) {
- for (val sym <- decls.elements) {
+ def addPackageClassMembers = {
+ for (val sym <- decls.toList) {
if (sym.isImplClass) {
- sym setFlag lateMODULE;
+ sym setFlag lateMODULE | notABSTRACT;
addMember(
clazz.newModule(sym.pos, sym.name.toTermName, sym.asInstanceOf[ClassSymbol])
setInfo sym.tpe)
}
}
- } else if (clazz hasFlag lateINTERFACE) {
+ }
+ def addLateInterfaceMembers = {
+ def newGetter(field: Symbol): Symbol =
+ clazz.newMethod(field.pos, nme.getterName(field.name))
+ setFlag (field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | DEFERRED | SYNTHETIC)
+ setInfo MethodType(List(), field.info);
+ def newSetter(field: Symbol): Symbol =
+ clazz.newMethod(field.pos, nme.getterToSetter(nme.getterName(field.name)))
+ setFlag (field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | DEFERRED | SYNTHETIC)
+ setInfo MethodType(List(field.info), UnitClass.tpe);
+ clazz.info;
val impl = implClass(clazz);
- assert(impl != NoSymbol, clazz);
- for (val member <- decls.toList) {
- if (!member.isMethod) {
- assert(member.isTerm && !member.hasFlag(DEFERRED));
- member.makeNotPrivate(clazz);
+ assert(impl != NoSymbol, "" + clazz + " " + flattenPhase.flatClasses + atPhase(flattenPhase)(clazz.owner.info.decls));
+ for (val member <- impl.info.decls.toList) {
+ if (!member.isMethod && !member.isModule && !member.isModuleVar)) {
+ assert(member.isTerm && !member.hasFlag(DEFERRED), member);
+ if (member.getter(impl) hasFlag PRIVATE) member.makeNotPrivate(clazz);
var getter = member.getter(clazz);
if (getter == NoSymbol) getter = addMember(newGetter(member));
- getter setFlag FINAL;
+ else getter setFlag (member getFlag MUTABLE);
if (!member.tpe.isInstanceOf[ConstantType]) {
var setter = member.setter(clazz);
- if (getter == NoSymbol) setter = addMember(newSetter(member));
- setter setFlag FINAL
+ if (setter == NoSymbol) setter = addMember(newSetter(member));
}
- }
- }
- } else if (clazz.isImplClass) {
- transformInfo(clazz.owner, clazz.owner.info);
- parents1 = List();
- decls1 = new Scope(decls.toList filter isForwarded)
- } else if (!parents.isEmpty) {
- parents1 = parents.head :: (parents.tail map toInterface);
+ } else if ((member hasFlag LIFTED) && !(member hasFlag PRIVATE)) {
+ member.expandName(clazz);
+ addMember(member.cloneSymbol(clazz));
+ }
+ }
+ }
+ def addMixedinMembers = {
for (val bc <- clazz.info.baseClasses.tail.takeWhile(parents.head.symbol !=)) {
if (bc.isImplClass) {
for (val member <- bc.info.decls.toList) {
- if (isForwarded(member) && (clazz.info.member(member.name).alternatives contains member)) {
- val member1 = member.cloneSymbol(clazz) setFlag MIXEDIN;
+ if (isForwarded(member) && !isStatic(member) &&
+ (clazz.info.member(member.name).alternatives contains member)) {
+ val member1 = addMember(member.cloneSymbol(clazz) setFlag MIXEDIN);
member1.asInstanceOf[TermSymbol] setAlias member;
+ }
+ }
+ } else if (bc.hasFlag(lateINTERFACE)) {
+ for (val member <- atPhase(phase.next)(bc.info.decls.toList)) {
+ if (member hasFlag ACCESSOR) {
+ val member1 = addMember(
+ member.cloneSymbol(clazz) setFlag (MIXEDIN | FINAL) resetFlag DEFERRED);
+ if (!member.isSetter)
+ member.tpe match {
+ case MethodType(List(), ConstantType(_)) =>
+ ;
+ case _ =>
+ addMember(
+ clazz.newValue(member.pos, nme.getterToLocal(member.name))
+ setFlag (LOCAL | PRIVATE | MIXEDIN | member.getFlag(MUTABLE))
+ setInfo member.tpe.resultType)
+ }
} else if (member hasFlag SUPERACCESSOR) {
- member.asInstanceOf[TermSymbol] setAlias rebindSuper(clazz, member.alias, bc);
- addMember(member)
+ val member1 = addMember(member.cloneSymbol(clazz)) setFlag MIXEDIN;
+ assert(member1.alias != NoSymbol, member1);
+ member1.asInstanceOf[TermSymbol] setAlias rebindSuper(clazz, member.alias, bc);
+ } else if (member.isMethod && member.sModule && !(member hasFlag LIFTED)) {
+ addMember(member.cloneSymbol(clazz) setFlag MIXEDIN)
}
}
}
}
}
- if ((parents1 eq parents) && (decls1 eq decls)) tp else ClassInfoType(parents, decls1, clazz)
+
+ if (clazz.isPackageClass) {
+ addPackageClassMembers
+ } else {
+ atPhase(phase.next)(clazz.owner.info);
+ if (clazz.isImplClass) {
+ parents1 = List();
+ decls1 = new Scope(decls.toList filter isForwarded)
+ } else if (!parents.isEmpty) {
+ parents1 = parents.head :: (parents.tail map toInterface);
+ if (!(clazz hasFlag INTERFACE)) addMixedinMembers
+ else if (clazz hasFlag lateINTERFACE) addLateInterfaceMembers
+ }
+ }
+ if (settings.debug.value && !clazz.isPackageClass) log("new defs of " + clazz + " = " + decls1);
+ decls1 = atPhase(phase.next)(new Scope(decls1.toList));//debug
+ if ((parents1 eq parents) && (decls1 eq decls)) tp
+ else ClassInfoType(parents1, decls1, clazz);
+
case MethodType(formals, restp) =>
- if (isForwarded(sym))
- MethodType(toInterface(sym.owner.thisType) :: formals, restp)
+ if (isForwarded(sym)) MethodType(toInterface(sym.owner.typeOfThis) :: formals, restp)
else tp
case _ =>
tp
@@ -152,95 +156,180 @@ abstract class Mixin extends InfoTransform {
protected def newTransformer(unit: CompilationUnit): Transformer = new MixinTransformer;
class MixinTransformer extends Transformer {
+ private var self: Symbol = _;
+ private var localTyper: analyzer.Typer = _;
+ private var enclInterface: Symbol = _;
+
+ private def preTransform(tree: Tree): Tree = {
+ val sym = tree.symbol;
+ tree match {
+ case Template(parents, body) =>
+ localTyper = typer.atOwner(tree, currentOwner);
+ tree
+ case DefDef(mods, name, tparams, List(vparams), tpt, rhs) if currentOwner.isImplClass =>
+ if (isForwarded(sym)) {
+ sym setFlag notOVERRIDE;
+ self = sym.newValue(sym.pos, nme.SELF)
+ setFlag (PARAM | SYNTHETIC)
+ setInfo toInterface(currentOwner.typeOfThis);
+ enclInterface = currentOwner.toInterface;
+ val selfdef = ValDef(self) setType NoType;
+ copy.DefDef(tree, mods, name, tparams, List(selfdef :: vparams), tpt, rhs)
+ } else {
+ EmptyTree
+ }
+ case ValDef(_, _, _, _) if (currentOwner.isImplClass) =>
+ EmptyTree
+ case _ =>
+ tree
+ }
+ }
- var self: Symbol = _;
- var localTyper: analyzer.Typer = _;
+ private def selfRef(pos: int) = gen.Ident(self) setPos pos;
+
+ private def staticRef(sym: Symbol) = {
+ sym.owner.info;
+ if (sym.owner.sourceModule == NoSymbol)
+ assert(false, "" + sym.owner + " " + sym.owner.owner.info.decls);//debug
+ Select(gen.mkRef(sym.owner.sourceModule), sym);
+ }
private def addNewDefs(clazz: Symbol, stats: List[Tree]): List[Tree] = {
val newDefs = new ListBuffer[Tree];
def addDef(pos: int, tree: Tree): unit = {
- System.out.println("add new def to " + clazz + ": " + tree);
- newDefs += localTyper.typed(atPos(pos)(tree))
+ if (settings.debug.value) log("add new def to " + clazz + ": " + tree);
+ newDefs += localTyper.typed {
+ atPos(pos) {
+ tree
+ }
+ }
}
def position(sym: Symbol) =
if (sym.pos == Position.NOPOS) clazz.pos else sym.pos;
def addDefDef(sym: Symbol, rhs: List[Symbol] => Tree): unit =
addDef(position(sym), DefDef(sym, vparamss => rhs(vparamss.head)));
- if (!clazz.isImplClass) {
- atPhase(phase.next) {
- for (val sym <- clazz.info.decls.toList) {
- if (sym hasFlag MIXEDIN) {
- if (sym hasFlag SUPERACCESSOR) {
- addDefDef(sym, vparams =>
- Apply(Select(Super(clazz, nme.EMPTY.toTypeName), sym.alias), vparams map Ident))
- } else if (sym hasFlag ACCESSOR) {
- addDefDef(sym, vparams =>
- Select(This(clazz), sym.accessed))
- } else if (isForwarded(sym)) {
- addDefDef(sym, vparams =>
- Apply(staticRef(sym.alias), gen.This(clazz) :: (vparams map Ident)))
- } else {
- addDef(position(sym), ValDef(sym))
- }
+ def completeSuperAccessor(stat: Tree) = stat match {
+ case DefDef(mods, name, tparams, List(vparams), tpt, EmptyTree)
+ if (stat.symbol hasFlag SUPERACCESSOR) =>
+ assert(stat.symbol hasFlag MIXEDIN, stat);
+ val rhs1 =
+ localTyper.typed {
+ atPos(stat.pos) {
+ Apply(Select(Super(clazz, nme.EMPTY.toTypeName), stat.symbol.alias),
+ vparams map (vparam => Ident(vparam.symbol)))
+ }
+ }
+ copy.DefDef(stat, mods, name, tparams, List(vparams), tpt, rhs1)
+ case _ =>
+ assert(!(stat.symbol hasFlag SUPERACCESSOR), stat);
+ stat
+ }
+ var stats1 = stats;
+ if (clazz hasFlag lateINTERFACE) {
+ for (val sym <- clazz.info.decls.toList) {
+ if ((sym hasFlag SYNTHETIC) && (sym hasFlag ACCESSOR))
+ addDefDef(sym, vparamss => EmptyTree)
+ }
+ } else if (!clazz.isImplClass && !(clazz hasFlag INTERFACE)) {
+ for (val sym <- clazz.info.decls.toList) {
+ if (sym hasFlag MIXEDIN) {
+ if (sym hasFlag ACCESSOR) {
+ addDefDef(sym, vparams => {
+ val accessedRef = sym.tpe match {
+ case MethodType(List(), ConstantType(c)) => Literal(c)
+ case _ => Select(This(clazz), sym.accessed)
+ }
+ if (sym.isSetter) Assign(accessedRef, Ident(vparams.head)) else accessedRef})
+ } else if (sym.isModule && !(sym hasFlag LIFTED)) {
+ val vdef = refchecks.newModuleVarDef(sym);
+ addDef(position(sym), vdef);
+ addDef(position(sym), refchecks.newModuleAccessDef(sym, vdef.symbol));
+ } else if (!sym.isMethod) {
+ addDef(position(sym), ValDef(sym))
+ } else if (!(sym hasFlag SUPERACCESSOR)) {
+ assert(sym.alias != NoSymbol, sym);
+ addDefDef(sym, vparams =>
+ Apply(staticRef(sym.alias), gen.This(clazz) :: (vparams map Ident)))
}
}
}
+ stats1 = stats map completeSuperAccessor;
}
- if (newDefs.hasNext) stats ::: newDefs.toList else stats
+ if (newDefs.hasNext) stats1 ::: newDefs.toList else stats1
}
- override def transform(tree: Tree): Tree = {
- try { //debug
+ private def postTransform(tree: Tree): Tree = atPhase(phase.next) {
val sym = tree.symbol;
- val tree1 = tree match {
+ tree match {
case Template(parents, body) =>
- localTyper = typer.atOwner(tree, currentOwner);
- tree
- case DefDef(mods, name, tparams, List(vparams), tpt, rhs) =>
- if (isForwarded(sym)) {
- self = sym.newValue(sym.pos, nme.SELF)
- setFlag PARAM
- setInfo toInterface(currentOwner.thisType);
- val selfdef = ValDef(self) setType NoType;
- copy.DefDef(tree, mods, name, tparams, List(selfdef :: vparams), tpt, rhs)
- } else if (currentOwner.isImplClass) {
- EmptyTree
- } else tree
- case ValDef(_, _, _, _) if (currentOwner.isImplClass) =>
- EmptyTree
- case Super(_, mix) if (mix == nme.EMPTY.toTypeName && currentOwner.isImplClass) =>
- atPos(tree.pos){
+ val parents1 = currentOwner.info.parents map (t => TypeTree(t) setPos tree.pos);
+ val body1 = addNewDefs(currentOwner, body);
+ copy.Template(tree, parents1, body1)
+ case Apply(Select(qual, _), args) =>
+ assert(sym != NoSymbol, tree);//debug
+ if (isStatic(sym)) {
+ assert(sym.isConstructor || currentOwner.enclClass.isImplClass, tree);
localTyper.typed {
- Select(Ident(self), sym.superAccessor(self.tpe.symbol))
- }
- }
- case Apply(Select(qual, _), args)
- if (isSelfRef(qual) && currentOwner.enclClass.isImplClass &&
- sym.owner.isImplClass && isStatic(sym)) =>
- atPos(tree.pos) {
- atPhase(phase.next) {
- localTyper.typed {
- Apply(staticRef(sym), Ident(self) :: args)
+ atPos(tree.pos) {
+ Apply(staticRef(sym), qual :: args)
}
}
+ } else tree
+ case This(_) if tree.symbol.isImplClass =>
+ assert(tree.symbol == currentOwner.enclClass, "" + tree.symbol + " " + currentOwner.enclClass);
+ selfRef(tree.pos)
+ case Select(qual @ Super(_, mix), name) =>
+ if (currentOwner.enclClass.isImplClass) {
+ if (mix == nme.EMPTY.toTypeName) {
+ val superAccName = enclInterface.expandedName(nme.superName(sym.name));
+ val superAcc = enclInterface.info.decl(superAccName) suchThat (.alias.==(sym));
+ assert(superAcc != NoSymbol, tree);//debug
+ localTyper.typedOperator {
+ atPos(tree.pos){
+ Select(selfRef(qual.pos), superAcc)
+ }
+ }
+ } else {
+ copy.Select(tree, selfRef(qual.pos), name)
+ }
+ } else {
+ if (mix == nme.EMPTY.toTypeName) tree
+ else copy.Select(tree, gen.This(currentOwner.enclClass) setPos qual.pos, name)
+ }
+ case Select(qual, name) if sym.owner.isImplClass && !isStatic(sym) =>
+ if (sym.isMethod) {
+ assert(sym hasFlag LIFTED, sym);
+ val sym1 = enclInterface.info.decl(sym.name);
+ assert(sym1 != NoSymbol && !(sym1 hasFlag OVERLOADED), sym);//debug
+ tree setSymbol sym1
+ } else {
+ val getter = sym.getter(enclInterface);
+ assert(getter != NoSymbol, "" + enclInterface + " " + sym);
+ localTyper.typed {
+ atPos(tree.pos) {
+ Apply(Select(qual, getter), List())
+ }
+ }
}
- case This(_) if (sym.isImplClass) =>
- atPos(tree.pos)(gen.Ident(self))
- case _ =>
- tree
- }
- val tree2 = super.transform(tree1);
- tree2 match {
- case Template(parents, body) =>
- copy.Template(tree2, parents, addNewDefs(currentOwner, body))
+ case Assign(Apply(lhs @ Select(qual, _), List()), rhs) =>
+ localTyper.typed {
+ atPos(tree.pos) {
+ Apply(Select(qual, lhs.symbol.setter(enclInterface)) setPos lhs.pos, List(rhs))
+ }
+ }
case _ =>
- tree2
+ tree
+ }
+ }
+
+ override def transform(tree: Tree): Tree = {
+ try { //debug
+ postTransform(super.transform(preTransform(tree)))
+ } catch {
+ case ex: Throwable =>
+ System.out.println("exception when traversing " + tree);
+ throw ex
}
- } catch {//debug
- case ex: Throwable =>
- System.out.println("exception when traversing " + tree);
- throw ex
- }
}
}
}
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index cb3226c705..b547301645 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -65,7 +65,7 @@ trait Namers: Analyzer {
p.pos = pos; p.moduleClass.pos = pos; p
} else {
val pkg = context.owner.newPackage(pos, name);
- pkg.moduleClass.setInfo(new PackageClassInfoType(new Scope(), pkg));
+ pkg.moduleClass.setInfo(new PackageClassInfoType(new Scope(), pkg.moduleClass));
pkg.setInfo(pkg.moduleClass.tpe);
enterInScope(pkg)
}
@@ -240,7 +240,10 @@ trait Namers: Analyzer {
}
private def deconstIfNotFinal(sym: Symbol, tpe: Type): Type =
- if (sym.isVariable || !(sym hasFlag FINAL)) tpe.deconst else tpe;
+ if (sym.isVariable ||
+ !(sym hasFlag FINAL) ||
+ sym.isMethod && !(sym hasFlag ACCESSOR)) tpe.deconst
+ else tpe;
def enterValueParams(owner: Symbol, vparamss: List[List[ValDef]]): List[List[Symbol]] = {
def enterValueParam(param: ValDef): Symbol = {
diff --git a/sources/scala/tools/nsc/typechecker/RefChecks.scala b/sources/scala/tools/nsc/typechecker/RefChecks.scala
index 71ac61b4f6..f78c74c821 100755
--- a/sources/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/sources/scala/tools/nsc/typechecker/RefChecks.scala
@@ -51,6 +51,31 @@ abstract class RefChecks extends InfoTransform {
} else tp
}
+ // var m$: T = null; or, if class member: local var m$: T = _;
+ def newModuleVarDef(accessor: Symbol) = {
+ val mvar = accessor.owner.newVariable(accessor.pos, nme.moduleVarName(accessor.name))
+ setInfo accessor.tpe.finalResultType;
+ if (mvar.owner.isClass) {
+ mvar setFlag (PRIVATE | LOCAL | SYNTHETIC);
+ mvar.owner.info.decls.enter(mvar);
+ }
+ ValDef(mvar, if (mvar.owner.isClass) EmptyTree else Literal(Constant(null)))
+ }
+
+ // def m: T = { if (m$ == null) m$ = new m$class; m$ }
+ def newModuleAccessDef(accessor: Symbol, mvar: Symbol) =
+ DefDef(accessor, vparamss =>
+ Block(
+ List(
+ If(
+ Apply(Select(Ident(mvar), nme.eq), List(Literal(Constant(null)))),
+ Assign(Ident(mvar),
+ New(TypeTree(mvar.tpe),
+ List(for (val pt <- mvar.tpe.symbol.primaryConstructor.info.paramTypes)
+ yield This(accessor.owner.enclClass)))),//???
+ EmptyTree)),
+ Ident(mvar)));
+
class RefCheckTransformer(unit: CompilationUnit) extends Transformer {
// Override checking ------------------------------------------------------------
@@ -186,7 +211,7 @@ abstract class RefChecks extends InfoTransform {
if (member hasFlag DEFERRED) {
abstractClassError(
infoString(member) + " is not defined" +
- (if (member hasFlag MUTABLE)
+ (if (member.isVariable)
"\n(Note that variables need to be initialized to be defined)" else ""))
} else if (member.isIncompleteIn(clazz)) {
val other = member.superSymbol(clazz);
@@ -394,31 +419,20 @@ abstract class RefChecks extends InfoTransform {
setType NoType;
if (sym.isStatic) List(transform(cdef))
else {
- val moduleType = sym.tpe;
-
- // var m$: T = null; or, if class member: local var m$: T = _;
- val mvar = currentOwner.newVariable(sym.pos, name.toString() + "$") setInfo moduleType;
- if (currentOwner.isClass) {
- mvar setFlag (PRIVATE | LOCAL | SYNTHETIC);
- sym.owner.info.decls.enter(mvar);
- }
- val vdef = localTyper.typed(
- ValDef(mvar, if (sym.isLocal) Literal(Constant(null)) else EmptyTree));
+ val vdef =
+ localTyper.typed {
+ atPos(tree.pos) {
+ newModuleVarDef(sym)
+ }
+ }
- // def m: T = { if (m$ == null) m$ = new m$class; m$ }
val ddef =
atPhase(phase.next) {
localTyper.typed {
- DefDef(sym, vparamss =>
- Block(
- List(
- If(
- Apply(Select(Ident(mvar), nme.EQ), List(Literal(Constant(null)))),
- Assign(Ident(mvar), New(TypeTree(moduleType), List(List()))),
- EmptyTree)),
- Ident(mvar)))
- }
- }
+ newModuleAccessDef(sym, vdef.symbol)
+ }
+ }
+
transformTrees(List(cdef, vdef, ddef))
}
@@ -466,7 +480,7 @@ abstract class RefChecks extends InfoTransform {
validateVariance(sym, sym.tpe, CoVariance);
case ValDef(_, _, _, _) =>
- validateVariance(sym, sym.tpe, if ((sym.flags & MUTABLE) != 0) NoVariance else CoVariance);
+ validateVariance(sym, sym.tpe, if (sym.isVariable) NoVariance else CoVariance);
case AbsTypeDef(_, _, _, _) =>
validateVariance(sym, sym.info, CoVariance);
@@ -504,19 +518,28 @@ abstract class RefChecks extends InfoTransform {
case Select(qual, name) =>
if (sym.isSourceMethod && sym.hasFlag(CASE))
result = toConstructor
- else if (sym hasFlag DEFERRED) {
- qual match {
- case Super(qualifier, mixin) =>
- val base = currentOwner.enclClass;
+ else qual match {
+ case Super(qualifier, mixin) =>
+ val base = currentOwner.enclClass;
+ if (sym hasFlag DEFERRED) {
val member = sym.overridingSymbol(base);
if (mixin != nme.EMPTY.toTypeName || member == NoSymbol ||
!((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(base)))
unit.error(tree.pos, "symbol accessed from super may not be abstract");
- case _ =>
- }
- } else if (sym.alias != NoSymbol) {
- qual match {
- case This(_) =>
+ }
+ //System.out.println("super: " + tree + " in " + base);//DEBUG
+ if (base.isTrait && mixin == nme.EMPTY.toTypeName) {
+ val superAccName = nme.superName(sym.name);
+ val superAcc = base.info.decl(superAccName) suchThat (.alias.==(sym));
+ assert(superAcc != NoSymbol, "" + sym + " " + base + " " + superAccName);//debug
+ val tree1 = Select(This(base), superAcc);
+ if (settings.debug.value) log("super-replacement: " + tree + "=>" + tree1);
+ result = atPos(tree.pos) {
+ Select(gen.This(base), superAcc) setType superAcc.tpe
+ }
+ }
+ case This(_) =>
+ if ((sym hasFlag PARAMACCESSOR) && (sym.alias != NoSymbol)) {
result = typed {
Select(
Super(qual.symbol, qual.symbol.info.parents.head.symbol.name) setPos qual.pos,
@@ -524,8 +547,8 @@ abstract class RefChecks extends InfoTransform {
}
if (settings.debug.value)
System.out.println("alias replacement: " + tree + " ==> " + result);//debug
- case _ =>
- }
+ }
+ case _ =>
}
case _ =>
}
diff --git a/sources/scala/tools/nsc/typechecker/TreeCheckers.scala b/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
index d109a46ec8..95a3af20bf 100644
--- a/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -62,7 +62,9 @@ abstract class TreeCheckers extends Analyzer {
try {
tree match {
case DefDef(_, _, _, _, _, _) =>
- if (tree.symbol.hasFlag(ACCESSOR) && !tree.symbol.hasFlag(DEFERRED)) {
+ if (tree.symbol.hasFlag(ACCESSOR) &&
+ !tree.symbol.hasFlag(DEFERRED) &&
+ !tree.symbol.tpe.resultType.isInstanceOf[ConstantType]) {
assert(tree.symbol.accessed != NoSymbol);
assert(tree.symbol.accessed.getter(tree.symbol.owner) == tree.symbol ||
tree.symbol.accessed.setter(tree.symbol.owner) == tree.symbol);
@@ -73,6 +75,16 @@ abstract class TreeCheckers extends Analyzer {
}
case Apply(_, args) =>
assert(args forall (EmptyTree !=))
+ case Select(_, _) =>
+ assert(tree.symbol != NoSymbol, tree);
+ case This(_) =>
+ if (!(tree.symbol.isStatic && (tree.symbol hasFlag MODULE))) {
+ var o = currentOwner;
+ while (o != tree.symbol) {
+ o = o.owner;
+ assert(o != NoSymbol, tree)
+ }
+ }
case _ =>
}
if (tree.pos == Position.NOPOS && tree != EmptyTree) {
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 2c22fe5f53..1b108537b7 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -223,17 +223,20 @@ abstract class Typers: Analyzer {
} else tree
}
- class AddSuperAccessors(clazz: Symbol) extends Traverser {
+ class AddSuperAccessors(clazz: Symbol, accdefs: ListBuffer[Tree]) extends Traverser {
override def traverse(tree: Tree) = tree match {
case Select(Super(_, mix), _) =>
if (tree.isTerm && mix == nme.EMPTY.toTypeName) {
- if (tree.symbol.superAccessor(clazz) == NoSymbol) {
- System.out.println("add super acc " + tree.symbol + tree.symbol.locationString + " to " + clazz);//debug
- clazz.info.decls enter
- clazz.newMethod(tree.pos, nme.superName(tree.symbol.name))
+ val supername = nme.superName(tree.symbol.name);
+ if (clazz.info.decl(supername).suchThat(.alias.==(tree.symbol)) == NoSymbol) {
+ if (settings.debug.value) log("add super acc " + tree.symbol + tree.symbol.locationString + " to " + clazz);//debug
+ val superAcc =
+ clazz.newMethod(tree.pos, supername)
.setFlag(SUPERACCESSOR | PRIVATE)
.setAlias(tree.symbol)
- .setInfo(clazz.thisType.memberType(tree.symbol))
+ .setInfo(clazz.thisType.memberType(tree.symbol));
+ clazz.info.decls enter superAcc;
+ accdefs += typed(DefDef(superAcc, vparamss => EmptyTree));
}
}
case Template(_, _) =>
@@ -383,32 +386,34 @@ abstract class Typers: Analyzer {
tree.tpe
}
- def parentTypes(templ: Template): List[Tree] = {
- var supertpt = typedTypeConstructor(templ.parents.head);
- var mixins = templ.parents.tail map typedType;
- // If first parent is trait, make it first mixin and add its superclass as first parent
- while (supertpt.tpe.symbol != null && supertpt.tpe.symbol.initialize.isTrait) {
- mixins = typedType(supertpt) :: mixins;
- supertpt = TypeTree(supertpt.tpe.parents.head) setPos supertpt.pos;
- }
- if (supertpt.hasSymbol) {
- val tparams = supertpt.symbol.typeParams;
- if (!tparams.isEmpty) {
- val constr @ DefDef(_, _, _, vparamss, _, Apply(_, superargs)) =
- treeInfo.firstConstructor(templ.body);
- val outercontext = context.outer.outer;
- supertpt = TypeTree(
- newTyper(context.outer.outer.makeNewScope(constr, context.outer.outer.owner))
- .completeSuperType(
- supertpt,
- tparams,
- vparamss map (.map(.duplicate.asInstanceOf[ValDef])),
- superargs map (.duplicate))) setPos supertpt.pos;
- }
+ def parentTypes(templ: Template): List[Tree] =
+ if (templ.parents.isEmpty) List()
+ else {
+ var supertpt = typedTypeConstructor(templ.parents.head);
+ var mixins = templ.parents.tail map typedType;
+ // If first parent is trait, make it first mixin and add its superclass as first parent
+ while (supertpt.tpe.symbol != null && supertpt.tpe.symbol.initialize.isTrait) {
+ mixins = typedType(supertpt) :: mixins;
+ supertpt = TypeTree(supertpt.tpe.parents.head) setPos supertpt.pos;
+ }
+ if (supertpt.hasSymbol) {
+ val tparams = supertpt.symbol.typeParams;
+ if (!tparams.isEmpty) {
+ val constr @ DefDef(_, _, _, vparamss, _, Apply(_, superargs)) =
+ treeInfo.firstConstructor(templ.body);
+ val outercontext = context.outer.outer;
+ supertpt = TypeTree(
+ newTyper(context.outer.outer.makeNewScope(constr, context.outer.outer.owner))
+ .completeSuperType(
+ supertpt,
+ tparams,
+ vparamss map (.map(.duplicate.asInstanceOf[ValDef])),
+ superargs map (.duplicate))) setPos supertpt.pos;
+ }
+ }
+ //System.out.println("parents(" + context.owner + ") = " + supertpt :: mixins);//DEBUG
+ List.mapConserve(supertpt :: mixins)(tpt => checkNoEscaping.privates(context.owner, tpt))
}
- //System.out.println("parents(" + context.owner + ") = " + supertpt :: mixins);//DEBUG
- List.mapConserve(supertpt :: mixins)(tpt => checkNoEscaping.privates(context.owner, tpt))
- }
/** Check that
* - all parents are class types,
@@ -498,7 +503,7 @@ abstract class Typers: Analyzer {
atPos(vdef.pos)(
DefDef(setter, vparamss =>
if ((mods & DEFERRED) != 0) EmptyTree
- else typed(Assign(Select(This(value.owner), getterDef.symbol),
+ else typed(Assign(Select(This(value.owner), value),
Ident(vparamss.head.head)))))
}
val gs = if ((mods & MUTABLE) != 0) List(getterDef, setterDef)
@@ -524,9 +529,12 @@ abstract class Typers: Analyzer {
new Namer(context.outer.make(templ, clazz, clazz.info.decls)).enterSyms(templ.body);
validateParentClasses(parents1, selfType);
val body1 = templ.body flatMap addGetterSetter;
- val body2 = typedStats(body1, templ.symbol);
- if (clazz.isTrait && phase.id <= typerPhase.id)
- new AddSuperAccessors(clazz).traverseTrees(body2);
+ var body2 = typedStats(body1, templ.symbol);
+ if (clazz.isTrait && phase.id <= typerPhase.id) {
+ val superAccs = new ListBuffer[Tree];
+ new AddSuperAccessors(clazz, superAccs).traverseTrees(body2);
+ body2 = superAccs.toList ::: body2;
+ }
copy.Template(templ, parents1, body2) setType clazz.tpe
}
@@ -535,7 +543,7 @@ abstract class Typers: Analyzer {
var tpt1 = checkNoEscaping.privates(sym, typedType(vdef.tpt));
val rhs1 =
if (vdef.rhs.isEmpty) {
- if ((sym hasFlag MUTABLE) && sym.owner.isTerm && phase.id <= typerPhase.id)
+ if (sym.isVariable && sym.owner.isTerm && phase.id <= typerPhase.id)
error(vdef.pos, "local variables must be initialized");
vdef.rhs
} else {
@@ -575,14 +583,14 @@ abstract class Typers: Analyzer {
if (vparamss.exists(.exists(vp => vp.symbol == superArg.symbol))) {
var alias = superAcc.initialize.alias;
if (alias == NoSymbol)
- alias = if (superAcc.hasGetter) superAcc.getter(superAcc.owner) else superAcc;
+ alias = superAcc.getter(superAcc.owner);
if (alias != NoSymbol &&
superClazz.info.nonPrivateMember(alias.name) != alias)
alias = NoSymbol;
if (alias != NoSymbol) {
var ownAcc = clazz.info.decl(name);
if (ownAcc hasFlag ACCESSOR) ownAcc = ownAcc.accessed;
- System.out.println("" + ownAcc + " has alias " + alias + alias.locationString);//debug
+ if (settings.debug.value) log("" + ownAcc + " has alias " + alias + alias.locationString);//debug
ownAcc.asInstanceOf[TermSymbol].setAlias(alias)
}
}
@@ -720,18 +728,19 @@ abstract class Typers: Analyzer {
val vparams = List.mapConserve(fun.vparams)(typedValDef);
val body = typed(fun.body, respt);
val formals = vparamSyms map (.tpe);
- val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(body.tpe));
+ val restpe = body.tpe.deconst;
+ val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(restpe));
assert(context.owner != RootClass);//debug
val anonClass = context.owner.newAnonymousFunctionClass(fun.pos) setFlag (FINAL | SYNTHETIC);
anonClass setInfo ClassInfoType(
List(ObjectClass.tpe, funtpe, ScalaObjectClass.tpe), new Scope(), anonClass);
val applyMethod = anonClass.newMethod(fun.pos, nme.apply)
- setFlag FINAL setInfo MethodType(formals, body.tpe);
+ setFlag FINAL setInfo MethodType(formals, restpe);
anonClass.info.decls enter applyMethod;
for (val vparam <- vparamSyms) vparam.owner = applyMethod;
new ChangeOwnerTraverser(context.owner, applyMethod).traverse(body);
var members = List(
- DefDef(FINAL, nme.apply, List(), List(vparams), TypeTree(body.tpe), body)
+ DefDef(FINAL, nme.apply, List(), List(vparams), TypeTree(restpe), body)
setSymbol applyMethod);
if (pt.symbol == PartialFunctionClass) {
val isDefinedAtMethod = anonClass.newMethod(fun.pos, nme.isDefinedAt)