diff options
author | Martin Odersky <odersky@gmail.com> | 2013-03-15 18:48:20 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-03-15 18:48:20 +0100 |
commit | 1d029f5f8f90a909ed140f7ef5cf656fafd9fc27 (patch) | |
tree | d7ed9423ebbd7b700f49c41f59da80963d68a6cf | |
parent | 0d2fd0fd49fb1b6d4ab344ae32da493b36c99ba7 (diff) | |
download | dotty-1d029f5f8f90a909ed140f7ef5cf656fafd9fc27.tar.gz dotty-1d029f5f8f90a909ed140f7ef5cf656fafd9fc27.tar.bz2 dotty-1d029f5f8f90a909ed140f7ef5cf656fafd9fc27.zip |
Various fixes to make classfile loading work.
Can now read and display info of verious classfiles as listed in the showClass test. Great end of the week!
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 67 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Printers.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 18 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymbolLoaders.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 49 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 70 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/Reporter.scala | 17 | ||||
-rw-r--r-- | src/test/showClass.scala | 46 |
12 files changed, 195 insertions, 95 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index d2b41b9a3..6874cd74c 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -80,8 +80,8 @@ object Contexts { protected def typeComparer_=(typeComparer: TypeComparer) = _typeComparer = typeComparer def typeComparer: TypeComparer = { - if ((_typeComparer eq outer.typeComparer) && - (constraints ne outer.constraints)) + if ((_typeComparer == null) || + (_typeComparer eq outer.typeComparer) && (constraints ne outer.constraints)) _typeComparer = new TypeComparer() _typeComparer } @@ -234,6 +234,7 @@ object Contexts { } object NoContext extends Context { + override def typeComparer = null lazy val base = unsupported("base") } @@ -348,6 +349,8 @@ object Contexts { /** implicit conversion that injects all ContextBase members into a context */ implicit def toBase(ctx: Context): ContextBase = ctx.base + + val theBase = new ContextBase // !!! DEBUG, so that we can use a minimal context for reporting even in code that normallly cannot access a context } diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 4ddf2e49a..ded45548d 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -40,7 +40,7 @@ class Definitions(implicit ctx: Context) { denot.info = ClassInfo(ScalaPackageClass.thisType, cls, parentRefs, paramDecls) } } - ctx.newClassSymbol(ScalaPackageClass, name, flags, completer) + ctx.newClassSymbol(ScalaPackageClass, name, flags, completer).entered } private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[ClassSymbol] = { diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index 20be08d46..116eacab2 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -66,6 +66,12 @@ object Flags { /** Is this flag set a subset of that one? */ def <= (that: FlagSet) = (bits & that.bits) == bits + /** Does this flag set apply to terms? */ + def isTermFlags = (bits & TERMS) != 0 + + /** Does this flag set apply to terms? */ + def isTypeFlags = (bits & TYPES) != 0 + /** This flag set with all flags transposed to be type flags */ def toTypeFlags = if (bits == 0) this else FlagSet(bits & ~KINDFLAGS | TYPES) @@ -211,14 +217,14 @@ object Flags { /** A value or variable accessor (getter or setter) */ final val Accessor = termFlag(11, "<accessor>") - /** A covariant type variable */ - final val Covariant = typeFlag(11, "<covariant>") + /** Labeled with `sealed` modifier (sealed class) */ + final val Sealed = typeFlag(11, "sealed") /** A mutable var */ final val Mutable = termFlag(12, "mutable") - /** A contravariant type variable */ - final val Contravariant = typeFlag(12, "<contravariant>") + /** Class symbol is defined in this/superclass constructor. */ + final val InConstructor = typeFlag(12, "<inconstructor>") /** Symbol is local to current class (i.e. private[this] or protected[this] * pre: Private or Protected are also set @@ -259,64 +265,65 @@ object Flags { /** Symbol's name is expanded */ final val ExpandedName = commonFlag(19, "<expandedname>") - /** Method is a label. */ - final val Label = termFlag(20, "<label>") + /** A covariant type variable */ + final val CovariantCommon = commonFlag(20, "<covariant>") + final val Covariant = CovariantCommon.toTypeFlags - /** Labeled with `sealed` modifier (sealed class) */ - final val Sealed = typeFlag(20, "sealed") + final val ContravariantCommon = commonFlag(21, "<contravariant>") + final val Contravariant = ContravariantCommon.toTypeFlags + + /** Method is a label. */ + final val Label = termFlag(22, "<label>") /** Labeled with of abstract & override */ - final val AbsOverride = termFlag(21, "abstract override") + final val AbsOverride = termFlag(23, "abstract override") /** Method is assumed to be stable */ - final val Stable = termFlag(22, "<stable>") + final val Stable = termFlag(24, "<stable>") /** A case parameter (or its accessor, or a GADT skolem) */ - final val CaseAccessor = termFlag(23, "<caseaccessor>") - - /** Class symbol is defined in this/superclass constructor. */ - final val InConstructor = typeFlag(23, "<inconstructor>") + final val CaseAccessor = termFlag(25, "<caseaccessor>") /** A super accessor */ - final val SuperAccessor = termFlag(24, "<superaccessor>") + final val SuperAccessor = termFlag(26, "<superaccessor>") /** A parameter with a default value */ - final val DefaultParam = termFlag(25, "<defaultparam>") + final val DefaultParam = termFlag(27, "<defaultparam>") /** Symbol is initialized to the default value, e.g. var x: T = _ */ - final val DefaultInit = termFlag(26, "<defaultinit>") + final val DefaultInit = termFlag(28, "<defaultinit>") /** Symbol is a macro */ - final val Macro = commonFlag(27, "<macro>") + final val Macro = commonFlag(29, "<macro>") /** Symbol is defined by a Java class */ - final val JavaDefined = commonFlag(28, "<java>") + final val JavaDefined = commonFlag(30, "<java>") /** Symbol is implemented as a Java static */ - final val Static = commonFlag(29, "<static>") + final val Static = commonFlag(31, "<static>") /** Variable is accessed from nested function. */ - final val Captured = termFlag(30, "<captured>") + final val Captured = termFlag(32, "<captured>") /** Symbol should be ignored when typechecking; will be marked ACC_SYNTHETIC in bytecode */ - final val Artifact = commonFlag(31, "<artifact>") + final val Artifact = commonFlag(33, "<artifact>") /** A bridge method. Set by Erasure */ - final val Bridge = termFlag(32, "<bridge>") + final val Bridge = termFlag(34, "<bridge>") /** Symbol is a Java varargs bridge */ - final val VBridge = termFlag(33, "<vbridge>") + final val VBridge = termFlag(35, "<vbridge>") /** Symbol is a method which should be marked ACC_SYNCHRONIZED */ - final val Synchronized = termFlag(34, "<synchronized>") + final val Synchronized = termFlag(36, "<synchronized>") /** Symbol is a Java-style varargs method */ - final val JavaVarargs = termFlag(35, "<varargs>") + final val JavaVarargs = termFlag(37, "<varargs>") // Flags following this one are not pickled /** Denotation is in train of being loaded and completed, used to catch cyclic dependencies */ - final val CompletionStarted = commonFlag(48, "<locked>") + final val Touched = commonFlag(48, "<touched>") /** Class is not allowed to accept new members because fingerprint of subclass has been taken */ final val Frozen = typeFlag(49, "<frozen>") @@ -361,7 +368,11 @@ object Flags { /** Flags guaranteed to be set upon symbol creation */ final val FromStartFlags = - AccessFlags | Module | Package | Deferred | Param | Scala2ExistentialCommon + AccessFlags | Module | Package | Deferred | Param | Scala2ExistentialCommon | Touched | + CovariantCommon | ContravariantCommon + + assert(FromStartFlags.isTermFlags && FromStartFlags.isTypeFlags) + // TODO: Should check that FromStartFlags do not changed in completion /** A value that's unstable unless complemented with a Stable flag */ final val UnstableValue = Mutable | Method diff --git a/src/dotty/tools/dotc/core/Printers.scala b/src/dotty/tools/dotc/core/Printers.scala index c90e5f39c..2e0d03082 100644 --- a/src/dotty/tools/dotc/core/Printers.scala +++ b/src/dotty/tools/dotc/core/Printers.scala @@ -263,8 +263,8 @@ object Printers { if (lo eq hi) " = " + lo else - (if (lo.typeSymbol == defn.NothingClass) "" else ">: " + lo) + - (if (hi.typeSymbol == defn.AnyClass) "" else "<: " + hi) + (if (lo.typeSymbol == defn.NothingClass) "" else " >: " + lo) + + (if (hi.typeSymbol == defn.AnyClass) "" else " <: " + hi) case ClassInfo(pre, cdenot, cparents, decls, optSelfType) => val preStr = showLocal(pre) val selfStr = diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 578fa325b..bf51b443c 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -87,16 +87,18 @@ object SymDenotations { * Uncompleted denotations set _info to a LazyType. */ final def info: Type = _info match { - case _info: LazyType => completedInfo(_info) + case _info: LazyType => completeFrom(_info); info case _ => _info } - private def completedInfo(completer: LazyType): Type = { - if (_flags is CompletionStarted) throw new CyclicReference(this) - _flags |= CompletionStarted - println("completing "+this.debugString+"/"+owner.id) // !!! DEBUG - completer.complete(this) - info + private def completeFrom(completer: LazyType): Unit = { + if (_flags is Touched) throw new CyclicReference(this) + _flags |= Touched + Context.theBase.initialCtx.traceIndented( // !!! DEBUG + ">>>> completing "+this.debugString+"/"+owner.id, + "<<<< completed: "+this.debugString) { + completer.complete(this) + } } protected[core] final def info_=(tp: Type) = @@ -148,6 +150,8 @@ object SymDenotations { protected[core] final def preCompleteDecls: Scope = _info match { case cinfo: LazyClassInfo => cinfo.decls case cinfo: ClassInfo => cinfo.decls + case cinfo: LazyType => completeFrom(cinfo); preCompleteDecls + case cinfo => throw new AssertionError(s"unexpected class completer for $debugString: ${cinfo.getClass}") } // ------ Names ---------------------------------------------- diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala index 2a8c9cfc5..b71b0c660 100644 --- a/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -225,7 +225,7 @@ trait SymbolLoader extends LazyType { throw ex } finally { def postProcess(denot: SymDenotation) = - if (!denot.isCompleted) denot.markAbsent() + if ((denot is Touched) && !denot.isCompleted) denot.markAbsent() postProcess(root) if (!root.isRoot) postProcess(root.linkedClass.denot) diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 48cd03f60..48bb91a1e 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -24,7 +24,7 @@ trait TypeOps { this: Context => else { val tp1 = tp.derivedNamedType(asSeenFrom(tp.prefix, pre, cls, theMap)) // short-circuit instantiated type parameters - if ((tp1 ne tp) && (sym is (TypeParam, butNot = Deferred))) tp1.dealias + if ((tp1 ne tp) && (sym is (TypeParam, butNot = Deferred))) tp1.dealias else tp1 } case ThisType(thiscls) => @@ -173,7 +173,7 @@ trait TypeOps { this: Context => case Some(info) => info & tp.refinedInfo case none => tp.refinedInfo }) - formals = formals.updated(name, tp1.member(name).symbol) + formals = formals.updated(name, tp1.typeParamNamed(name)) normalizeToRef(tp1) case tp: TypeRef => tp diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 526b1014d..28ecdb805 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -176,16 +176,22 @@ object Types { } /** The type parameters of this type are: - * For a ClassInfo type, the type parameters of its denotation. + * For a ClassInfo type, the type parameters of its class. + * For a typeref referring to a class, the type parameters of the class. * Inherited by type proxies. * Empty list for all other types. */ final def typeParams(implicit ctx: Context): List[TypeSymbol] = this match { case tp: ClassInfo => tp.cls.typeParams + case tp: TypeRef => + val tsym = tp.typeSymbol + if (tsym.isClass) tsym.typeParams + else tp.underlying.typeParams case tp: TypeProxy => tp.underlying.typeParams - case _ => Nil + case _ => + Nil } // ----- Member access ------------------------------------------------- @@ -441,6 +447,13 @@ object Types { case _ => TypeBounds(this, this) } + /** The type parameter with given `name`. This tries first `preCompleteDecls` + * in order not to provoke a cylce by forcing the info. If that yields + * no symbol it tries `member` as an alternative. + */ + def typeParamNamed(name: TypeName)(implicit ctx: Context): Symbol = + typeSymbol.preCompleteDecls.lookup(name) orElse member(name).symbol + /** The disjunctive normal form of this type. * This collects a set of alternatives, each alternative consisting * of a set of typerefs and a set of refinement names. Collected are @@ -508,12 +521,24 @@ object Types { final def appliedTo(args: List[Type])(implicit ctx: Context): Type = { def recur(tp: Type, tparams: List[TypeSymbol], args: List[Type]): Type = args match { case arg :: args1 => + if (tparams.isEmpty) { + println(s"applied type mismatch: $this $args, $typeParams = typeParams") + println(s"precomplete decls = ${typeSymbol.preCompleteDecls.toList.map(_.denot).mkString("\n ")}") + } val tparam = tparams.head val tp1 = RefinedType(tp, tparam.name, arg.toRHS(tparam)) recur(tp1, tparams.tail, args1) case nil => tp } - if (args.isEmpty) this else recur(this, typeParams, args) + if (args.isEmpty) this + else this match { + case tp: PolyType => + tp.instantiate(args) + case tp: TypeRef if tp.symbol.isClass => + recur(tp, tp.typeParams, args) + case tp: TypeProxy => + tp.underlying.appliedTo(args) + } } final def appliedTo(arg: Type)(implicit ctx: Context): Type = appliedTo(arg :: Nil) @@ -1089,19 +1114,25 @@ object Types { } final class CachedMethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type) - extends MethodType(paramNames, paramTypes)(resultTypeExp) + extends MethodType(paramNames, paramTypes)(resultTypeExp) { + override def equals(that: Any) = super.equals(that) && that.isInstanceOf[CachedMethodType] + } final class JavaMethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type) extends MethodType(paramNames, paramTypes)(resultTypeExp) { override def isJava = true + override def equals(that: Any) = super.equals(that) && that.isInstanceOf[JavaMethodType] + override def computeHash = super.computeHash + 1 } final class ImplicitMethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type) - extends MethodType(paramNames, paramTypes)(resultTypeExp) { + extends MethodType(paramNames, paramTypes)(resultTypeExp) { override def isImplicit = true + override def equals(that: Any) = super.equals(that) && that.isInstanceOf[ImplicitMethodType] + override def computeHash = super.computeHash + 2 } - abstract class GenericMethodType { + abstract class MethodTypeCompanion { def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType def apply(paramNames: List[TermName], paramTypes: List[Type], resultType: Type)(implicit ctx: Context): MethodType = apply(paramNames, paramTypes)(_ => resultType) @@ -1112,17 +1143,17 @@ object Types { } } - object MethodType extends GenericMethodType { + object MethodType extends MethodTypeCompanion { def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context) = unique(new CachedMethodType(paramNames, paramTypes)(resultTypeExp)) } - object JavaMethodType extends GenericMethodType { + object JavaMethodType extends MethodTypeCompanion { def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context) = unique(new JavaMethodType(paramNames, paramTypes)(resultTypeExp)) } - object ImplicitMethodType extends GenericMethodType { + object ImplicitMethodType extends MethodTypeCompanion { def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context) = unique(new ImplicitMethodType(paramNames, paramTypes)(resultTypeExp)) } diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index 1b2672c4a..51be5b329 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -178,10 +178,10 @@ class ClassfileParser( case Some(entry) if !isStatic(entry.jflags) => val mt @ MethodType(paramnames, paramtypes) = info denot.info = mt.derivedMethodType(paramnames.tail, paramtypes.tail, mt.resultType) - + case _ => } setPrivateWithin(denot, jflags) - denot.info = parseAttributes(sym, info) + denot.info = depoly(parseAttributes(sym, info)) if ((denot is Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0) denot.info = arrayToRepeated(denot.info) diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index de6dc053e..dc4494e4e 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -46,9 +46,9 @@ object UnPickler { elemtp0 } tp.derivedMethodType( - paramNames, - paramTypes.init :+ defn.JavaRepeatedParamType.appliedTo(elemtp), - tp.resultType) + paramNames, + paramTypes.init :+ defn.JavaRepeatedParamType.appliedTo(elemtp), + tp.resultType) case tp @ PolyType(paramNames) => tp.derivedPolyType(paramNames, tp.paramBounds, arrayToRepeated(tp.resultType)) } @@ -107,15 +107,19 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: /** A map from refinement classes to their associated refinement types */ private val refinementTypes = mutable.HashMap[Symbol, RefinedType]() - protected def errorBadSignature(msg: String) = { + protected def errorBadSignature(msg: String, original: Option[RuntimeException] = None) = { val ex = new BadSignature( s"""error reading Scala signature of $classRoot from $source: |error occured at position $readIndex: $msg""".stripMargin) - /*if (debug)*/ ex.printStackTrace() + /*if (debug)*/ original.getOrElse(ex).printStackTrace() // !!! DEBUG throw ex } - // Laboriously unrolled for performance. + protected def handleRuntimeException(ex: RuntimeException) = ex match { + case ex: BadSignature => throw ex + case _ => errorBadSignature(s"a runtime exception occured: $ex", Some(ex)) + } + def run() = try { var i = 0 @@ -128,8 +132,6 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: } i += 1 } - finishCompletion(classRoot) - finishCompletion(moduleClassRoot) // read children last, fix for #3951 i = 0 while (i < index.length) { @@ -149,22 +151,9 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: i += 1 } } catch { - case ex: BadSignature => - throw ex - case ex: RuntimeException => - ex.printStackTrace() // !!! DEBUG - errorBadSignature(s"a runtime exception occured: $ex $ex.getMessage()") + case ex: RuntimeException => handleRuntimeException(ex) } - def finishCompletion(root: SymDenotation) = { - if (!root.isCompleted) - root.completer match { - case completer: LocalUnpickler => - completer.complete(root) - case _ => - } - } - def source: AbstractFile = { val f = classRoot.symbol.associatedFile if (f != null) f else moduleClassRoot.symbol.associatedFile @@ -331,6 +320,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: nestedObjectSymbol orElse { // // (4) Call the mirror's "missing" hook. adjust(cctx.base.missingHook(owner, name)) orElse { + println(owner.info.decls.toList.map(_.debugString).mkString("\n ")) // !!! DEBUG // } // (5) Create a stub symbol to defer hard failure a little longer. cctx.newStubSymbol(owner, name, source) @@ -362,14 +352,15 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: def completeRoot(denot: ClassDenotation): Symbol = { denot.setFlag(flags) - denot.info = new RootUnpickler(start) + denot.resetFlag(Touched) // allow one more completion + denot.info = new RootUnpickler(start, denot.symbol) denot.symbol } def finishSym(sym: Symbol): Symbol = { if (sym.owner.isClass && !( isUnpickleRoot(sym) || - (sym is (ModuleClass | TypeParam | Scala2Existential)) || + (sym is (ModuleClass | Scala2Existential)) || isRefinementClass(sym))) symScope(sym.owner).openForMutations.enter(sym) sym @@ -384,22 +375,22 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: name1 = name1.expandedName(owner) flags1 |= TypeParamCreationFlags } - cctx.newSymbol(owner, name1, flags1, localUnpickler, coord = start) + cctx.newSymbol(owner, name1, flags1, localMemberUnpickler, coord = start) case CLASSsym => if (isClassRoot) completeRoot(classRoot) else if (isModuleClassRoot) completeRoot(moduleClassRoot) - else cctx.newClassSymbol(owner, name.asTypeName, flags, localUnpickler, coord = start) + else cctx.newClassSymbol(owner, name.asTypeName, flags, new LocalClassUnpickler(_), coord = start) case MODULEsym | VALsym => if (isModuleRoot) { moduleRoot setFlag flags moduleRoot.symbol - } else cctx.newSymbol(owner, name.asTermName, flags, localUnpickler, coord = start) + } else cctx.newSymbol(owner, name.asTermName, flags, localMemberUnpickler, coord = start) case _ => errorBadSignature("bad symbol tag: " + tag) }) } - abstract class LocalUnpickler extends LazyType { + trait LocalUnpickler extends LazyType { def parseToCompletion(denot: SymDenotation) = { val tag = readByte() val end = readNat() + readIndex @@ -421,7 +412,8 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: val optSelfType = if (atEnd) NoType else readTypeRef() setClassInfo(denot, tp, optSelfType) case denot => - denot.info = if (tag == ALIASsym) TypeAlias(tp) else depoly(tp) + val tp1 = depoly(tp) + denot.info = if (tag == ALIASsym) TypeAlias(tp1) else tp1 if (atEnd) { assert(!(denot is SuperAccessor), denot) } else { @@ -433,18 +425,20 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: } } } - def startCoord(denot: SymDenotation): Coord - def complete(denot: SymDenotation): Unit = { + def startCoord(denot: SymDenotation): Coord = denot.symbol.coord + def complete(denot: SymDenotation): Unit = try { atReadPos(startCoord(denot).toIndex, () => parseToCompletion(denot)) + } catch { + case ex: RuntimeException => handleRuntimeException(ex) } } - object localUnpickler extends LocalUnpickler { - def startCoord(denot: SymDenotation): Coord = denot.symbol.coord - } + class LocalClassUnpickler(cls: Symbol) extends LazyClassInfo(symScope(cls)) with LocalUnpickler + + object localMemberUnpickler extends LocalUnpickler - class RootUnpickler(start: Coord) extends LocalUnpickler { - def startCoord(denot: SymDenotation): Coord = start + class RootUnpickler(start: Coord, cls: Symbol) extends LocalClassUnpickler(cls) { + override def startCoord(denot: SymDenotation): Coord = start } /** Convert @@ -524,7 +518,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: if (isLocal(sym)) TypeRef(pre, sym.asType) else TypeRef(pre, sym.name.asTypeName) val args = until(end, readTypeRef) - // println(s"reading app type $tycon $args") // !!! DEBUG + // if (args.nonEmpty) println(s"reading app type $tycon ${tycon.typeSymbol.debugString} $args, owner = ${tycon.typeSymbol.owner.debugString}") // !!! DEBUG tycon.appliedTo(args) case TYPEBOUNDStpe => TypeBounds(readTypeRef(), readTypeRef()) @@ -533,7 +527,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: val decls = symScope(clazz) symScopes(clazz) = EmptyScope // prevent further additions val parents = until(end, readTypeRef) - val parent = parents.reduceLeft(_ & _) + val parent = parents.reduceLeft(AndType(_, _)) if (decls.isEmpty) parent else { def addRefinement(tp: Type, sym: Symbol) = diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 723af8768..dac2b6874 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -36,15 +36,26 @@ trait Reporting { this: Context => value } - def traceIndented[T](leading: => String, trailing: => String)(op: => T): T = + def traceIndented[T](leading: => String, trailing: => String)(op: => T): T = { + var finalized = false + def finalize(note: String) = + if (!finalized) { + base.indent -= 1 + log(s"${base.indentTab * base.indent}$trailing$note") + finalized = true + } try { log(s"${base.indentTab * base.indent}$leading") base.indent += 1 op + } catch { + case ex: Throwable => + finalize(s" (with exception $ex)") + throw ex } finally { - base.indent -= 1 - log(s"${base.indentTab * base.indent}$trailing") + finalize("") } + } } object Reporter { diff --git a/src/test/showClass.scala b/src/test/showClass.scala new file mode 100644 index 000000000..2ddf0599f --- /dev/null +++ b/src/test/showClass.scala @@ -0,0 +1,46 @@ +package test + +import dotty.tools.dotc.core._ +import Contexts._ +import Symbols._, Types._ +import Decorators._ + +object showClass { + + def showClass(path: String)(implicit ctx: Context): Unit = { + println(s"showing $path") + val cls = ctx.requiredClass(path.toTypeName) + println(s"showing $path -> ${cls.denot}") + val info = cls.info + info match { + case ClassInfo(pre, c, cps, decls, optSelfType) => + println(s"prefix = ${pre.show}") + println(s"self = ${c.show}") + println(s"parents = ${cps.map(_.show).mkString(",")}") + println(s"decls = ${decls.show}") + println(s"selftype = $optSelfType") + } + } + + def main(args: Array[String]) = { + val base = Context.theBase + implicit val ctx = base.initialCtx + println(ctx.settings) + base.definitions.init() + + for (arg <- args) showClass(arg) + + showClass("java.lang.Class") + showClass("scala.Boolean") + showClass("scala.Array") + showClass("scala.math.Ordering") + showClass("scala.collection.Traversable") + showClass("scala.collection.LinearSeqLike") + showClass("scala.collection.immutable.List") + showClass("scala.collection.TraversableLike") + showClass("scala.collection.immutable.Seq") + showClass("scala.collection.MapLike") + //showClass("dotty.tools.dotc.core.Types") + println("done") + } +}
\ No newline at end of file |