From 37a290b02ef09c7e563239d878088aa30405eecb Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 10 Aug 2012 13:01:25 +0200 Subject: HIDDEN => ARTIFACT This test is necessary in the API to tell apart useful synthetic symbols (such as accessors) and low-level compilation artifacts (such as $outer). However `isHidden` (as it's currently named in the compiler) is too generic. Hence I renamed it along with the corresponding flag. Now the test says `isArtifact` and the flag is named ARTIFACT. Despite being an improvement over the first version, `isArtifact` is still a bit unlucky. The name I like is `isImplementationArtifact`, but that's a mouthful to be used in compiler hacking. Moreover, IMPLEMENTATION_ARTIFACT looks weird. For a discussion about related stuff see: http://groups.google.com/group/scala-internals/browse_thread/thread/d04e762127737968 https://github.com/scala/scala/pull/1114 --- .../scala/tools/nsc/backend/jvm/GenASM.scala | 4 +-- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 14 ++++----- .../nsc/symtab/classfile/ClassfileParser.scala | 2 +- .../scala/tools/nsc/transform/ExplicitOuter.scala | 4 +-- .../tools/nsc/transform/SpecializeTypes.scala | 36 +++++++++++----------- .../tools/nsc/typechecker/PatternMatching.scala | 4 +-- src/reflect/scala/reflect/api/Symbols.scala | 5 +++ src/reflect/scala/reflect/internal/Flags.scala | 22 ++++++------- src/reflect/scala/reflect/internal/HasFlags.scala | 8 ++--- src/reflect/scala/reflect/internal/Symbols.scala | 5 +-- 10 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 194ceca504..17b479e5e5 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -295,7 +295,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { if (finalFlag && !sym.hasAbstractFlag) ACC_FINAL else 0, if (sym.isStaticMember) ACC_STATIC else 0, if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0, - if (sym.isHidden) ACC_SYNTHETIC else 0, + if (sym.isArtifact) ACC_SYNTHETIC else 0, if (sym.isClass && !sym.isInterface) ACC_SUPER else 0, if (sym.isVarargsMethod) ACC_VARARGS else 0, if (sym.hasFlag(Flags.SYNCHRONIZED)) ACC_SYNCHRONIZED else 0 @@ -851,7 +851,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { // generic information could disappear as a consequence of a seemingly // unrelated change. settings.Ynogenericsig.value - || sym.isHidden + || sym.isArtifact || sym.isLiftedMethod || sym.isBridge || (sym.ownerChain exists (_.isImplClass)) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index bad4ecc647..11b0c40be7 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -728,7 +728,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with // generic information could disappear as a consequence of a seemingly // unrelated change. settings.Ynogenericsig.value - || sym.isHidden + || sym.isArtifact || sym.isLiftedMethod || sym.isBridge || (sym.ownerChain exists (_.isImplClass)) @@ -866,7 +866,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with def genField(f: IField) { debuglog("Adding field: " + f.symbol.fullName) - + val jfield = jclass.addNewField( javaFieldFlags(f.symbol), javaName(f.symbol), @@ -1021,7 +1021,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with method = m jmethod = clinitMethod - + computeLocalVarsIndex(m) genCode(m) case None => @@ -1116,7 +1116,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name } toSet } debuglog("Potentially conflicting names for forwarders: " + conflictingNames) - + for (m <- moduleClass.info.membersBasedOnFlags(ExcludedForwarderFlags, Flags.METHOD)) { if (m.isType || m.isDeferred || (m.owner eq ObjectClass) || m.isConstructor) debuglog("No forwarder for '%s' from %s to '%s'".format(m, className, moduleClass)) @@ -1308,7 +1308,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with jclass.getType()) } } - + style match { case Static(true) => dbg("invokespecial"); jcode.emitINVOKESPECIAL(jowner, jname, jtype) case Static(false) => dbg("invokestatic"); jcode.emitINVOKESTATIC(jowner, jname, jtype) @@ -1889,7 +1889,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with */ def computeLocalVarsIndex(m: IMethod) { var idx = if (m.symbol.isStaticMember) 0 else 1; - + for (l <- m.params) { debuglog("Index value for " + l + "{" + l.## + "}: " + idx) l.index = idx @@ -1977,7 +1977,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if (finalFlag && !sym.hasAbstractFlag) ACC_FINAL else 0, if (sym.isStaticMember) ACC_STATIC else 0, if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0, - if (sym.isHidden) ACC_SYNTHETIC else 0, + if (sym.isArtifact) ACC_SYNTHETIC else 0, if (sym.isClass && !sym.isInterface) ACC_SUPER else 0, if (sym.isVarargsMethod) ACC_VARARGS else 0, if (sym.hasFlag(Flags.SYNCHRONIZED)) JAVA_ACC_SYNCHRONIZED else 0 diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 32c9bff21b..fcd5e369f5 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -869,7 +869,7 @@ abstract class ClassfileParser { } else in.skip(attrLen) case tpnme.SyntheticATTR => - sym.setFlag(SYNTHETIC | HIDDEN) + sym.setFlag(SYNTHETIC | ARTIFACT) in.skip(attrLen) case tpnme.BridgeATTR => sym.setFlag(BRIDGE) diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 8e928dc9e6..dd7c83967d 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -95,7 +95,7 @@ abstract class ExplicitOuter extends InfoTransform else findOrElse(clazz.info.decls)(_.outerSource == clazz)(NoSymbol) } def newOuterAccessor(clazz: Symbol) = { - val accFlags = SYNTHETIC | HIDDEN | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 ) + val accFlags = SYNTHETIC | ARTIFACT | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 ) val sym = clazz.newMethod(nme.OUTER, clazz.pos, accFlags) val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType @@ -104,7 +104,7 @@ abstract class ExplicitOuter extends InfoTransform sym setInfo MethodType(Nil, restpe) } def newOuterField(clazz: Symbol) = { - val accFlags = SYNTHETIC | HIDDEN | PARAMACCESSOR | ( if (clazz.isEffectivelyFinal) PrivateLocal else PROTECTED ) + val accFlags = SYNTHETIC | ARTIFACT | PARAMACCESSOR | ( if (clazz.isEffectivelyFinal) PrivateLocal else PROTECTED ) val sym = clazz.newValue(nme.OUTER_LOCAL, clazz.pos, accFlags) sym setInfo clazz.outerClass.thisType diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 10a946c318..1d987825d1 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -452,7 +452,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { def survivingParams(params: List[Symbol], env: TypeEnv) = params filter { p => - !p.isSpecialized || + !p.isSpecialized || !env.contains(p) || !isPrimitiveValueType(env(p)) } @@ -506,16 +506,16 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * was both already used for a map and mucho long. So "sClass" is the * specialized subclass of "clazz" throughout this file. */ - + // SI-5545: Eliminate classes with the same name loaded from the bytecode already present - all we need to do is // to force .info on them, as their lazy type will be evaluated and the symbols will be eliminated. Unfortunately // evaluating the info after creating the specialized class will mess the specialized class signature, so we'd - // better evaluate it before creating the new class symbol + // better evaluate it before creating the new class symbol val clazzName = specializedName(clazz, env0).toTypeName - val bytecodeClazz = clazz.owner.info.decl(clazzName) + val bytecodeClazz = clazz.owner.info.decl(clazzName) // debuglog("Specializing " + clazz + ", but found " + bytecodeClazz + " already there") bytecodeClazz.info - + val sClass = clazz.owner.newClass(clazzName, clazz.pos, (clazz.flags | SPECIALIZED) & ~CASE) def cloneInSpecializedClass(member: Symbol, flagFn: Long => Long, newName: Name = null) = @@ -762,7 +762,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } } - + val subclasses = specializations(clazz.info.typeParams) filter satisfiable subclasses foreach { env => @@ -798,7 +798,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { var specializingOn = specializedParams(sym) val unusedStvars = specializingOn filterNot specializedTypeVars(sym.info) - // I think the last condition should be !sym.isHidden, but that made the + // I think the last condition should be !sym.isArtifact, but that made the // compiler start warning about Tuple1.scala and Tuple2.scala claiming // their type parameters are used in non-specializable positions. Why is // unusedStvars.nonEmpty for these classes??? @@ -1006,7 +1006,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * Fails if such an environment cannot be found. * * If `strict` is true, a UnifyError is thrown if unification is impossible. - * + * * If `tparams` is true, then the methods tries to unify over type params in polytypes as well. */ private def unify(tp1: Type, tp2: Type, env: TypeEnv, strict: Boolean, tparams: Boolean = false): TypeEnv = (tp1, tp2) match { @@ -1185,7 +1185,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { || specializedTypeVars(t1).nonEmpty || specializedTypeVars(t2).nonEmpty) } - + env forall { case (tvar, tpe) => matches(tvar.info.bounds.lo, tpe) && matches(tpe, tvar.info.bounds.hi) || { if (warnings) @@ -1201,7 +1201,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } } - + def satisfiabilityConstraints(env: TypeEnv): Option[TypeEnv] = { val noconstraints = Some(emptyEnv) def matches(tpe1: Type, tpe2: Type): Option[TypeEnv] = { @@ -1232,7 +1232,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } with typechecker.Duplicators { private val (castfrom, castto) = casts.unzip private object CastMap extends SubstTypeMap(castfrom.toList, castto.toList) - + class BodyDuplicator(_context: Context) extends super.BodyDuplicator(_context) { override def castType(tree: Tree, pt: Type): Tree = { // log(" expected type: " + pt) @@ -1249,9 +1249,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { ntree } } - + protected override def newBodyDuplicator(context: Context) = new BodyDuplicator(context) - + } /** A tree symbol substituter that substitutes on type skolems. @@ -1359,7 +1359,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } } - + def reportError[T](body: =>T)(handler: TypeError => T): T = try body catch { @@ -1396,7 +1396,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { else None } else None } - + curTree = tree tree match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => @@ -1570,7 +1570,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { }) debuglog("created special overload tree " + t) debuglog("created " + t) - reportError { + reportError { localTyper.typed(t) } { _ => super.transform(tree) @@ -1629,9 +1629,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { super.transform(tree) } } - + /** Duplicate the body of the given method `tree` to the new symbol `source`. - * + * * Knowing that the method can be invoked only in the `castmap` type environment, * this method will insert casts for all the expressions of types mappend in the * `castmap`. diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 1b502025c2..2063a261f8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -8,7 +8,7 @@ package scala.tools.nsc package typechecker import symtab._ -import Flags.{MUTABLE, METHOD, LABEL, SYNTHETIC, HIDDEN} +import Flags.{MUTABLE, METHOD, LABEL, SYNTHETIC, ARTIFACT} import language.postfixOps import scala.tools.nsc.transform.TypingTransformers import scala.tools.nsc.transform.Transform @@ -1083,7 +1083,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` by `Select(q, outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix` // if there's an outer accessor, otherwise the condition becomes `true` -- TODO: can we improve needsOuterTest so there's always an outerAccessor? - val outer = expectedTp.typeSymbol.newMethod(vpmName.outer) setInfo expectedTp.prefix setFlag SYNTHETIC | HIDDEN + val outer = expectedTp.typeSymbol.newMethod(vpmName.outer) setInfo expectedTp.prefix setFlag SYNTHETIC | ARTIFACT (Select(codegen._asInstanceOf(testedBinder, expectedTp), outer)) OBJ_EQ expectedOuter } diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index 448382973a..9846d827b7 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -67,6 +67,11 @@ trait Symbols extends base.Symbols { self: Universe => */ def isSynthetic: Boolean + /** Does this symbol represent an implementation artifact that isn't meant for public use? + * Examples of such artifacts are erasure bridges and $outer fields. + */ + def isImplementationArtifact: Boolean + /** Does this symbol represent a local declaration or definition? * * If yes, either `isPrivate` or `isProtected` are guaranteed to be true. diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala index f3f3bf5ce8..0eb839479a 100644 --- a/src/reflect/scala/reflect/internal/Flags.scala +++ b/src/reflect/scala/reflect/internal/Flags.scala @@ -135,7 +135,7 @@ class Flags extends ModifierFlags { final val CAPTURED = 1 << 16 // variable is accessed from nested function. Set by LambdaLift. final val LABEL = 1 << 17 // method symbol is a label. Set by TailCall final val INCONSTRUCTOR = 1 << 17 // class symbol is defined in this/superclass constructor. - final val SYNTHETIC = 1 << 21 // symbol is compiler-generated (compare with HIDDEN) + final val SYNTHETIC = 1 << 21 // symbol is compiler-generated (compare with ARTIFACT) final val STABLE = 1 << 22 // functions that are assumed to be stable // (typically, access methods for valdefs) // or classes that do not contain abstract types. @@ -165,7 +165,7 @@ class Flags extends ModifierFlags { // A Java method's type is ``cooked'' by transforming raw types to existentials final val SYNCHRONIZED = 1L << 45 // symbol is a method which should be marked ACC_SYNCHRONIZED - final val HIDDEN = 1L << 46 // symbol should be ignored when typechecking; will be marked ACC_SYNTHETIC in bytecode + final val ARTIFACT = 1L << 46 // symbol should be ignored when typechecking; will be marked ACC_SYNTHETIC in bytecode // ------- shift definitions ------------------------------------------------------- @@ -218,7 +218,7 @@ class Flags extends ModifierFlags { /** To be a little clearer to people who aren't habitual bit twiddlers. */ final val AllFlags = -1L - + /** These flags can be set when class or module symbol is first created. * They are the only flags to survive a call to resetFlags(). */ @@ -288,11 +288,11 @@ class Flags extends ModifierFlags { /** These flags are not pickled */ final val FlagsNotPickled = IS_ERROR | OVERLOADED | LIFTED | TRANS_FLAG | LOCKED | TRIEDCOOKING - + // A precaution against future additions to FlagsNotPickled turning out // to be overloaded flags thus not-pickling more than intended. assert((OverloadedFlagsMask & FlagsNotPickled) == 0, flagsToString(OverloadedFlagsMask & FlagsNotPickled)) - + /** These flags are pickled */ final val PickledFlags = InitialFlags & ~FlagsNotPickled @@ -339,13 +339,13 @@ class Flags extends ModifierFlags { (SEALED, SEALED_PKL), (ABSTRACT, ABSTRACT_PKL) ) - + private val mappedRawFlags = rawPickledCorrespondence map (_._1) private val mappedPickledFlags = rawPickledCorrespondence map (_._2) - + private class MapFlags(from: Array[Long], to: Array[Long]) extends (Long => Long) { val fromSet = (0L /: from) (_ | _) - + def apply(flags: Long): Long = { var result = flags & ~fromSet var tobeMapped = flags & fromSet @@ -360,7 +360,7 @@ class Flags extends ModifierFlags { result } } - + val rawToPickledFlags: Long => Long = new MapFlags(mappedRawFlags, mappedPickledFlags) val pickledToRawFlags: Long => Long = new MapFlags(mappedPickledFlags, mappedRawFlags) @@ -434,7 +434,7 @@ class Flags extends ModifierFlags { case 0x8000000000000000L => "" // (1L << 63) case _ => "" } - + private def accessString(flags: Long, privateWithin: String)= ( if (privateWithin == "") { if ((flags & PrivateLocal) == PrivateLocal) "private[this]" @@ -446,7 +446,7 @@ class Flags extends ModifierFlags { else if ((flags & PROTECTED) != 0) "protected[" + privateWithin + "]" else "private[" + privateWithin + "]" ) - + @deprecated("Use flagString on the flag-carrying member", "2.10.0") def flagsToString(flags: Long, privateWithin: String): String = { val access = accessString(flags, privateWithin) diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala index 7ead9d6a1b..62c8ed702b 100644 --- a/src/reflect/scala/reflect/internal/HasFlags.scala +++ b/src/reflect/scala/reflect/internal/HasFlags.scala @@ -66,7 +66,7 @@ trait HasFlags { */ def flagString: String = flagString(flagMask) def flagString(mask: Long): String = calculateFlagString(flags & mask) - + /** The default mask determining which flags to display. */ def flagMask: Long = AllFlags @@ -92,7 +92,7 @@ trait HasFlags { def isCaseAccessor = hasFlag(CASEACCESSOR) def isDeferred = hasFlag(DEFERRED) def isFinal = hasFlag(FINAL) - def isHidden = hasFlag(HIDDEN) + def isArtifact = hasFlag(ARTIFACT) def isImplicit = hasFlag(IMPLICIT) def isInterface = hasFlag(INTERFACE) def isJavaDefined = hasFlag(JAVA) @@ -136,7 +136,7 @@ trait HasFlags { def accessString: String = { val pw = if (hasAccessBoundary) privateWithin.toString else "" - + if (pw == "") { if (hasAllFlags(PrivateLocal)) "private[this]" else if (hasAllFlags(ProtectedLocal)) "protected[this]" @@ -150,7 +150,7 @@ trait HasFlags { protected def calculateFlagString(basis: Long): String = { val access = accessString val nonAccess = flagBitsToString(basis & ~AccessFlags) - + if (access == "") nonAccess else if (nonAccess == "") access else nonAccess + " " + access diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 2a306d7c6e..824877f1e2 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -66,6 +66,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isExistential: Boolean = this.isExistentiallyBound def isParamWithDefault: Boolean = this.hasDefault def isByNameParam: Boolean = this.isValueParameter && (this hasFlag BYNAMEPARAM) + def isImplementationArtifact: Boolean = (this hasFlag BRIDGE) || (this hasFlag VBRIDGE) || (this hasFlag ARTIFACT) def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) @@ -690,13 +691,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Is this symbol an accessor method for outer? */ final def isOuterAccessor = { - hasFlag(STABLE | HIDDEN) && + hasFlag(STABLE | ARTIFACT) && originalName == nme.OUTER } /** Is this symbol an accessor method for outer? */ final def isOuterField = { - hasFlag(HIDDEN) && + hasFlag(ARTIFACT) && originalName == nme.OUTER_LOCAL } -- cgit v1.2.3