diff options
Diffstat (limited to 'src')
24 files changed, 310 insertions, 224 deletions
diff --git a/src/build/pack.xml b/src/build/pack.xml index 564d290967..1735b93f3f 100644 --- a/src/build/pack.xml +++ b/src/build/pack.xml @@ -29,10 +29,15 @@ MAIN DISTRIBUTION PACKAGING <tarfileset dir="${dist.dir}" prefix="${dist.name}" excludes="bin/**"/> </tar> <gzip src="${dists.dir}/archives/${dist.name}.tar" destfile="${dists.dir}/archives/${dist.name}.tgz"/> - <exec executable="xz" failifexecutionfails="false"> - <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}.tar"/> - </exec> - <move file="${dists.dir}/archives/${dist.name}.tar.xz" tofile="${dists.dir}/archives/${dist.name}.txz" failonerror="false"/> + <if> + <not><equals arg1="${archives.skipxz}" arg2="true" /></not> + <then> + <exec executable="xz" failifexecutionfails="false"> + <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}.tar"/> + </exec> + <move file="${dists.dir}/archives/${dist.name}.tar.xz" tofile="${dists.dir}/archives/${dist.name}.txz" failonerror="false"/> + </then> + </if> <delete file="${dists.dir}/archives/${dist.name}.tar" /> <checksum fileext=".md5"> <fileset dir="${dists.dir}/archives"> @@ -54,10 +59,15 @@ MAIN DISTRIBUTION PACKAGING <tarfileset dir="${dist.dir}/doc/scala-devel-docs" prefix="${dist.name}-devel-docs"/> </tar> <gzip src="${dists.dir}/archives/${dist.name}-devel-docs.tar" destfile="${dists.dir}/archives/${dist.name}-devel-docs.tgz"/> - <exec executable="xz" failifexecutionfails="false"> - <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}-devel-docs.tar"/> - </exec> - <move file="${dists.dir}/archives/${dist.name}-devel-docs.tar.xz" tofile="${dists.dir}/archives/${dist.name}-devel-docs.txz" failonerror="false"/> + <if> + <not><equals arg1="${archives.skipxz}" arg2="true" /></not> + <then> + <exec executable="xz" failifexecutionfails="false"> + <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}-devel-docs.tar"/> + </exec> + <move file="${dists.dir}/archives/${dist.name}-devel-docs.tar.xz" tofile="${dists.dir}/archives/${dist.name}-devel-docs.txz" failonerror="false"/> + </then> + </if> <delete file="${dists.dir}/archives/${dist.name}-devel-docs.tar" /> <checksum fileext=".md5"> <fileset dir="${dists.dir}/archives"> @@ -84,10 +94,15 @@ MAIN DISTRIBUTION PACKAGING </tarfileset> </tar> <gzip src="${dists.dir}/archives/${dist.name}-sources.tar" destfile="${dists.dir}/archives/${dist.name}-sources.tgz"/> - <exec executable="xz" failifexecutionfails="false"> - <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}-sources.tar"/> - </exec> - <move file="${dists.dir}/archives/${dist.name}-sources.tar.xz" tofile="${dists.dir}/archives/${dist.name}-sources.txz" failonerror="false"/> + <if> + <not><equals arg1="${archives.skipxz}" arg2="true" /></not> + <then> + <exec executable="xz" failifexecutionfails="false"> + <arg line="-k -9e -S .xz ${dists.dir}/archives/${dist.name}-sources.tar"/> + </exec> + <move file="${dists.dir}/archives/${dist.name}-sources.tar.xz" tofile="${dists.dir}/archives/${dist.name}-sources.txz" failonerror="false"/> + </then> + </if> <delete file="${dists.dir}/archives/${dist.name}-sources.tar" /> <checksum fileext=".md5"> <fileset dir="${dists.dir}/archives"> diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala index 59651bcdf9..7f066a2cc3 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala @@ -36,7 +36,8 @@ trait GenSymbols { else if (sym.isEmptyPackageClass) mirrorMirrorSelect(nme.EmptyPackageClass) else if (sym.isModuleClass) - Select(Select(reify(sym.sourceModule), nme.asModule), nme.moduleClass) + if (sym.sourceModule.isLocatable) Select(Select(reify(sym.sourceModule), nme.asModule), nme.moduleClass) + else reifySymDef(sym) else if (sym.isPackage) mirrorMirrorCall(nme.staticPackage, reify(sym.fullName)) else if (sym.isLocatable) { diff --git a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala index a7ac299317..3892c86dd3 100644 --- a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala +++ b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala @@ -174,15 +174,18 @@ trait SymbolTables { if (sym.annotations.isEmpty) EmptyTree else Apply(Select(currtab.symRef(sym), nme.setAnnotations), List(reifier.reify(sym.annotations))) } else { - import scala.reflect.internal.Flags._ - if (sym hasFlag LOCKED) { - // [Eugene] better to have a symbol without a type signature, than to crash with a CyclicReference - EmptyTree - } else { - val rset = reifier.mirrorBuildCall(nme.setTypeSignature, currtab.symRef(sym), reifier.reify(sym.info)) - if (sym.annotations.isEmpty) rset - else reifier.mirrorBuildCall(nme.setAnnotations, rset, reifier.mkList(sym.annotations map reifier.reifyAnnotationInfo)) - } + // SI-6204 don't reify signatures for incomplete symbols, because this might lead to cyclic reference errors + val signature = + if (sym.isInitialized) { + if (sym.isCapturedVariable) capturedVariableType(sym) + else sym.info + } else NoType + val rset = reifier.mirrorBuildCall(nme.setTypeSignature, currtab.symRef(sym), reifier.reify(signature)) + // `Symbol.annotations` doesn't initialize the symbol, so we don't need to do anything special here + // also since we call `sym.info` a few lines above, by now the symbol will be initialized (if possible) + // so the annotations will be filled in and will be waiting to be reified (unless symbol initialization is prohibited as described above) + if (sym.annotations.isEmpty) rset + else reifier.mirrorBuildCall(nme.setAnnotations, rset, reifier.mkList(sym.annotations map reifier.reifyAnnotationInfo)) } } diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index d87a242f1b..5464b6fc3b 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -661,13 +661,15 @@ abstract class Inliners extends SubComponent { * * TODO handle more robustly the case of a trait var changed at the source-level from public to private[this] * (eg by having ICodeReader use unpickler, see SI-5442). - * */ + + DISABLED + def potentiallyPublicized(f: Symbol): Boolean = { (m.sourceFile eq NoSourceFile) && f.name.containsChar('$') } + */ - def checkField(f: Symbol) = check(f, potentiallyPublicized(f) || - (f.isPrivate && !canMakePublic(f))) + def checkField(f: Symbol) = check(f, f.isPrivate && !canMakePublic(f)) def checkSuper(n: Symbol) = check(n, n.isPrivate || !n.isClassConstructor) def checkMethod(n: Symbol) = check(n, n.isPrivate) diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 108c5ced6f..436867257a 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -1,5 +1,5 @@ /* NSC -- new Scala compiler - * Copyrights 2005-2011 LAMP/EPFL + * Copyright 2005-2012 LAMP/EPFL * @author Martin Odersky */ diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 6fba6dcc39..8e928dc9e6 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -497,16 +497,7 @@ abstract class ExplicitOuter extends InfoTransform else atPos(tree.pos)(outerPath(outerValue, currentClass.outerClass, sym)) // (5) case Select(qual, name) => - /** return closest enclosing method, unless shadowed by an enclosing class; - * no use of closures here in the interest of speed. - */ - def closestEnclMethod(from: Symbol): Symbol = - if (from.isSourceMethod) from - else if (from.isClass) NoSymbol - else closestEnclMethod(from.owner) - - if (currentClass != sym.owner || - (closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass)) + if (currentClass != sym.owner) sym.makeNotPrivate(sym.owner) val qsym = qual.tpe.widen.typeSymbol diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 574c2c7049..2831afc48e 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -28,9 +28,6 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { /** the following two members override abstract members in Transform */ val phaseName: String = "extmethods" - /** The following flags may be set by this phase: */ - override def phaseNewFlags: Long = notPRIVATE - def newTransformer(unit: CompilationUnit): Transformer = new Extender(unit) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index a9e6345f91..8dc2cb34d6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -198,6 +198,69 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL import typer.{typed, context, silent, reallyExists} // import typer.infer.containsUnchecked + // Why is it so difficult to say "here's a name and a context, give me any + // matching symbol in scope" ? I am sure this code is wrong, but attempts to + // use the scopes of the contexts in the enclosing context chain discover + // nothing. How to associate a name with a symbol would would be a wonderful + // linkage for which to establish a canonical acquisition mechanism. + def matchingSymbolInScope(pat: Tree): Symbol = { + def declarationOfName(tpe: Type, name: Name): Symbol = tpe match { + case PolyType(tparams, restpe) => tparams find (_.name == name) getOrElse declarationOfName(restpe, name) + case MethodType(params, restpe) => params find (_.name == name) getOrElse declarationOfName(restpe, name) + case ClassInfoType(_, _, clazz) => clazz.rawInfo member name + case _ => NoSymbol + } + pat match { + case Bind(name, _) => + context.enclosingContextChain.foldLeft(NoSymbol: Symbol)((res, ctx) => + res orElse declarationOfName(ctx.owner.rawInfo, name)) + case _ => NoSymbol + } + } + + // Issue better warnings than "unreachable code" when people mis-use + // variable patterns thinking they bind to existing identifiers. + // + // Possible TODO: more deeply nested variable patterns, like + // case (a, b) => 1 ; case (c, d) => 2 + // However this is a pain (at least the way I'm going about it) + // and I have to think these detailed errors are primarily useful + // for beginners, not people writing nested pattern matches. + def checkMatchVariablePatterns(m: Match) { + // A string describing the first variable pattern + var vpat: String = null + // Using an iterator so we can recognize the last case + val it = m.cases.iterator + + def addendum(pat: Tree) = { + matchingSymbolInScope(pat) match { + case NoSymbol => "" + case sym => + val desc = if (sym.isParameter) s"parameter ${sym.nameString} of" else sym + " in" + s"\nIf you intended to match against $desc ${sym.owner}, you must use backticks, like: case `${sym.nameString}` =>" + } + } + + while (it.hasNext) { + val cdef = it.next + // If a default case has been seen, then every succeeding case is unreachable. + if (vpat != null) + context.unit./*error*/warning(cdef.body.pos, "unreachable code due to " + vpat + addendum(cdef.pat)) + // If this is a default case and more cases follow, warn about this one so + // we have a reason to mention its pattern variable name and any corresponding + // symbol in scope. Errors will follow from the remaining cases, at least + // once we make the above warning an error. + else if (it.hasNext && (treeInfo isDefaultCase cdef)) { + val vpatName = cdef.pat match { + case Bind(name, _) => s" '$name'" + case _ => "" + } + vpat = s"variable pattern$vpatName on line ${cdef.pat.pos.line}" + context.unit.warning(cdef.pos, s"patterns after a variable pattern cannot match (SLS 8.1.1)" + addendum(cdef.pat)) + } + } + } + /** Implement a pattern match by turning its cases (including the implicit failure case) * into the corresponding (monadic) extractors, and combining them with the `orElse` combinator. * @@ -210,6 +273,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL */ def translateMatch(match_ : Match): Tree = { val Match(selector, cases) = match_ + checkMatchVariablePatterns(match_) // we don't transform after uncurry // (that would require more sophistication when generating trees, @@ -3354,16 +3418,12 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case Some(cds) => cds } - val allReachable = - if (unchecked) true - else { - val unreachables = unreachableCase(caseDefsWithGuards) - unreachables foreach {cd => reportUnreachable(cd.body.pos)} - // a switch with duplicate cases yields a verify error, - // and a switch with duplicate cases and guards cannot soundly be rewritten to an unguarded switch - // (even though the verify error would disappear, the behaviour would change) - unreachables.isEmpty - } + val allReachable = unchecked || { + // a switch with duplicate cases yields a verify error, + // and a switch with duplicate cases and guards cannot soundly be rewritten to an unguarded switch + // (even though the verify error would disappear, the behaviour would change) + unreachableCase(caseDefsWithGuards) map (cd => reportUnreachable(cd.body.pos)) isEmpty + } if (!allReachable) Nil else if (noGuards(caseDefsWithGuards)) { diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 92c50a05c2..d2a89eb9ff 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -34,6 +34,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT /** the following two members override abstract members in Transform */ val phaseName: String = "superaccessors" + /** The following flags may be set by this phase: */ + override def phaseNewFlags: Long = notPRIVATE + protected def newTransformer(unit: CompilationUnit): Transformer = new SuperAccTransformer(unit) @@ -192,9 +195,11 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT } } super.transform(tree) + case ModuleDef(_, _, _) => checkCompanionNameClashes(sym) super.transform(tree) + case Template(_, _, body) => val ownAccDefs = new ListBuffer[Tree] accDefs(currentOwner) = ownAccDefs @@ -221,72 +226,85 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT typeDef.symbol.deSkolemize.setFlag(SPECIALIZED) typeDef - case sel @ Select(qual @ This(_), name) => - // warn if they are selecting a private[this] member which - // also exists in a superclass, because they may be surprised - // to find out that a constructor parameter will shadow a - // field. See SI-4762. - if (settings.lint.value) { - if (sym.isPrivateLocal && sym.paramss.isEmpty) { - qual.symbol.ancestors foreach { parent => - parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 => - if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) { - unit.warning(sel.pos, - sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name - + " inherited from " + m2.owner + ". Changes to " + m2.name + " will not be visible within " - + sym.owner + " - you may want to give them distinct names." - ) + case sel @ Select(qual, name) => + /** return closest enclosing method, unless shadowed by an enclosing class; + * no use of closures here in the interest of speed. + */ + def closestEnclMethod(from: Symbol): Symbol = + if (from.isSourceMethod) from + else if (from.isClass) NoSymbol + else closestEnclMethod(from.owner) + + if (closestEnclMethod(currentOwner) hasAnnotation definitions.ScalaInlineClass) + sym.makeNotPrivate(sym.owner) + + qual match { + case This(_) => + // warn if they are selecting a private[this] member which + // also exists in a superclass, because they may be surprised + // to find out that a constructor parameter will shadow a + // field. See SI-4762. + if (settings.lint.value) { + if (sym.isPrivateLocal && sym.paramss.isEmpty) { + qual.symbol.ancestors foreach { parent => + parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 => + if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) { + unit.warning(sel.pos, + sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name + + " inherited from " + m2.owner + ". Changes to " + m2.name + " will not be visible within " + + sym.owner + " - you may want to give them distinct names.") + } + } } } } - } - } - // direct calls to aliases of param accessors to the superclass in order to avoid - // duplicating fields. - if (sym.isParamAccessor && sym.alias != NoSymbol) { - val result = (localTyper.typedPos(tree.pos) { - Select(Super(qual, tpnme.EMPTY) setPos qual.pos, sym.alias) - }).asInstanceOf[Select] - debuglog("alias replacement: " + tree + " ==> " + result);//debug - localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, true)) - } - else { - /** A trait which extends a class and accesses a protected member - * of that class cannot implement the necessary accessor method - * because its implementation is in an implementation class (e.g. - * Foo$class) which inherits nothing, and jvm access restrictions - * require the call site to be in an actual subclass. So non-trait - * classes inspect their ancestors for any such situations and - * generate the accessors. See SI-2296. - */ - // FIXME - this should be unified with needsProtectedAccessor, but some - // subtlety which presently eludes me is foiling my attempts. - val shouldEnsureAccessor = ( - currentClass.isTrait - && sym.isProtected - && sym.enclClass != currentClass - && !sym.owner.isTrait - && (sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass) - && (qual.symbol.info.member(sym.name) ne NoSymbol) - ) - if (shouldEnsureAccessor) { - log("Ensuring accessor for call to protected " + sym.fullLocationString + " from " + currentClass) - ensureAccessor(sel) - } - else - mayNeedProtectedAccessor(sel, List(EmptyTree), false) - } + // direct calls to aliases of param accessors to the superclass in order to avoid + // duplicating fields. + if (sym.isParamAccessor && sym.alias != NoSymbol) { + val result = (localTyper.typedPos(tree.pos) { + Select(Super(qual, tpnme.EMPTY) setPos qual.pos, sym.alias) + }).asInstanceOf[Select] + debuglog("alias replacement: " + tree + " ==> " + result); //debug + localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, true)) + } else { + /** + * A trait which extends a class and accesses a protected member + * of that class cannot implement the necessary accessor method + * because its implementation is in an implementation class (e.g. + * Foo$class) which inherits nothing, and jvm access restrictions + * require the call site to be in an actual subclass. So non-trait + * classes inspect their ancestors for any such situations and + * generate the accessors. See SI-2296. + */ + // FIXME - this should be unified with needsProtectedAccessor, but some + // subtlety which presently eludes me is foiling my attempts. + val shouldEnsureAccessor = ( + currentClass.isTrait + && sym.isProtected + && sym.enclClass != currentClass + && !sym.owner.isTrait + && (sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass) + && (qual.symbol.info.member(sym.name) ne NoSymbol)) + if (shouldEnsureAccessor) { + log("Ensuring accessor for call to protected " + sym.fullLocationString + " from " + currentClass) + ensureAccessor(sel) + } else + mayNeedProtectedAccessor(sel, List(EmptyTree), false) + } - case sel @ Select(Super(_, mix), name) => - if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) { - if (!settings.overrideVars.value) - unit.error(tree.pos, "super may be not be used on "+ sym.accessedOrSelf) - } - else if (isDisallowed(sym)) { - unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead") + case Super(_, mix) => + if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) { + if (!settings.overrideVars.value) + unit.error(tree.pos, "super may be not be used on " + sym.accessedOrSelf) + } else if (isDisallowed(sym)) { + unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead") + } + transformSuperSelect(sel) + + case _ => + mayNeedProtectedAccessor(sel, List(EmptyTree), true) } - transformSuperSelect(sel) case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension => treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, withInvalidOwner(transform(rhs))) @@ -294,9 +312,6 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT case TypeApply(sel @ Select(qual, name), args) => mayNeedProtectedAccessor(sel, args, true) - case sel @ Select(qual, name) => - mayNeedProtectedAccessor(sel, List(EmptyTree), true) - case Assign(lhs @ Select(qual, name), rhs) => if (lhs.symbol.isVariable && lhs.symbol.isJavaDefined && @@ -311,10 +326,12 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT case Apply(fn, args) => assert(fn.tpe != null, tree) treeCopy.Apply(tree, transform(fn), transformArgs(fn.tpe.params, args)) + case Function(vparams, body) => withInvalidOwner { treeCopy.Function(tree, vparams, transform(body)) } + case _ => super.transform(tree) } diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala index 0d51230623..903de4a247 100644 --- a/src/library/scala/collection/GenTraversableLike.scala +++ b/src/library/scala/collection/GenTraversableLike.scala @@ -333,7 +333,7 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with /** Selects first ''n'' elements. * $orderDependent - * @param n Tt number of elements to take from this $coll. + * @param n the number of elements to take from this $coll. * @return a $coll consisting only of the first `n` elements of this $coll, * or else the whole $coll, if it has less than `n` elements. */ diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index 2cf9985523..0b297aeb45 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -72,19 +72,8 @@ class HashMap[A, +B] extends AbstractMap[A, B] } private[collection] def computeHash(key: A) = improve(elemHashCode(key)) - - protected type MergeFunction[A1, B1] = ((A1, B1), (A1, B1)) => (A1, B1); - - import HashMap.Merger - protected def liftMerger[A1, B1](mergef: MergeFunction[A1, B1]): Merger[A1, B1] = if (mergef == null) null else new Merger[A1, B1] { - self => - def apply(kv1: (A1, B1), kv2: (A1, B1)): (A1, B1) = mergef(kv1, kv2) - val invert: Merger[A1, B1] = new Merger[A1, B1] { - def apply(kv1: (A1, B1), kv2: (A1, B1)): (A1, B1) = mergef(kv2, kv1) - def invert: Merger[A1, B1] = self - } - } + import HashMap.{Merger, MergeFunction, liftMerger} private[collection] def get0(key: A, hash: Int, level: Int): Option[B] = None @@ -130,11 +119,26 @@ class HashMap[A, +B] extends AbstractMap[A, B] */ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int { - private[immutable] abstract class Merger[A, B] { + private abstract class Merger[A, B] { def apply(kv1: (A, B), kv2: (A, B)): (A, B) def invert: Merger[A, B] } - + + private type MergeFunction[A1, B1] = ((A1, B1), (A1, B1)) => (A1, B1) + + private def liftMerger[A1, B1](mergef: MergeFunction[A1, B1]): Merger[A1, B1] = + if (mergef == null) defaultMerger.asInstanceOf[Merger[A1, B1]] else liftMerger0(mergef) + + private[this] val defaultMerger : Merger[Any, Any] = liftMerger0((a,b) => a) + + private[this] def liftMerger0[A1, B1](mergef: MergeFunction[A1, B1]): Merger[A1, B1] = new Merger[A1, B1] { + self => + def apply(kv1: (A1, B1), kv2: (A1, B1)): (A1, B1) = mergef(kv1, kv2) + val invert: Merger[A1, B1] = new Merger[A1, B1] { + def apply(kv1: (A1, B1), kv2: (A1, B1)): (A1, B1) = mergef(kv2, kv1) + def invert: Merger[A1, B1] = self + } + } /** $mapCanBuildFromInfo */ implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), HashMap[A, B]] = new MapCanBuildFrom[A, B] diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index c60fdc3bf1..ef0173337c 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -151,10 +151,12 @@ object HashSet extends ImmutableSetFactory[HashSet] { override def removed0(key: A, hash: Int, level: Int): HashSet[A] = if (hash == this.hash) { val ks1 = ks - key - if (!ks1.isEmpty) - new HashSetCollision1(hash, ks1) - else + if(ks1.isEmpty) HashSet.empty[A] + else if(ks1.tail.isEmpty) + new HashSet1(ks1.head, hash) + else + new HashSetCollision1(hash, ks1) } else this override def iterator: Iterator[A] = ks.iterator @@ -236,7 +238,12 @@ object HashSet extends ImmutableSetFactory[HashSet] { Array.copy(elems, 0, elemsNew, 0, offset) Array.copy(elems, offset + 1, elemsNew, offset, elems.length - offset - 1) val sizeNew = size - sub.size - new HashTrieSet(bitmapNew, elemsNew, sizeNew) + // if we have only one child, which is not a HashTrieSet but a self-contained set like + // HashSet1 or HashSetCollision1, return the child instead + if (elemsNew.length == 1 && !elemsNew(0).isInstanceOf[HashTrieSet[_]]) + elemsNew(0) + else + new HashTrieSet(bitmapNew, elemsNew, sizeNew) } else HashSet.empty[A] } else { diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index ce3abaacb7..4dd0d62fc0 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -116,8 +116,8 @@ class ListSet[A] extends AbstractSet[A] def hasNext = that.nonEmpty def next: A = if (hasNext) { - val res = that.elem - that = that.next + val res = that.head + that = that.tail res } else Iterator.empty.next @@ -126,18 +126,18 @@ class ListSet[A] extends AbstractSet[A] /** * @throws Predef.NoSuchElementException */ - protected def elem: A = throw new NoSuchElementException("Set has no elements"); + override def head: A = throw new NoSuchElementException("Set has no elements"); /** * @throws Predef.NoSuchElementException */ - protected def next: ListSet[A] = throw new NoSuchElementException("Next of an empty set"); + override def tail: ListSet[A] = throw new NoSuchElementException("Next of an empty set"); override def stringPrefix = "ListSet" /** Represents an entry in the `ListSet`. */ - protected class Node(override protected val elem: A) extends ListSet[A] with Serializable { + protected class Node(override val head: A) extends ListSet[A] with Serializable { override private[ListSet] def unchecked_outer = self /** Returns the number of elements in this set. @@ -162,7 +162,7 @@ class ListSet[A] extends AbstractSet[A] */ override def contains(e: A) = containsInternal(this, e) @tailrec private def containsInternal(n: ListSet[A], e: A): Boolean = - !n.isEmpty && (n.elem == e || containsInternal(n.unchecked_outer, e)) + !n.isEmpty && (n.head == e || containsInternal(n.unchecked_outer, e)) /** This method creates a new set with an additional element. */ @@ -170,10 +170,10 @@ class ListSet[A] extends AbstractSet[A] /** `-` can be used to remove a single element from a set. */ - override def -(e: A): ListSet[A] = if (e == elem) self else { - val tail = self - e; new tail.Node(elem) + override def -(e: A): ListSet[A] = if (e == head) self else { + val tail = self - e; new tail.Node(head) } - override protected def next: ListSet[A] = self + override def tail: ListSet[A] = self } } diff --git a/src/library/scala/reflect/base/FlagSets.scala b/src/library/scala/reflect/base/FlagSets.scala index 43de9970c0..96cdbe894c 100644 --- a/src/library/scala/reflect/base/FlagSets.scala +++ b/src/library/scala/reflect/base/FlagSets.scala @@ -13,11 +13,4 @@ trait FlagSets { self: Universe => /** The empty set of flags */ val NoFlags: FlagSet - - /** The base API all flag bearers support */ - trait HasFlagsBase { - def flags: FlagSet - def hasFlag(flags: FlagSet): Boolean - } } - diff --git a/src/library/scala/reflect/base/Trees.scala b/src/library/scala/reflect/base/Trees.scala index 7fa3c90e7d..70993fd77f 100644 --- a/src/library/scala/reflect/base/Trees.scala +++ b/src/library/scala/reflect/base/Trees.scala @@ -1359,7 +1359,9 @@ trait Trees { self: Universe => implicit val ModifiersTag: ClassTag[Modifiers] /** ... */ - abstract class ModifiersBase extends HasFlagsBase { + abstract class ModifiersBase { + def flags: FlagSet // default: NoFlags + def hasFlag(flag: FlagSet): Boolean def privateWithin: Name // default: EmptyTypeName def annotations: List[Tree] // default: List() def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala index 6d105c9d20..36836e84a9 100644 --- a/src/reflect/scala/reflect/api/FlagSets.scala +++ b/src/reflect/scala/reflect/api/FlagSets.scala @@ -9,7 +9,6 @@ trait FlagSets { self: Universe => trait FlagOps extends Any { def | (right: FlagSet): FlagSet - def hasFlag(flags: FlagSet): Boolean } implicit def addFlagOps(left: FlagSet): FlagOps @@ -18,84 +17,86 @@ trait FlagSets { self: Universe => type FlagValues >: Null <: FlagValuesApi + // Q: I have a pretty flag. Can I put it here? + // A: Only if there's a tree that cannot be built without it. + // If you want to put a flag here so that it can be tested against, + // introduce an `isXXX` method in one of the `api.Symbols` classes instead. + trait FlagValuesApi { - /** Flag indicating that symbol or tree represents a trait */ + /** Flag indicating that tree represents a trait */ val TRAIT: FlagSet - /** Flag indicating that symbol or tree represents a module or its internal module class */ - val MODULE: FlagSet + /** Flag indicating that a tree is an interface (i.e. a trait which defines only abstract methods) */ + val INTERFACE: FlagSet - /** Flag indicating that symbol or tree represents a mutable variable */ + /** Flag indicating that tree represents a mutable variable */ val MUTABLE: FlagSet - /** Flag indicating that symbol or tree represents a package or its internal package class */ - val PACKAGE: FlagSet - - /** Flag indicating that symbol or tree represents a method */ - val METHOD: FlagSet - - /** Flag indicating that symbol or tree represents a macro definition. */ + /** Flag indicating that tree represents a macro definition. */ val MACRO: FlagSet - /** Flag indicating that symbol or tree represents an abstract type, method, or value */ + /** Flag indicating that tree represents an abstract type, method, or value */ val DEFERRED: FlagSet - /** Flag indicating that symbol or tree represents an abstract class */ + /** Flag indicating that tree represents an abstract class */ val ABSTRACT: FlagSet - /** Flag indicating that symbol or tree has `final` modifier set */ + /** Flag indicating that tree has `final` modifier set */ val FINAL: FlagSet - /** Flag indicating that symbol or tree has `sealed` modifier set */ + /** Flag indicating that tree has `sealed` modifier set */ val SEALED: FlagSet - /** Flag indicating that symbol or tree has `implicit` modifier set */ + /** Flag indicating that tree has `implicit` modifier set */ val IMPLICIT: FlagSet - /** Flag indicating that symbol or tree has `lazy` modifier set */ + /** Flag indicating that tree has `lazy` modifier set */ val LAZY: FlagSet - /** Flag indicating that symbol or tree has `override` modifier set */ + /** Flag indicating that tree has `override` modifier set */ val OVERRIDE: FlagSet - /** Flag indicating that symbol or tree has `private` modifier set */ + /** Flag indicating that tree has `private` modifier set */ val PRIVATE: FlagSet - /** Flag indicating that symbol or tree has `protected` modifier set */ + /** Flag indicating that tree has `protected` modifier set */ val PROTECTED: FlagSet - /** Flag indicating that symbol or tree has `case` modifier set */ + /** Flag indicating that tree represents a member local to current class + * (i.e. private[this] or protected[this]. + * This requires having either PRIVATE or PROTECTED set as well. + */ + val LOCAL: FlagSet + + /** Flag indicating that tree has `case` modifier set */ val CASE: FlagSet - /** Flag indicating that symbol or tree has `abstract` and `override` modifiers set */ + /** Flag indicating that tree has `abstract` and `override` modifiers set */ val ABSOVERRIDE: FlagSet - /** Flag indicating that symbol or tree represents a by-name parameter */ + /** Flag indicating that tree represents a by-name parameter */ val BYNAMEPARAM: FlagSet - /** Flag indicating that symbol or tree represents a class or parameter. + /** Flag indicating that tree represents a class or parameter. * Both type and value parameters carry the flag. */ val PARAM: FlagSet - /** Flag indicating that symbol or tree represents a field of a class - * that was generated from a parameter of that class */ - val PARAMACCESSOR: FlagSet - - /** Flag indicating that symbol or tree represents a field of a case class - * that corresponds to a parameter in the first parameter list of the - * primary constructor of that class */ - val CASEACCESSOR: FlagSet - - /** Flag indicating that symbol or tree represents a contravariant + /** Flag indicating that tree represents a covariant * type parameter (marked with `+`). */ val COVARIANT: FlagSet - /** Flag indicating that symbol or tree represents a contravariant + /** Flag indicating that tree represents a contravariant * type parameter (marked with `-`). */ val CONTRAVARIANT: FlagSet - /** Flag indicating that parameter has a default value */ + /** Flag indicating that tree represents a parameter that has a default value */ val DEFAULTPARAM: FlagSet + + /** Flag indicating that tree represents an early definition */ + val PRESUPER: FlagSet + + /** Flag indicating that tree represents a variable or a member initialized to the default value */ + val DEFAULTINIT: FlagSet } } diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index 448382973a..fda76c7b95 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -13,7 +13,7 @@ trait Symbols extends base.Symbols { self: Universe => override type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolApi /** The API of symbols */ - trait SymbolApi extends SymbolBase with HasFlagsBase { this: Symbol => + trait SymbolApi extends SymbolBase { this: Symbol => /** The position of this symbol */ @@ -110,10 +110,10 @@ trait Symbols extends base.Symbols { self: Universe => * * The java access levels translate as follows: * - * java private: hasFlag(PRIVATE) && (privateWithin == NoSymbol) - * java package: !hasFlag(PRIVATE | PROTECTED) && (privateWithin == enclosingPackage) - * java protected: hasFlag(PROTECTED) && (privateWithin == enclosingPackage) - * java public: !hasFlag(PRIVATE | PROTECTED) && (privateWithin == NoSymbol) + * java private: isPrivate && (privateWithin == NoSymbol) + * java package: !isPrivate && !isProtected && (privateWithin == enclosingPackage) + * java protected: isProtected && (privateWithin == enclosingPackage) + * java public: !isPrivate && !isProtected && (privateWithin == NoSymbol) */ def privateWithin: Symbol diff --git a/src/reflect/scala/reflect/internal/FlagSets.scala b/src/reflect/scala/reflect/internal/FlagSets.scala index 6e77741355..b03d01c944 100644 --- a/src/reflect/scala/reflect/internal/FlagSets.scala +++ b/src/reflect/scala/reflect/internal/FlagSets.scala @@ -13,7 +13,6 @@ trait FlagSets extends api.FlagSets { self: SymbolTable => private class FlagOpsImpl(left: Long) extends FlagOps { def | (right: Long): Long = left | right - def hasFlag(right: Long): Boolean = (left & right) != 0 } val NoFlags: FlagSet = 0L @@ -22,10 +21,8 @@ trait FlagSets extends api.FlagSets { self: SymbolTable => object Flag extends FlagValues { val TRAIT : FlagSet = Flags.TRAIT - val MODULE : FlagSet = Flags.MODULE + val INTERFACE : FlagSet = Flags.INTERFACE val MUTABLE : FlagSet = Flags.MUTABLE - val PACKAGE : FlagSet = Flags.PACKAGE - val METHOD : FlagSet = Flags.METHOD val MACRO : FlagSet = Flags.MACRO val DEFERRED : FlagSet = Flags.DEFERRED val ABSTRACT : FlagSet = Flags.ABSTRACT @@ -36,15 +33,15 @@ trait FlagSets extends api.FlagSets { self: SymbolTable => val OVERRIDE : FlagSet = Flags.OVERRIDE val PRIVATE : FlagSet = Flags.PRIVATE val PROTECTED : FlagSet = Flags.PROTECTED + val LOCAL : FlagSet = Flags.LOCAL val CASE : FlagSet = Flags.CASE val ABSOVERRIDE : FlagSet = Flags.ABSOVERRIDE val BYNAMEPARAM : FlagSet = Flags.BYNAMEPARAM val PARAM : FlagSet = Flags.PARAM - val PARAMACCESSOR : FlagSet = Flags.PARAMACCESSOR - val CASEACCESSOR : FlagSet = Flags.CASEACCESSOR val COVARIANT : FlagSet = Flags.COVARIANT val CONTRAVARIANT : FlagSet = Flags.CONTRAVARIANT val DEFAULTPARAM : FlagSet = Flags.DEFAULTPARAM - val INTERFACE : FlagSet = Flags.INTERFACE + val PRESUPER : FlagSet = Flags.PRESUPER + val DEFAULTINIT : FlagSet = Flags.DEFAULTINIT } } diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 2e2e63a4b4..bde7f7ac51 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -247,7 +247,7 @@ trait Mirrors extends api.Mirrors { // is very beneficial for a handful of bootstrap symbols to have // first class identities sealed trait WellKnownSymbol extends Symbol { - this initFlags TopLevelCreationFlags + this initFlags (TopLevelCreationFlags | STATIC) } // Features common to RootClass and RootPackage, the roots of all // type and term symbols respectively. @@ -276,7 +276,6 @@ trait Mirrors extends api.Mirrors { override def isRoot = true override def isEffectiveRoot = true - override def isStatic = true override def isNestedClass = false } // The empty package, which holds all top level types without given packages. diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index e3e2063b05..0c86e4fba0 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -670,7 +670,8 @@ trait Printers extends api.Printers { self: SymbolTable => if (flags == NoFlags) nme.NoFlags.toString else { val s_flags = new collection.mutable.ListBuffer[String] - for (i <- 0 to 63 if (flags hasFlag (1L << i))) + def hasFlag(left: Long, right: Long): Boolean = (left & right) != 0 + for (i <- 0 to 63 if hasFlag(flags, 1L << i)) s_flags += flagToString(1L << i).replace("<", "").replace(">", "").toUpperCase s_flags mkString " | " } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 2a306d7c6e..5b99e2fdf0 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -80,8 +80,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def toType: Type = tpe def toTypeIn(site: Type): Type = site.memberType(this) def toTypeConstructor: Type = typeConstructor - def setFlags(flags: FlagSet): this.type = setInternalFlags(flags) - def setInternalFlags(flag: Long): this.type = { setFlag(flag); this } def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this } def getAnnotations: List[AnnotationInfo] = { initialize; annotations } def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this } @@ -876,7 +874,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => // ------ owner attribute -------------------------------------------------------------- def owner: Symbol = { - Statistics.incCounter(ownerCount) + if (Statistics.hotEnabled) Statistics.incCounter(ownerCount) rawowner } @@ -2272,7 +2270,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => private[this] var _rawname: TermName = initName def rawname = _rawname def name = { - Statistics.incCounter(nameCount) + if (Statistics.hotEnabled) Statistics.incCounter(nameCount) _rawname } def name_=(name: Name) { @@ -2444,12 +2442,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => flatOwnerInfo.decl(name.toTypeName).suchThat(sym => sym.isClass && (sym isCoDefinedWith this)) override def owner = { - Statistics.incCounter(ownerCount) + if (Statistics.hotEnabled) Statistics.incCounter(ownerCount) if (!isMethod && needsFlatClasses) rawowner.owner else rawowner } override def name: TermName = { - Statistics.incCounter(nameCount) + if (Statistics.hotEnabled) Statistics.incCounter(nameCount) if (!isMethod && needsFlatClasses) { if (flatname eq null) flatname = nme.flattenedName(rawowner.name, rawname) @@ -2543,7 +2541,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def rawname = _rawname def name = { - Statistics.incCounter(nameCount) + if (Statistics.hotEnabled) Statistics.incCounter(nameCount) _rawname } final def asNameType(n: Name) = n.toTypeName @@ -2681,7 +2679,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } } - Statistics.incCounter(typeSymbolCount) + if (Statistics.hotEnabled) Statistics.incCounter(typeSymbolCount) } implicit val TypeSymbolTag = ClassTag[TypeSymbol](classOf[TypeSymbol]) @@ -2860,7 +2858,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } override def owner: Symbol = { - Statistics.incCounter(ownerCount) + if (Statistics.hotEnabled) Statistics.incCounter(ownerCount) if (needsFlatClasses) rawowner.owner else rawowner } @@ -2904,7 +2902,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def children = childSet override def addChild(sym: Symbol) { childSet = childSet + sym } - Statistics.incCounter(classSymbolCount) + if (Statistics.hotEnabled) Statistics.incCounter(classSymbolCount) } implicit val ClassSymbolTag = ClassTag[ClassSymbol](classOf[ClassSymbol]) diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 1b4c1b2877..92a6156e54 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -236,7 +236,7 @@ abstract class TreeInfo { case _ => tree } - + /** Is tree a self or super constructor call? */ def isSelfOrSuperConstrCall(tree: Tree) = { // stripNamedApply for SI-3584: adaptToImplicitMethod in Typers creates a special context diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 220869e4d2..94d51b7455 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -160,7 +160,7 @@ trait Trees extends api.Trees { self: SymbolTable => new ThisSubstituter(clazz, to) transform this def hasSymbolWhich(f: Symbol => Boolean) = - hasSymbol && symbol != null && f(symbol) + (symbol ne null) && (symbol ne NoSymbol) && f(symbol) def isErroneous = (tpe ne null) && tpe.isErroneous def isTyped = (tpe ne null) && !tpe.isErroneous diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala index 4074dd9e93..8d9711dedd 100644 --- a/src/reflect/scala/reflect/macros/Universe.scala +++ b/src/reflect/scala/reflect/macros/Universe.scala @@ -22,17 +22,15 @@ abstract class Universe extends scala.reflect.api.Universe { /** The extended API of symbols that's supported in macro context universes */ - trait SymbolContextApi extends SymbolApi with AttachableApi { this: Symbol => + trait SymbolContextApi extends SymbolApi with AttachableApi { self: Symbol => - def setFlags(flags: FlagSet): this.type + def setTypeSignature(tpe: Type): Symbol - def setTypeSignature(tpe: Type): this.type + def setAnnotations(annots: AnnotationInfo*): Symbol - def setAnnotations(annots: AnnotationInfo*): this.type + def setName(name: Name): Symbol - def setName(name: Name): this.type - - def setPrivateWithin(sym: Symbol): this.type + def setPrivateWithin(sym: Symbol): Symbol } // Tree extensions --------------------------------------------------------------- @@ -41,20 +39,20 @@ abstract class Universe extends scala.reflect.api.Universe { /** The extended API of trees that's supported in macro context universes */ - trait TreeContextApi extends TreeApi with AttachableApi { this: Tree => + trait TreeContextApi extends TreeApi with AttachableApi { self: Tree => /** ... */ def pos_=(pos: Position): Unit /** ... */ - def setPos(newpos: Position): this.type + def setPos(newpos: Position): Tree /** ... */ def tpe_=(t: Type): Unit /** Set tpe to give `tp` and return this. */ - def setType(tp: Type): this.type + def setType(tp: Type): Tree /** Like `setType`, but if this is a previously empty TypeTree that * fact is remembered so that resetAllAttrs will snap back. @@ -73,13 +71,13 @@ abstract class Universe extends scala.reflect.api.Universe { * and therefore should be abandoned if the current line of type * inquiry doesn't work out. */ - def defineType(tp: Type): this.type + def defineType(tp: Type): Tree /** ... */ def symbol_=(sym: Symbol): Unit /** ... */ - def setSymbol(sym: Symbol): this.type + def setSymbol(sym: Symbol): Tree } override type SymTree >: Null <: Tree with SymTreeContextApi |