diff options
-rwxr-xr-x | bin/build-nsc | 2 | ||||
-rwxr-xr-x | bin/init-nsc | 6 | ||||
-rwxr-xr-x | bin/test-nsc | 20 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/Global.scala | 13 | ||||
-rw-r--r-- | sources/scala/tools/nsc/ast/Trees.scala | 12 | ||||
-rw-r--r-- | sources/scala/tools/nsc/matching/LeftTracers.scala | 2 | ||||
-rw-r--r-- | sources/scala/tools/nsc/matching/RightTracers.scala | 2 | ||||
-rw-r--r-- | sources/scala/tools/nsc/matching/WordAutoms.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Definitions.scala | 54 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Symbols.scala | 10 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Types.scala | 144 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/classfile/UnPickler.scala | 7 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/UnCurry.scala | 5 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Namers.scala | 7 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/RefChecks.scala | 6 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Typers.scala | 17 |
16 files changed, 223 insertions, 86 deletions
diff --git a/bin/build-nsc b/bin/build-nsc new file mode 100755 index 0000000000..6855e25af4 --- /dev/null +++ b/bin/build-nsc @@ -0,0 +1,2 @@ +scalac -d /tmp/classes tools/nsc/*.scala tools/nsc/ast/*.scala tools/nsc/ast/parser/*.scala tools/nsc/symtab/*.scala tools/nsc/symtab/classfile/*.scala tools/nsc/util/*.scala tools/nsc/typechecker/*.scala tools/nsc/transform/*.scala tools/nsc/matching/*.scala $* + diff --git a/bin/init-nsc b/bin/init-nsc new file mode 100755 index 0000000000..8e2eada8bd --- /dev/null +++ b/bin/init-nsc @@ -0,0 +1,6 @@ +cd $HOME/scala/sources/scala +rm -r /tmp/newclasses/* +pico -scala-hack -source 1.4 -d /tmp/newclasses *.java runtime/*.java runtime/*/*.java tools/util/*.java +rm /tmp/newclasses/scala/ScalaObject.class +rm /tmp/newclasses/scala/Array.class + diff --git a/bin/test-nsc b/bin/test-nsc new file mode 100755 index 0000000000..afc7a722e5 --- /dev/null +++ b/bin/test-nsc @@ -0,0 +1,20 @@ +#! /bin/tcsh +alias scala java -Xms16m -ea -classpath /home/linuxsoft/apps/java-1.4.2_08/jre/lib/rt.jar:$HOME/scala/objects/main/lib/scala:$HOME/scala/objects/main/lib/tools:/tmp/classes +alias scala-debug scala -Djava.compiler=NONE +alias nsc "scala scala.tools.nsc.Main -classpath "/tmp/newclasses:$HOME/scala/sources:$HOME/scala/newsources" -d /tmp/newclasses" +nsc -verbose -prompt -nopredefs Predef.scala runtime/ScalaRunTime.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt *.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt collection/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt collection/mutable/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt collection/immutable/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt concurrent/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt io/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt mobile/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt runtime/*.scala runtime/*/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt text/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt testing/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt util/*/*.scala -skip:tailcalls -skip:transmatch -check:term +nsc -verbose -prompt xml*.scala xml/*/*.scala -skip:tailcalls -skip:transmatch -check:term +rm -r /tmp/newclasses/scala/tools/nsc +nsc -verbose -prompt tools/nsc/*.scala -skip:tailcalls -skip:transmatch -check:term + diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala index 2b74fa67dd..f809d77498 100755 --- a/sources/scala/tools/nsc/Global.scala +++ b/sources/scala/tools/nsc/Global.scala @@ -16,7 +16,7 @@ import util._; import ast._; import ast.parser._; import typechecker._; -import matching.TransMatcher; +//import matching.TransMatcher; import transform._; class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable with Trees with CompilationUnits { @@ -124,6 +124,8 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable abstract class StdPhase(prev: Phase) extends Phase(prev) { def run: unit = units foreach applyPhase; def apply(unit: CompilationUnit): unit; + private val isErased = /*prev == erasurePhase ||*/ prev.erasedTypes; + override def erasedTypes: boolean = isErased; def applyPhase(unit: CompilationUnit): unit = { if (settings.debug.value) inform("[running phase " + name + " on " + unit + "]"); apply(unit) @@ -176,20 +178,17 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable } val tailCallPhase = new tailCalls.Phase(uncurryPhase); +/* object transmatcher extends TransMatcher { val global: Global.this.type = Global.this; - } - val transMatchPhase = new transmatcher.Phase(tailCallPhase); - //object typesAsValues extends TypesAsValues { - // val global: Global.this.type = Global.this; - //} +*/ object sampleTransform extends SampleTransform { val global: Global.this.type = Global.this; } - val samplePhase = new sampleTransform.Phase(transMatchPhase); + val samplePhase = new sampleTransform.Phase(tailCallPhase); //val transMatchPhase = new transmatcher.TransMatchPhase(picklePhase); diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala index 7a92280d17..6f1c0452de 100644 --- a/sources/scala/tools/nsc/ast/Trees.scala +++ b/sources/scala/tools/nsc/ast/Trees.scala @@ -59,15 +59,15 @@ abstract class Trees: Global { } abstract class DefTree extends SymTree { - override def isDef = true; + override def isDef = true } abstract class TermTree extends Tree { - override def isTerm = true; + override def isTerm = true } abstract class TypTree extends Tree { - override def isType = true; + override def isType = true } // ----- auxiliary objects and methods ------------------------------ @@ -920,8 +920,7 @@ abstract class Trees: Global { List.mapConserve(trees)(tree => transform(tree).asInstanceOf[Ident]); def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = List.mapConserve(stats)(stat => - if (exprOwner != currentOwner && (!stat.isDef || stat.isInstanceOf[LabelDef])) - atOwner(exprOwner)(transform(stat)) + if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(transform(stat)) else transform(stat)); def atOwner[A](owner: Symbol)(trans: => A): A = { @@ -1030,8 +1029,7 @@ abstract class Trees: Global { treess foreach traverseTrees; def traverseStats(stats: List[Tree], exprOwner: Symbol): unit = stats foreach (stat => - if (exprOwner != currentOwner && (!stat.isDef || stat.isInstanceOf[LabelDef])) - atOwner(exprOwner)(traverse(stat)) + if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(traverse(stat)) else traverse(stat)); def atOwner(owner: Symbol)(traverse: => unit): unit = { diff --git a/sources/scala/tools/nsc/matching/LeftTracers.scala b/sources/scala/tools/nsc/matching/LeftTracers.scala index 6d1639952a..fe38779951 100644 --- a/sources/scala/tools/nsc/matching/LeftTracers.scala +++ b/sources/scala/tools/nsc/matching/LeftTracers.scala @@ -50,7 +50,7 @@ abstract class LeftTracerInScala extends Autom2Scala { // accumType)); this.funSym.setInfo( - new MethodType( + MethodType( scala.List ( // dummy symbol MethodType definitions.IntClass.info, accumType diff --git a/sources/scala/tools/nsc/matching/RightTracers.scala b/sources/scala/tools/nsc/matching/RightTracers.scala index bb391ad34d..8dc3d638a9 100644 --- a/sources/scala/tools/nsc/matching/RightTracers.scala +++ b/sources/scala/tools/nsc/matching/RightTracers.scala @@ -185,7 +185,7 @@ abstract class RightTracerInScala extends Autom2Scala { .setInfo( definitions.IntClass.info ) ; funSym.setInfo( - new MethodType( scala.List ( // dummy symbol MethodType + MethodType( scala.List ( // dummy symbol MethodType SeqTraceType(elementType), //funSym.newValueParameter( pos, fresh.newName("iter") /*, SeqTraceType elementType */), definitions.IntClass.info), diff --git a/sources/scala/tools/nsc/matching/WordAutoms.scala b/sources/scala/tools/nsc/matching/WordAutoms.scala index 2a9dc26596..5912ad3900 100644 --- a/sources/scala/tools/nsc/matching/WordAutoms.scala +++ b/sources/scala/tools/nsc/matching/WordAutoms.scala @@ -75,7 +75,7 @@ abstract class WordAutomInScala extends Autom2Scala { this.resultSym = owner.newVariable( pos, fresh.newName("swRes")) .setInfo( definitions.IntClass.info ) ; - this.funSym.setInfo( new MethodType(scala.List (definitions.IntClass.info), + this.funSym.setInfo( MethodType(scala.List (definitions.IntClass.info), definitions.IntClass.info )); this.curSym = owner.newVariable( pos, "cur" /*Names.cur*/ ) diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala index f82a74dba1..1c41acfe1d 100755 --- a/sources/scala/tools/nsc/symtab/Definitions.scala +++ b/sources/scala/tools/nsc/symtab/Definitions.scala @@ -6,6 +6,7 @@ package scala.tools.nsc.symtab; import scala.tools.util.Position; +import collection.mutable.HashMap; import Flags._; abstract class Definitions: SymbolTable { @@ -145,8 +146,10 @@ abstract class Definitions: SymbolTable { // boxed classes var BoxedArrayClass: Symbol = _; - var BoxedObjectArrayClass: Symbol = _; + var BoxedNumberClass: Symbol = _; var BoxedUnitClass: Symbol = _; + var BoxedUnitModule: Symbol = _; + def BoxedUnit_UNIT = getMember(BoxedUnitModule, "UNIT"); def getModule(fullname: Name): Symbol = getModuleOrClass(fullname, true); @@ -220,6 +223,34 @@ abstract class Definitions: SymbolTable { owner.newTypeParameter(Position.NOPOS, "T" + index) .setInfo(TypeBounds(AllClass.typeConstructor, AnyClass.typeConstructor)); + val boxedSym = new HashMap[Symbol, Symbol]; + val boxedArraySym = new HashMap[Symbol, Symbol]; + private val abbrvTag = new HashMap[Symbol, char]; + + private def getValueClass(name: String, tag: char): Symbol = { + val result = getClass("scala." + name); + boxedSym(result) = getClass("scala.runtime.Boxed" + name); + if (name != "Unit") boxedArraySym(result) = getClass("scala.runtime.Boxed" + name + "Array"); + abbrvTag(result) = tag; + result + } + + /** Is symbol a value class? */ + def isValueClass(sym: Symbol): boolean = boxedSym contains sym; + + /** Is symbol a value or array class? */ + def isUnboxedClass(sym: Symbol): boolean = isValueClass(sym) || sym == ArrayClass; + + def signature(tp: Type): String = { + def signature1(tp: Type): String = { + if (tp.symbol == ArrayClass) "[" + signature1(tp.typeArgs.head); + else if (isValueClass(tp.symbol)) String.valueOf(abbrvTag(tp.symbol)) + else "L" + tp.symbol.fullNameString + ";" + } + if (tp.symbol == ArrayClass) signature1(tp); + else tp.symbol.fullNameString + } + def init = { RootClass = NoSymbol.newClass(Position.NOPOS, nme.ROOT.toTypeName) @@ -252,15 +283,15 @@ abstract class Definitions: SymbolTable { ThrowableClass = getClass("java.lang.Throwable"); // the scala value classes - UnitClass = getClass("scala.Unit"); - BooleanClass = getClass("scala.Boolean"); - ByteClass = getClass("scala.Byte"); - ShortClass = getClass("scala.Short"); - CharClass = getClass("scala.Char"); - IntClass = getClass("scala.Int"); - LongClass = getClass("scala.Long"); - FloatClass = getClass("scala.Float"); - DoubleClass = getClass("scala.Double"); + UnitClass = getValueClass("Unit", 'V'); + BooleanClass = getValueClass("Boolean", 'Z'); + ByteClass = getValueClass("Byte", 'B'); + ShortClass = getValueClass("Short", 'S'); + CharClass = getValueClass("Char", 'C'); + IntClass = getValueClass("Int", 'I'); + LongClass = getValueClass("Long", 'L'); + FloatClass = getValueClass("Float", 'F'); + DoubleClass = getValueClass("Double", 'D'); // the scala reference classes ScalaObjectClass = getClass("scala.ScalaObject"); @@ -319,8 +350,9 @@ abstract class Definitions: SymbolTable { PatternWildcard = NoSymbol.newValue(Position.NOPOS, "_").setInfo(AllClass.typeConstructor); BoxedArrayClass = getClass("scala.runtime.BoxedArray"); - BoxedObjectArrayClass = getClass("scala.runtime.BoxedObjectArray"); + BoxedNumberClass = getClass("scala.runtime.BoxedNumber"); BoxedUnitClass = getClass("scala.runtime.BoxedUnit"); + BoxedUnitModule = getModule("scala.runtime.BoxedUnit"); } } } diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index d8a8182c07..92593447ff 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -97,7 +97,8 @@ abstract class Symbols: SymbolTable { final def isSetter = isTerm && hasFlag(ACCESSOR) && name.endsWith(nme._EQ); final def isValueParameter = isTerm && hasFlag(PARAM); final def isLocalDummy = isTerm && (name startsWith nme.LOCAL_PREFIX); - final def isMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD; + final def isMethod = isTerm && hasFlag(METHOD); + final def isSourceMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD; final def isLabel = isTerm && hasFlag(LABEL); final def isConstructor = isTerm && name == nme.CONSTRUCTOR; final def isModule = isTerm && hasFlag(MODULE); @@ -139,7 +140,7 @@ abstract class Symbols: SymbolTable { /** Is this symbol a sealed class?*/ final def isSealed: boolean = - isClass && (hasFlag(SEALED) || isSubClass(AnyValClass) || isSubClass(ArrayClass)); + isClass && (hasFlag(SEALED) || isUnboxedClass(this)); /** Is this symbol locally defined? I.e. not accessed from outside `this' instance */ final def isLocal: boolean = owner.isTerm; @@ -360,6 +361,7 @@ abstract class Symbols: SymbolTable { def filter(cond: Symbol => boolean): Symbol = if (hasFlag(OVERLOADED)) { + //assert(info.isInstanceOf[OverloadedType], "" + this + ":" + info);//DEBUG val alts = alternatives; val alts1 = alts filter cond; if (alts1 eq alts) this @@ -395,7 +397,7 @@ abstract class Symbols: SymbolTable { def enclClass: Symbol = if (isClass) this else owner.enclClass; /** The next enclosing method */ - def enclMethod: Symbol = if (isMethod) this else owner.enclMethod; + def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod; /** The primary constructor of a class */ def primaryConstructor: Symbol = info.decl(nme.CONSTRUCTOR).alternatives.head; @@ -526,7 +528,7 @@ abstract class Symbols: SymbolTable { else if (isPackage) "package" else if (isModule) "object" else if (isConstructor) "constructor" - else if (isMethod) "method" + else if (isSourceMethod) "method" else if (isTerm) "value" else ""; diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala index 0533920f9f..19517329d7 100755 --- a/sources/scala/tools/nsc/symtab/Types.scala +++ b/sources/scala/tools/nsc/symtab/Types.scala @@ -383,8 +383,9 @@ abstract class Types: SymbolTable { /** A base class for types that defer some operations * to their immediate supertype */ - abstract trait SubType extends Type { - protected def supertype: Type; + abstract class SubType extends Type { + assert(!phase.erasedTypes, this); + def supertype: Type; override def parents: List[Type] = supertype.parents; override def decls: Scope = supertype.decls; override def baseType(clazz: Symbol): Type = supertype.baseType(clazz); @@ -396,9 +397,9 @@ abstract class Types: SymbolTable { /** A base class for types that represent a single value * (single-types and this-types) */ - abstract trait SingletonType extends SubType { + abstract class SingletonType extends SubType { override def singleDeref: Type; - protected def supertype: Type = singleDeref; + def supertype: Type = singleDeref; override def isStable: boolean = true; override def widen: Type = singleDeref.widen; override def closure: Array[Type] = addClosure(this, supertype.closure); @@ -442,7 +443,7 @@ abstract class Types: SymbolTable { /** A class for this-types of the form <sym>.this.type */ - case class ThisType(sym: Symbol) extends SingletonType { + abstract case class ThisType(sym: Symbol) extends SingletonType { assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym); override def symbol = sym; override def singleDeref: Type = sym.typeOfThis; @@ -450,7 +451,7 @@ abstract class Types: SymbolTable { if (settings.debug.value) sym.nameString + ".this."; else if (sym.isRoot || sym.isEmptyPackageClass) "" else if (sym.isAnonymousClass || sym.isRefinementClass) "this." - else if (sym.isPackageClass) sym.fullNameString('.') + "." + else if (sym.isPackageClass) sym.fullNameString + "." else sym.nameString + ".this."; override def narrow: Type = this; } @@ -476,7 +477,7 @@ abstract class Types: SymbolTable { else pre.prefixString + sym.nameString + "."; } - case class SuperType(thistpe: Type, supertp: Type) extends SingletonType { + abstract case class SuperType(thistpe: Type, supertp: Type) extends SingletonType { override def symbol = thistpe.symbol; override def singleDeref = supertp; override def prefixString = @@ -488,8 +489,8 @@ abstract class Types: SymbolTable { /** A class for the bounds of abstract types and type parameters */ - case class TypeBounds(lo: Type, hi: Type) extends SubType { - protected def supertype: Type = hi; + abstract case class TypeBounds(lo: Type, hi: Type) extends SubType { + def supertype: Type = hi; override def bounds: TypeBounds = this; def containsType(that: Type) = that <:< this || lo <:< that && that <:< hi; override def toString() = ">: " + lo + " <: " + hi; @@ -511,6 +512,7 @@ abstract class Types: SymbolTable { override def closure: Array[Type] = { def computeClosure: Array[Type] = try { + //System.out.println("computing closure of " + symbol.tpe + " " + parents);//DEBUG addClosure(symbol.tpe, glbArray(parents map (.closure))); } catch { case ex: MalformedClosure => @@ -601,7 +603,7 @@ abstract class Types: SymbolTable { class PackageClassInfoType(decls: Scope, clazz: Symbol) extends ClassInfoType(List(), decls, clazz); /** A class representing a constant type */ - case class ConstantType(value: Constant) extends SingletonType { + abstract case class ConstantType(value: Constant) extends SingletonType { assert(value.tpe.symbol != UnitClass); override def symbol: Symbol = value.tpe.symbol; override def singleDeref: Type = value.tpe; @@ -612,7 +614,7 @@ abstract class Types: SymbolTable { /** A class for named types of the form <prefix>.<sym.name>[args] * Cannot be created directly; one should always use `typeRef' for creation. */ - case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type { + abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type { assert(!sym.isAbstractType || pre.isStable || pre.isError); assert(!pre.isInstanceOf[ClassInfoType], this); @@ -683,11 +685,18 @@ abstract class Types: SymbolTable { pre.prefixString + sym.nameString + (if (args.isEmpty) "" else args.mkString("[", ",", "]")) } + + override def prefixString = + if (settings.debug.value) super.prefixString + else if (sym.isRoot || sym.isEmptyPackageClass || + sym.isAnonymousClass || sym.isRefinementClass) "" + else if (sym.isPackageClass) sym.fullNameString + "." + else super.prefixString; } /** A class representing a method type with parameters. */ - case class MethodType(override val paramTypes: List[Type], + abstract case class MethodType(override val paramTypes: List[Type], override val resultType: Type) extends Type { override def paramSectionCount: int = resultType.paramSectionCount + 1; @@ -791,13 +800,44 @@ abstract class Types: SymbolTable { } else sym } + /** The canonical creator for this-types */ + def ThisType(sym: Symbol): Type = + if (phase.erasedTypes) sym.tpe else unique(new ThisType(sym){}); + /** The canonical creator for single-types */ - def singleType(pre: Type, sym: Symbol): SingleType = { - if (checkMalformedSwitch && !pre.isStable && !pre.isError) + def singleType(pre: Type, sym: Symbol): Type = { + if (phase.erasedTypes) + sym.tpe + else if (checkMalformedSwitch && !pre.isStable && !pre.isError) throw new MalformedType(pre, sym.name.toString()); - new SingleType(pre, rebind(pre, sym)) {} + else + unique(new SingleType(pre, rebind(pre, sym)) {}) } + /** The canonical creator for super-types */ + def SuperType(thistp: Type, supertp: Type): Type = + if (phase.erasedTypes) supertp else unique(new SuperType(thistp, supertp){}); + + /** The canonical creator for type bounds */ + def TypeBounds(lo: Type, hi: Type): TypeBounds = + unique(new TypeBounds(lo, hi) {}); + + /** the canonical creator for a refined type with a given scope */ + def refinedType(parents: List[Type], owner: Symbol, decls: Scope): RefinedType = { + val clazz = owner.newRefinementClass(Position.NOPOS); + val result = new RefinedType(parents, decls) { override def symbol: Symbol = clazz } + clazz.setInfo(result); + result + } + + /** the canonical creator for a refined type with an initially empty scope */ + def refinedType(parents: List[Type], owner: Symbol): RefinedType = + refinedType(parents, owner, new Scope); + + /** the canonical creator for a constant type */ + def ConstantType(value: Constant): ConstantType = + unique(new ConstantType(value) {}); + /** The canonical creator for typerefs */ def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = { val sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym; @@ -813,23 +853,22 @@ abstract class Types: SymbolTable { sym1.resetFlag(LOCKED); result } else { - new TypeRef(pre, sym1, args) {} + rawTypeRef(pre, sym1, args) } } - /** the canonical creator for a refined type with a given scope */ - def refinedType(parents: List[Type], owner: Symbol, decls: Scope): RefinedType = { - val clazz = owner.newRefinementClass(Position.NOPOS); - val result = new RefinedType(parents, decls) { - override def symbol: Symbol = clazz - } - clazz.setInfo(result); - result + /** create a type-ref as found, without checks or rebinds */ + def rawTypeRef(pre: Type, sym: Symbol, args: List[Type]): Type = { + unique(new TypeRef(pre, sym, args) {}) } - /** the canonical creator for a refined type with an initially empty scope */ - def refinedType(parents: List[Type], owner: Symbol): RefinedType = - refinedType(parents, owner, new Scope); + /** The canonical creator for method types */ + def MethodType(paramTypes: List[Type], resultType: Type): MethodType = + unique(new MethodType(paramTypes, resultType) {}); + + /** The canonical creator for implicit method types */ + def ImplicitMethodType(paramTypes: List[Type], resultType: Type): ImplicitMethodType = + new ImplicitMethodType(paramTypes, resultType); // don't unique this! /** A creator for intersection type where intersections of a single type are * replaced by the type itself. */ @@ -852,6 +891,53 @@ abstract class Types: SymbolTable { case ErrorType => tycon } +// Hash consing -------------------------------------------------------------- + + private var size = 20000; + private var used = 0; + private var table = new Array[Type](size); + + private def findEntry(tp: Type): Type = { + var h = tp.hashCode() % size; + var entry = table(h); + while (entry != null && entry != tp) { + h = (h + 1) % size; + entry = table(h) + } + entry + } + + private def addEntry(tp: Type): unit = { + if (used >= (size >> 2)) growTable; + used = used + 1; + var h = tp.hashCode() % size; + while (table(h) != null) { + h = (h + 1) % size + } + table(h) = tp + } + + private def growTable: unit = { + val oldtable = table; + size = size * 2; + table = new Array[Type](size); + var i = 0; + while (i < oldtable.length) { + val entry = oldtable(i); + if (entry != null) addEntry(entry); + i = i + 1 + } + } + + private def unique[T <: Type](tp: T): T = { + tp +/* + val tp1 = findEntry(tp); + if (tp1 == null) { addEntry(tp); tp } + else { System.out.println("sharing " + tp1.getClass()); tp1.asInstanceOf[T] } +*/ + } + // Helper Classes --------------------------------------------------------- /** A class expressing upper and lower bounds constraints @@ -917,7 +1003,7 @@ abstract class Types: SymbolTable { val paramtypes1 = List.mapConserve(paramtypes)(this); val result1 = this(result); if ((paramtypes1 eq paramtypes) && (result1 eq result)) tp - else if (tp.isInstanceOf[ImplicitMethodType]) new ImplicitMethodType(paramtypes1, result1) + else if (tp.isInstanceOf[ImplicitMethodType]) ImplicitMethodType(paramtypes1, result1) else MethodType(paramtypes1, result1) case PolyType(tparams, result) => val tparams1 = mapOver(tparams); @@ -1282,7 +1368,7 @@ abstract class Types: SymbolTable { tp.symbol == AllClass || tp.symbol == AllRefClass && (sym.owner isSubClass AnyRefClass) || (tp.nonPrivateMember(sym.name).alternatives exists - (alt => sym == alt || specializesSym(tp.narrow, alt, ThisType(sym.owner), sym))); + (alt => sym == alt || specializesSym(tp.narrow, alt, sym.owner.thisType, sym))); /** Does member `sym1' of `tp1' have a stronger type than member `sym2' of `tp2'? */ private def specializesSym(tp1: Type, sym1: Symbol, tp2: Type, sym2: Symbol): boolean = { diff --git a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala index c6de552619..8fd7f63cb9 100755 --- a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -143,10 +143,9 @@ abstract class UnPickler { case CONSTANTtpe => ConstantType(readConstantRef()) case TYPEREFtpe => - // create a type-ref as found, without checks or rebinds - new TypeRef(readTypeRef(), readSymbolRef(), until(end, readTypeRef)) {} + rawTypeRef(readTypeRef(), readSymbolRef(), until(end, readTypeRef)) case TYPEBOUNDStpe => - new TypeBounds(readTypeRef(), readTypeRef()) + TypeBounds(readTypeRef(), readTypeRef()) case REFINEDtpe => val clazz = readSymbolRef(); new RefinedType(until(end, readTypeRef), symScope(clazz)) { override def symbol = clazz } @@ -158,7 +157,7 @@ abstract class UnPickler { MethodType(until(end, readTypeRef), restpe) case IMPLICITMETHODtpe => val restpe = readTypeRef(); - new ImplicitMethodType(until(end, readTypeRef), restpe) + ImplicitMethodType(until(end, readTypeRef), restpe) case POLYtpe => val restpe = readTypeRef(); PolyType(until(end, readSymbolRef), restpe) diff --git a/sources/scala/tools/nsc/transform/UnCurry.scala b/sources/scala/tools/nsc/transform/UnCurry.scala index 8392454607..cabe259e6a 100755 --- a/sources/scala/tools/nsc/transform/UnCurry.scala +++ b/sources/scala/tools/nsc/transform/UnCurry.scala @@ -47,7 +47,7 @@ abstract class UnCurry extends InfoTransform { case TypeRef(pre, sym, List(arg)) if (sym == ByNameParamClass) => apply(functionType(List(), arg)) case TypeRef(pre, sym, args) if (sym == RepeatedParamClass) => - apply(TypeRef(pre, SeqClass, args)); + apply(rawTypeRef(pre, SeqClass, args)); case _ => mapOver(tp) } @@ -130,8 +130,7 @@ abstract class UnCurry extends InfoTransform { def postTransform(tree: Tree): Tree = atPhase(phase.next) { def applyUnary(tree: Tree): Tree = - if ((tree.symbol.tpe.isInstanceOf[MethodType] || tree.symbol.tpe.isInstanceOf[PolyType]) && - (!tree.tpe.isInstanceOf[PolyType] || tree.tpe.typeParams.isEmpty)) { + if (tree.symbol.isMethod && (!tree.tpe.isInstanceOf[PolyType] || tree.tpe.typeParams.isEmpty)) { if (!tree.tpe.isInstanceOf[MethodType]) tree.tpe = MethodType(List(), tree.tpe); atPos(tree.pos)(Apply(tree, List()) setType tree.tpe.resultType) } else tree; diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala index 87aa573efa..439340c062 100755 --- a/sources/scala/tools/nsc/typechecker/Namers.scala +++ b/sources/scala/tools/nsc/typechecker/Namers.scala @@ -56,9 +56,9 @@ trait Namers: Analyzer { } def enterInScope(sym: Symbol): Symbol = { - if (!(sym.isMethod && sym.owner.isClass)) { + if (!(sym.isSourceMethod && sym.owner.isClass)) { val prev = context.scope.lookupEntry(sym.name); - if (prev != null && prev.owner == context.scope && !prev.sym.isMethod) + if (prev != null && prev.owner == context.scope && !prev.sym.isSourceMethod) doubleDefError(sym.pos, prev.sym); } context.scope enter sym; @@ -294,8 +294,7 @@ trait Namers: Analyzer { } else typer.typedType(tpt).tpe; def mkMethodType(vparams: List[Symbol], restpe: Type) = { val formals = vparams map (.tpe); - if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) - new ImplicitMethodType(formals, restpe) + if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) ImplicitMethodType(formals, restpe) else MethodType(formals, restpe); } makePolyType( diff --git a/sources/scala/tools/nsc/typechecker/RefChecks.scala b/sources/scala/tools/nsc/typechecker/RefChecks.scala index 7260ed625d..7ad0d2e182 100755 --- a/sources/scala/tools/nsc/typechecker/RefChecks.scala +++ b/sources/scala/tools/nsc/typechecker/RefChecks.scala @@ -572,13 +572,13 @@ abstract class RefChecks extends Transform { case TypeApply(fn, args) => checkBounds(fn.tpe.typeParams, args map (.tpe)); - if (sym.isMethod && sym.hasFlag(CASE)) result = toConstructor; + if (sym.isSourceMethod && sym.hasFlag(CASE)) result = toConstructor; case New(tpt) => enterReference(tree.pos, tpt.tpe.symbol); case Ident(name) => - if (sym.isMethod && sym.hasFlag(CASE)) + if (sym.isSourceMethod && sym.hasFlag(CASE)) result = toConstructor else if (name != nme.WILDCARD && name != nme.WILDCARD_STAR.toTypeName) { sym setFlag ACCESSED; @@ -587,7 +587,7 @@ abstract class RefChecks extends Transform { } case Select(qual, name) => - if (sym.isMethod && sym.hasFlag(CASE)) + if (sym.isSourceMethod && sym.hasFlag(CASE)) result = toConstructor else { sym setFlag ACCESSED; diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index 9875fdac28..7c2ede9dcb 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -199,7 +199,7 @@ abstract class Typers: Analyzer { errorTree(tree, sym.toString() + " is not a value"); else if (sym.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass && (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || - sym.isModule && !sym.tpe.isInstanceOf[MethodType])) { + sym.isModule && !sym.isMethod)) { tree.setType(singleType(pre, sym)) } else tree } @@ -458,11 +458,7 @@ abstract class Typers: Analyzer { val vdef = copy.ValDef(stat, mods | PRIVATE | LOCAL, nme.LOCAL_NAME(name), tpe, rhs); val getter: DefDef = { val sym = vdef.symbol; - val decls = sym.owner.info.decls; - var getterEntry = decls.lookupEntry(name); - while (!(getterEntry.sym hasFlag ACCESSOR)) - getterEntry = decls.lookupNextEntry(getterEntry); - val getter = getterEntry.sym; + val getter = sym.owner.info.decl(name).suchThat(.hasFlag(ACCESSOR)); val result = atPos(vdef.pos)( DefDef(getter, vparamss => if ((mods & DEFERRED) != 0) EmptyTree else typed(gen.mkRef(sym), EXPRmode, sym.tpe))); @@ -471,7 +467,7 @@ abstract class Typers: Analyzer { } def setter: DefDef = { val sym = vdef.symbol; - val setter = sym.owner.info.decls.lookup(nme.SETTER_NAME(name)).suchThat(.hasFlag(ACCESSOR)); + val setter = sym.owner.info.decl(nme.SETTER_NAME(name)).suchThat(.hasFlag(ACCESSOR)); atPos(vdef.pos)( DefDef(setter, vparamss => if ((mods & DEFERRED) != 0) EmptyTree @@ -704,7 +700,7 @@ abstract class Typers: Analyzer { } } - private def typed1(tree: Tree, mode: int, pt: Type): Tree = { + protected def typed1(tree: Tree, mode: int, pt: Type): Tree = { def funmode = mode & stickyModes | FUNmode | POLYmode; @@ -1113,8 +1109,7 @@ abstract class Typers: Analyzer { typedTypeApply(typed(fun, funmode | TAPPmode, WildcardType), args1) case Apply(fun, args) => - val stableApplication = - fun.symbol != null && fun.symbol.tpe.isInstanceOf[MethodType] && fun.symbol.isStable; + val stableApplication = fun.symbol != null && fun.symbol.isMethod && fun.symbol.isStable; if (stableApplication && (mode & PATTERNmode) != 0) { // treat stable function applications f() as expressions. typed1(tree, mode & ~PATTERNmode | EXPRmode, pt) @@ -1226,7 +1221,7 @@ abstract class Typers: Analyzer { try { if (settings.debug.value) { assert(pt != null, tree);//debug - //System.out.println("typing " + tree);//debug + //System.out.println("typing " + tree);//DEBUG } val tree1 = if (tree.tpe != null) tree else typed1(tree, mode, pt); //System.out.println("typed " + tree1 + ":" + tree1.tpe);//DEBUG |