Skip to content

Try to refine handling of SymDenotations #4504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ object CollectEntryPoints{
val StringType = d.StringType
// The given class has a main method.
def hasJavaMainMethod(sym: Symbol): Boolean =
(toDenot(sym).info member nme.main).alternatives exists(x => isJavaMainMethod(x.symbol))
(sym.info member nme.main).alternatives exists(x => isJavaMainMethod(x.symbol))

def fail(msg: String, pos: Position = sym.pos) = {
ctx.warning( sym.name +
s" has a main method with parameter type Array[String], but ${toDenot(sym).fullName} will not be a runnable program.\n Reason: $msg",
s" has a main method with parameter type Array[String], but ${sym.fullName} will not be a runnable program.\n Reason: $msg",
sourcePos(sym.pos)
// TODO: make this next claim true, if possible
// by generating valid main methods as static in module classes
Expand All @@ -77,7 +77,7 @@ object CollectEntryPoints{
def failNoForwarder(msg: String) = {
fail(s"$msg, which means no static forwarder can be generated.\n")
}
val possibles = if (sym.flags is Flags.Module) (toDenot(sym).info nonPrivateMember nme.main).alternatives else Nil
val possibles = if (sym.flags is Flags.Module) (sym.info nonPrivateMember nme.main).alternatives else Nil
val hasApproximate = possibles exists { m =>
m.info match {
case MethodTpe(_, p :: Nil, _) => p.typeSymbol == defn.ArrayClass
Expand All @@ -94,7 +94,7 @@ object CollectEntryPoints{

if (hasJavaMainMethod(companion))
failNoForwarder("companion contains its own main method")
else if (toDenot(companion).info.member(nme.main) != NoDenotation)
else if (companion.info.member(nme.main) != NoDenotation)
// this is only because forwarders aren't smart enough yet
failNoForwarder("companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)")
else if (companion.flags is Flags.Trait)
Expand All @@ -103,7 +103,7 @@ object CollectEntryPoints{
// attempts to be java main methods.
else (possibles exists(x=> isJavaMainMethod(x.symbol))) || {
possibles exists { m =>
toDenot(m.symbol).info match {
m.symbol.info match {
case t: PolyType =>
fail("main methods cannot be generic.")
case MethodTpe(paramNames, paramTypes, resultType) =>
Expand Down
85 changes: 42 additions & 43 deletions compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import dotty.tools.dotc.core.Names.TypeName
import scala.annotation.tailrec

class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit ctx: Context) extends BackendInterface{
import Symbols.{toDenot, toClassDenot}
// Dotty deviation: Need to (re-)import implicit decorators here because otherwise
// they would be shadowed by the more deeply nested `symHelper` decorator.

Expand Down Expand Up @@ -143,7 +142,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
val externalEqualsNumNum: Symbol = defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumNum)
val externalEqualsNumChar: Symbol = NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private
val externalEqualsNumObject: Symbol = defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumObject)
val externalEquals: Symbol = defn.BoxesRunTimeClass.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol
val externalEquals: Symbol = defn.BoxesRunTimeClass.info.decl(nme.equals_).suchThat(_.info.firstParamTypes.size == 2).symbol
val MaxFunctionArity: Int = Definitions.MaxImplementedFunctionArity
val FunctionClass: Array[Symbol] = defn.FunctionClassPerRun()
val AbstractFunctionClass: Array[Symbol] = defn.AbstractFunctionClassPerRun()
Expand Down Expand Up @@ -214,7 +213,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
implicit val ClosureTag: ClassTag[Closure] = ClassTag[Closure](classOf[Closure])

def isRuntimeVisible(annot: Annotation): Boolean =
if (toDenot(annot.atp.typeSymbol).hasAnnotation(AnnotationRetentionAttr))
if (annot.atp.typeSymbol.hasAnnotation(AnnotationRetentionAttr))
retentionPolicyOf(annot) == AnnotationRetentionRuntimeAttr
else {
// SI-8926: if the annotation class symbol doesn't have a @RetentionPolicy annotation, the
Expand Down Expand Up @@ -264,16 +263,16 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
av.visitEnum(name, edesc, evalue)
} else {
// println(i"not an enum: ${t.symbol} / ${t.symbol.denot.owner} / ${t.symbol.denot.owner.isTerm} / ${t.symbol.denot.owner.flags}")
assert(toDenot(t.symbol).name.is(DefaultGetterName),
s"${toDenot(t.symbol).name.debugString}") // this should be default getter. do not emmit.
assert(t.symbol.name.is(DefaultGetterName),
s"${t.symbol.name.debugString}") // this should be default getter. do not emmit.
}
case t: SeqLiteral =>
val arrAnnotV: AnnotationVisitor = av.visitArray(name)
for (arg <- t.elems) { emitArgument(arrAnnotV, null, arg, bcodeStore)(innerClasesStore) }
arrAnnotV.visitEnd()

case Apply(fun, args) if fun.symbol == defn.ArrayClass.primaryConstructor ||
toDenot(fun.symbol).owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply =>
fun.symbol.owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply =>
val arrAnnotV: AnnotationVisitor = av.visitArray(name)

var actualArgs = if (fun.tpe.isImplicitMethod) {
Expand Down Expand Up @@ -655,29 +654,29 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def fullName(sep: Char): String = sym.showFullName
def fullName: String = sym.showFullName
def simpleName: Name = sym.name
def javaSimpleName: String = toDenot(sym).name.mangledString // addModuleSuffix(simpleName.dropLocal)
def javaSimpleName: String = sym.name.mangledString // addModuleSuffix(simpleName.dropLocal)
def javaBinaryName: String = javaClassName.replace('.', '/') // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/'))
def javaClassName: String = toDenot(sym).fullName.mangledString // addModuleSuffix(fullNameInternal('.')).toString
def javaClassName: String = sym.fullName.mangledString // addModuleSuffix(fullNameInternal('.')).toString
def name: Name = sym.name
def rawname: String = {
val original = toDenot(sym).initial
val original = sym.initial
sym.name(ctx.withPhase(original.validFor.phaseId)).mangledString
}

// types
def info: Type = toDenot(sym).info
def tpe: Type = toDenot(sym).info // todo whats the differentce between tpe and info?
def thisType: Type = toDenot(sym).thisType
def info: Type = sym.info
def tpe: Type = sym.info // todo whats the differentce between tpe and info?
def thisType: Type = sym.thisType

// tests
def isClass: Boolean = {
sym.isPackageObject || (sym.isClass)
}
def isType: Boolean = sym.isType
def isAnonymousClass: Boolean = toDenot(sym).isAnonymousClass
def isConstructor: Boolean = toDenot(sym).isConstructor
def isAnonymousClass: Boolean = sym.isAnonymousClass
def isConstructor: Boolean = sym.isConstructor
def isExpanded: Boolean = sym.name.is(ExpandedName)
def isAnonymousFunction: Boolean = toDenot(sym).isAnonymousFunction
def isAnonymousFunction: Boolean = sym.isAnonymousFunction
def isMethod: Boolean = sym is Flags.Method
def isPublic: Boolean = sym.flags.is(Flags.EmptyFlags, Flags.Private | Flags.Protected)
def isSynthetic: Boolean = sym is Flags.Synthetic
Expand All @@ -689,22 +688,22 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def hasPackageFlag: Boolean = sym is Flags.Package
def isImplClass: Boolean = sym is Flags.ImplClass
def isInterface: Boolean = (sym is Flags.PureInterface) || (sym is Flags.Trait)
def isGetter: Boolean = toDenot(sym).isGetter
def isSetter: Boolean = toDenot(sym).isSetter
def isGetter: Boolean = sym.isGetter
def isSetter: Boolean = sym.isSetter
def isGetClass: Boolean = sym eq defn.Any_getClass
def isJavaDefined: Boolean = sym is Flags.JavaDefined
def isJavaDefaultMethod: Boolean = !((sym is Flags.Deferred) || toDenot(sym).isClassConstructor)
def isJavaDefaultMethod: Boolean = !((sym is Flags.Deferred) || sym.isClassConstructor)
def isDeferred: Boolean = sym is Flags.Deferred
def isPrivate: Boolean = sym is Flags.Private
def getsJavaFinalFlag: Boolean =
isFinal && !toDenot(sym).isClassConstructor && !(sym is Flags.Mutable) && !(sym.enclosingClass is Flags.Trait)
isFinal && !sym.isClassConstructor && !(sym is Flags.Mutable) && !(sym.enclosingClass is Flags.Trait)

def getsJavaPrivateFlag: Boolean =
isPrivate //|| (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass)

def isFinal: Boolean = sym is Flags.Final
def isStaticMember: Boolean = (sym ne NoSymbol) &&
((sym is Flags.JavaStatic) || (owner is Flags.ImplClass) || toDenot(sym).hasAnnotation(ctx.definitions.ScalaStaticAnnot))
((sym is Flags.JavaStatic) || (owner is Flags.ImplClass) || sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot))
// guard against no sumbol cause this code is executed to select which call type(static\dynamic) to use to call array.clone

def isBottomClass: Boolean = (sym ne defn.NullClass) && (sym ne defn.NothingClass)
Expand All @@ -720,12 +719,12 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def hasModuleFlag: Boolean = sym is Flags.Module
def isSynchronized: Boolean = sym is Flags.Synchronized
def isNonBottomSubClass(other: Symbol): Boolean = sym.derivesFrom(other)
def hasAnnotation(ann: Symbol): Boolean = toDenot(sym).hasAnnotation(ann)
def hasAnnotation(ann: Symbol): Boolean = sym.hasAnnotation(ann)
def shouldEmitForwarders: Boolean =
(sym is Flags.Module) && !(sym is Flags.ImplClass) && sym.isStatic
def isJavaEntryPoint: Boolean = CollectEntryPoints.isJavaEntryPoint(sym)

def isClassConstructor: Boolean = toDenot(sym).isClassConstructor
def isClassConstructor: Boolean = sym.isClassConstructor

/**
* True for module classes of modules that are top-level or owned only by objects. Module classes
Expand All @@ -736,33 +735,33 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
// scalac uses atPickling here
// this would not work if modules are created after pickling
// for example by specialization
val original = toDenot(sym).initial
val original = sym.initial
val validity = original.validFor
val shiftedContext = ctx.withPhase(validity.phaseId)
toDenot(sym)(shiftedContext).isStatic(shiftedContext)
sym.denot(shiftedContext).isStatic(shiftedContext)
}

def isStaticConstructor: Boolean = (isStaticMember && isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR)


// navigation
def owner: Symbol = toDenot(sym).owner
def owner: Symbol = sym.owner
def rawowner: Symbol = {
originalOwner
}
def originalOwner: Symbol =
// used to populate the EnclosingMethod attribute.
// it is very tricky in presence of classes(and annonymous classes) defined inside supper calls.
if (sym.exists) {
val original = toDenot(sym).initial
val original = sym.initial
val validity = original.validFor
val shiftedContext = ctx.withPhase(validity.phaseId)
val r = toDenot(sym)(shiftedContext).maybeOwner.lexicallyEnclosingClass(shiftedContext)
val r = sym.denot(shiftedContext).maybeOwner.lexicallyEnclosingClass(shiftedContext)
r
} else NoSymbol
def parentSymbols: List[Symbol] = toDenot(sym).info.parents.map(_.typeSymbol)
def parentSymbols: List[Symbol] = sym.info.parents.map(_.typeSymbol)
def superClass: Symbol = {
val t = toDenot(sym).asClass.superClass
val t = sym.asClass.superClass
if (t.exists) t
else if (sym is Flags.ModuleClass) {
// workaround #371
Expand All @@ -772,23 +771,23 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}
else t
}
def enclClass: Symbol = toDenot(sym).enclosingClass
def enclClass: Symbol = sym.enclosingClass
def linkedClassOfClass: Symbol = linkedClass
def linkedClass: Symbol = toDenot(sym)(ctx).linkedClass(ctx) //exitingPickler(sym.linkedClassOfClass)
def companionClass: Symbol = toDenot(sym).companionClass
def companionModule: Symbol = toDenot(sym).companionModule
def linkedClass: Symbol = sym.linkedClass(ctx) //exitingPickler(sym.linkedClassOfClass)
def companionClass: Symbol = sym.companionClass
def companionModule: Symbol = sym.companionModule
def companionSymbol: Symbol = if (sym is Flags.Module) companionClass else companionModule
def moduleClass: Symbol = toDenot(sym).moduleClass
def moduleClass: Symbol = sym.moduleClass
def enclosingClassSym: Symbol = {
if (this.isClass) {
val ct = ctx.withPhase(ctx.flattenPhase.prev)
toDenot(sym)(ct).owner.enclosingClass(ct)
sym.denot(ct).owner.enclosingClass(ct)
}
else sym.enclosingClass(ctx.withPhase(ctx.flattenPhase.prev))
} //todo is handled specially for JavaDefined symbols in scalac

// members
def primaryConstructor: Symbol = toDenot(sym).primaryConstructor
def primaryConstructor: Symbol = sym.primaryConstructor

/** For currently compiled classes: All locally defined classes including local classes.
* The empty list for classes that are not currently compiled.
Expand All @@ -803,22 +802,22 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
private def definedClasses(phase: Phase) =
if (sym.isDefinedInCurrentRun)
ctx.atPhase(phase) { implicit ctx =>
toDenot(sym).info.decls.filter(_.isClass)
sym.info.decls.filter(_.isClass)
}
else Nil

def annotations: List[Annotation] = toDenot(sym).annotations
def annotations: List[Annotation] = sym.annotations
def companionModuleMembers: List[Symbol] = {
// phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes,
// not local classes of the companion module (E in the exmaple) that were lifted by lambdalift.
if (linkedClass.isTopLevelModuleClass) /*exitingPickler*/ linkedClass.memberClasses
else Nil
}
def fieldSymbols: List[Symbol] = {
toDenot(sym).info.decls.filter(p => p.isTerm && !p.is(Flags.Method))
sym.info.decls.filter(p => p.isTerm && !p.is(Flags.Method))
}
def methodSymbols: List[Symbol] =
for (f <- toDenot(sym).info.decls.toList if f.isMethod && f.isTerm && !f.isModule) yield f
for (f <- sym.info.decls.toList if f.isMethod && f.isTerm && !f.isModule) yield f
def serialVUID: Option[Long] = None


Expand All @@ -842,7 +841,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def superInterfaces: List[Symbol] = {
val directlyInheritedTraits = decorateSymbol(sym).directlyInheritedTraits
val directlyInheritedTraitsSet = directlyInheritedTraits.toSet
val allBaseClasses = directlyInheritedTraits.iterator.flatMap(_.symbol.asClass.baseClasses.drop(1)).toSet
val allBaseClasses = directlyInheritedTraits.iterator.flatMap(_.baseClasses.drop(1)).toSet
val superCalls = superCallsMap.getOrElse(sym, Set.empty)
val additional = (superCalls -- directlyInheritedTraitsSet).filter(_.is(Flags.Trait))
// if (additional.nonEmpty)
Expand All @@ -856,7 +855,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
*/
def isTopLevelModuleClass: Boolean = sym.isModuleClass &&
ctx.atPhase(ctx.flattenPhase) { implicit ctx =>
toDenot(sym).owner.is(Flags.PackageClass)
sym.owner.is(Flags.PackageClass)
}

/**
Expand All @@ -874,7 +873,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def addRemoteRemoteExceptionAnnotation: Unit = ()

def samMethod(): Symbol =
toDenot(sym).info.abstractTermMembers.headOption.getOrElse(toDenot(sym).info.member(nme.apply)).symbol
sym.info.abstractTermMembers.headOption.getOrElse(sym.info.member(nme.apply)).symbol
}


Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
val sym = tree.symbol
val prevDenot = sym.denot(ctx.withPhase(trans))
if (prevDenot.effectiveOwner == from.skipWeakOwner) {
val d = sym.copySymDenotation(owner = to)
val d = sym.denot.copySymDenotation(owner = to)
d.installAfter(trans)
d.transformAfter(trans, d => if (d.owner eq from) d.copySymDenotation(owner = to) else d)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/config/JavaPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class JavaPlatform extends Platform {
}

// The given symbol is a method with the right name and signature to be a runnable java program.
def isMainMethod(sym: SymDenotation)(implicit ctx: Context) =
def isMainMethod(sym: Symbol)(implicit ctx: Context) =
(sym.name == nme.main) && (sym.info match {
case MethodTpe(_, defn.ArrayOf(el) :: Nil, restpe) => el =:= defn.StringType && (restpe isRef defn.UnitClass)
case _ => false
Expand Down
7 changes: 2 additions & 5 deletions compiler/src/dotty/tools/dotc/config/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,10 @@ abstract class Platform {
def newClassLoader(bin: AbstractFile)(implicit ctx: Context): SymbolLoader

/** The given symbol is a method with the right name and signature to be a runnable program. */
def isMainMethod(sym: SymDenotation)(implicit ctx: Context): Boolean
def isMainMethod(sym: Symbol)(implicit ctx: Context): Boolean

/** The given class has a main method. */
final def hasMainMethod(sym: Symbol)(implicit ctx: Context): Boolean =
sym.info.member(nme.main).hasAltWith {
case x: SymDenotation => isMainMethod(x)
case _ => false
}
sym.info.member(nme.main).hasAltWith(d => isMainMethod(d.symbol))
}

4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Annotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ object Annotations {

def makeAlias(sym: TermSymbol)(implicit ctx: Context) =
apply(defn.AliasAnnot, List(
ref(TermRef(sym.owner.thisType, sym.name, sym))))
ref(TermRef(sym.owner.thisType, sym.name, sym.denot))))

/** Extractor for child annotations */
object Child {
Expand All @@ -157,7 +157,7 @@ object Annotations {
def apply(delayedSym: Context => Symbol)(implicit ctx: Context): Annotation = {
def makeChildLater(implicit ctx: Context) = {
val sym = delayedSym(ctx)
New(defn.ChildAnnotType.appliedTo(sym.owner.thisType.select(sym.name, sym)), Nil)
New(defn.ChildAnnotType.appliedTo(sym.owner.thisType.select(sym.name, sym.denot)), Nil)
}
deferred(defn.ChildAnnot, implicit ctx => makeChildLater(ctx))
}
Expand Down
Loading