Skip to content

Try to refine handling of SymDenotations V2 #4512

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 12 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
50 changes: 25 additions & 25 deletions compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,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 All @@ -169,9 +169,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}

def isBox(sym: Symbol): Boolean =
Erasure.Boxing.isBox(sym) && sym.denot.owner != defn.UnitModuleClass
Erasure.Boxing.isBox(sym) && sym.owner != defn.UnitModuleClass
def isUnbox(sym: Symbol): Boolean =
Erasure.Boxing.isUnbox(sym) && sym.denot.owner != defn.UnitModuleClass
Erasure.Boxing.isUnbox(sym) && sym.owner != defn.UnitModuleClass

val primitives: Primitives = new Primitives {
val primitives = new DottyPrimitives(ctx)
Expand Down Expand Up @@ -256,24 +256,24 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
av.visitEnum(name, edesc, evalue)
}
case t: TypeApply if (t.fun.symbol == Predef_classOf) =>
av.visit(name, t.args.head.tpe.classSymbol.denot.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType)
av.visit(name, t.args.head.tpe.classSymbol.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType)
case t: tpd.Select =>
if (t.symbol.denot.owner.is(Flags.JavaEnum)) {
if (t.symbol.owner.is(Flags.JavaEnum)) {
val edesc = innerClasesStore.typeDescriptor(t.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class.
val evalue = t.symbol.name.mangledString // value the actual enumeration value.
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.
// println(i"not an enum: ${t.symbol} / ${t.symbol.owner} / ${t.symbol.owner.isTerm} / ${t.symbol.owner.flags}")
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 @@ -304,7 +304,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
} // for the lazy val in ScalaSigBytes to be GC'ed, the invoker of emitAnnotations() should hold the ScalaSigBytes in a method-local var that doesn't escape.
*/
case t @ Apply(constr, args) if t.tpe.derivesFrom(JavaAnnotationClass) =>
val typ = t.tpe.classSymbol.denot.info
val typ = t.tpe.classSymbol.info
val assocs = assocsFromApply(t)
val desc = innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the nested annotation class
val nestedVisitor = av.visitAnnotation(name, desc)
Expand Down Expand Up @@ -521,7 +521,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma

if (!valid) {
ctx.error(
i"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName}
i"""|compiler bug: created invalid generic signature for $sym in ${sym.owner.showFullName}
|signature: $sig
|if this is reproducible, please report bug at https://github.com/lampepfl/dotty/issues
""".trim, sym.pos)
Expand All @@ -540,7 +540,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def getGenericSignature(sym: Symbol, owner: Symbol): String = {
ctx.atPhase(ctx.erasurePhase) { implicit ctx =>
val memberTpe =
if (sym.is(Flags.Method)) sym.denot.info
if (sym.is(Flags.Method)) sym.info
else owner.denot.thisType.memberInfo(sym)
getGenericSignature(sym, owner, memberTpe).orNull
}
Expand All @@ -555,14 +555,14 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma

val memberTpe = ctx.atPhase(ctx.erasurePhase) { implicit ctx => moduleClass.denot.thisType.memberInfo(sym) }
val erasedMemberType = TypeErasure.erasure(memberTpe)
if (erasedMemberType =:= sym.denot.info)
if (erasedMemberType =:= sym.info)
getGenericSignature(sym, moduleClass, memberTpe).orNull
else null
}

private def getGenericSignature(sym: Symbol, owner: Symbol, memberTpe: Type)(implicit ctx: Context): Option[String] =
if (needsGenericSignature(sym)) {
val erasedTypeSym = sym.denot.info.typeSymbol
val erasedTypeSym = sym.info.typeSymbol
if (erasedTypeSym.isPrimitiveValueClass) {
None
} else {
Expand Down Expand Up @@ -655,7 +655,7 @@ 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 name: Name = sym.name
Expand All @@ -665,8 +665,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}

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

// tests
Expand Down Expand Up @@ -746,7 +746,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma


// navigation
def owner: Symbol = toDenot(sym).owner
def owner: Symbol = sym.owner
def rawowner: Symbol = {
originalOwner
}
Expand All @@ -760,7 +760,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
val r = toDenot(sym)(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
if (t.exists) t
Expand Down Expand Up @@ -803,7 +803,7 @@ 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

Expand All @@ -815,10 +815,10 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
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 +842,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(_.asClass.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 +856,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 +874,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
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1094,9 +1094,9 @@ object desugar {
Literal(Constant(scala.Symbol(str)))
case Quote(expr) =>
if (expr.isType)
TypeApply(ref(defn.QuotedType_applyR), List(expr))
TypeApply(ref(defn.QuotedType_apply.termRef), List(expr))
else
Apply(ref(defn.QuotedExpr_applyR), expr)
Apply(ref(defn.QuotedExpr_apply.termRef), expr)
case InterpolatedString(id, segments) =>
val strs = segments map {
case ts: Thicket => ts.trees.head
Expand Down
19 changes: 7 additions & 12 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ class Definitions {
lazy val Product_productPrefixR = ProductClass.requiredMethodRef(nme.productPrefix)
def Product_productPrefix(implicit ctx: Context) = Product_productPrefixR.symbol
lazy val LanguageModuleRef = ctx.requiredModule("scala.language")
def LanguageModuleClass(implicit ctx: Context) = LanguageModuleRef.symbol.moduleClass.asClass
def LanguageModuleClass(implicit ctx: Context) = LanguageModuleRef.moduleClass.asClass
lazy val NonLocalReturnControlType: TypeRef = ctx.requiredClassRef("scala.runtime.NonLocalReturnControl")
lazy val SelectableType: TypeRef = ctx.requiredClassRef("scala.Selectable")

Expand All @@ -638,16 +638,12 @@ class Definitions {

lazy val QuotedExprModuleType = ctx.requiredModuleRef("scala.quoted.Expr")
def QuotedExprModule(implicit ctx: Context) = QuotedExprModuleType.symbol
lazy val QuotedExpr_applyR = QuotedExprModule.requiredMethodRef(nme.apply)
def QuotedExpr_apply(implicit ctx: Context) = QuotedExpr_applyR.symbol

lazy val QuotedExpr_spliceR = QuotedExprClass.requiredMethod(nme.UNARY_~)
def QuotedExpr_~(implicit ctx: Context) = QuotedExpr_spliceR.symbol
lazy val QuotedExpr_runR = QuotedExprClass.requiredMethodRef(nme.run)
def QuotedExpr_run(implicit ctx: Context) = QuotedExpr_runR.symbol
def QuotedExpr_apply(implicit ctx: Context) = QuotedExprModule.requiredMethod(nme.apply)
def QuotedExpr_~(implicit ctx: Context) = QuotedExprClass.requiredMethod(nme.UNARY_~)
def QuotedExpr_run(implicit ctx: Context) =QuotedExprClass.requiredMethodRef(nme.run)

lazy val QuotedExprsModule = ctx.requiredModule("scala.quoted.Exprs")
def QuotedExprsClass(implicit ctx: Context) = QuotedExprsModule.symbol.asClass
def QuotedExprsClass(implicit ctx: Context) = QuotedExprsModule.asClass

lazy val QuotedTypeType = ctx.requiredClassRef("scala.quoted.Type")
def QuotedTypeClass(implicit ctx: Context) = QuotedTypeType.symbol.asClass
Expand All @@ -668,10 +664,9 @@ class Definitions {
def Unpickler_unpickleType = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType")

lazy val TastyUniverseModule = ctx.requiredModule("scala.tasty.Universe")
def TastyUniverseModuleClass(implicit ctx: Context) = TastyUniverseModule.symbol.asClass
def TastyUniverseModuleClass(implicit ctx: Context) = TastyUniverseModule.moduleClass.asClass

lazy val TastyUniverse_compilationUniverseR = TastyUniverseModule.requiredMethod("compilationUniverse")
def TastyUniverse_compilationUniverse(implicit ctx: Context) = TastyUniverse_compilationUniverseR.symbol
lazy val TastyUniverse_compilationUniverse = TastyUniverseModule.requiredMethod("compilationUniverse")

lazy val EqType = ctx.requiredClassRef("scala.Eq")
def EqClass(implicit ctx: Context) = EqType.symbol.asClass
Expand Down
35 changes: 5 additions & 30 deletions compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import printing.Printer
import io.AbstractFile
import config.Config
import util.common._
import util.Stats
import collection.mutable.ListBuffer
import Decorators.SymbolIteratorDecorator

Expand Down Expand Up @@ -174,6 +175,7 @@ object Denotations {
abstract class Denotation(val symbol: Symbol) extends PreDenotation with printing.Showable {

type AsSeenFromResult <: Denotation
Stats.record("Denotation")

/** The type info of the denotation, exists only for non-overloaded denotations */
def info(implicit ctx: Context): Type
Expand Down Expand Up @@ -287,35 +289,6 @@ object Denotations {
denot.symbol
}

def requiredMethod(name: PreName)(implicit ctx: Context): TermSymbol =
info.member(name.toTermName).requiredSymbol(_ is Method).asTerm
def requiredMethodRef(name: PreName)(implicit ctx: Context): TermRef =
requiredMethod(name).termRef

def requiredMethod(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermSymbol = {
info.member(name.toTermName).requiredSymbol { x =>
(x is Method) && {
x.info.paramInfoss match {
case paramInfos :: Nil => paramInfos.corresponds(argTypes)(_ =:= _)
case _ => false
}
}
}.asTerm
}
def requiredMethodRef(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermRef =
requiredMethod(name, argTypes).termRef

def requiredValue(name: PreName)(implicit ctx: Context): TermSymbol =
info.member(name.toTermName).requiredSymbol(_.info.isParameterless).asTerm
def requiredValueRef(name: PreName)(implicit ctx: Context): TermRef =
requiredValue(name).termRef

def requiredClass(name: PreName)(implicit ctx: Context): ClassSymbol =
info.member(name.toTypeName).requiredSymbol(_.isClass).asClass

def requiredType(name: PreName)(implicit ctx: Context): TypeSymbol =
info.member(name.toTypeName).requiredSymbol(_.isType).asType

/** The alternative of this denotation that has a type matching `targetType` when seen
* as a member of type `site`, `NoDenotation` if none exists.
*/
Expand Down Expand Up @@ -1139,6 +1112,8 @@ object Denotations {
def denot1: PreDenotation
def denot2: PreDenotation

Stats.record("MultiPreDenotation")

assert(denot1.exists && denot2.exists, s"Union of non-existing denotations ($denot1) and ($denot2)")
def first = denot1.first
def last = denot2.last
Expand Down Expand Up @@ -1290,7 +1265,7 @@ object Denotations {

/** An exception for accessing symbols that are no longer valid in current run */
class StaleSymbol(msg: => String) extends Exception {
util.Stats.record("stale symbol")
Stats.record("stale symbol")
override def getMessage() = msg
}
}
Loading